InterpAsm-armv5te-vfp.S revision d3a92b577f11c6357c76dc850c6cbf352ef4c760
1/*
2 * This file was generated automatically by gen-mterp.py for 'armv5te-vfp'.
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: armv5te/platform.S */
210/*
211 * ===========================================================================
212 *  CPU-version-specific defines
213 * ===========================================================================
214 */
215
216/*
217 * Macro for data memory barrier; not meaningful pre-ARMv6K.
218 */
219.macro  SMP_DMB
220.endm
221
222/*
223 * Macro for data memory barrier; not meaningful pre-ARMv6K.
224 */
225.macro  SMP_DMB_ST
226.endm
227
228/* File: armv5te/entry.S */
229/*
230 * Copyright (C) 2008 The Android Open Source Project
231 *
232 * Licensed under the Apache License, Version 2.0 (the "License");
233 * you may not use this file except in compliance with the License.
234 * You may obtain a copy of the License at
235 *
236 *      http://www.apache.org/licenses/LICENSE-2.0
237 *
238 * Unless required by applicable law or agreed to in writing, software
239 * distributed under the License is distributed on an "AS IS" BASIS,
240 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
241 * See the License for the specific language governing permissions and
242 * limitations under the License.
243 */
244/*
245 * Interpreter entry point.
246 */
247
248/*
249 * We don't have formal stack frames, so gdb scans upward in the code
250 * to find the start of the function (a label with the %function type),
251 * and then looks at the next few instructions to figure out what
252 * got pushed onto the stack.  From this it figures out how to restore
253 * the registers, including PC, for the previous stack frame.  If gdb
254 * sees a non-function label, it stops scanning, so either we need to
255 * have nothing but assembler-local labels between the entry point and
256 * the break, or we need to fake it out.
257 *
258 * When this is defined, we add some stuff to make gdb less confused.
259 */
260#define ASSIST_DEBUGGER 1
261
262    .text
263    .align  2
264    .global dvmMterpStdRun
265    .type   dvmMterpStdRun, %function
266
267/*
268 * On entry:
269 *  r0  MterpGlue* glue
270 *
271 * This function returns a boolean "changeInterp" value.  The return comes
272 * via a call to dvmMterpStdBail().
273 */
274dvmMterpStdRun:
275#define MTERP_ENTRY1 \
276    .save {r4-r10,fp,lr}; \
277    stmfd   sp!, {r4-r10,fp,lr}         @ save 9 regs
278#define MTERP_ENTRY2 \
279    .pad    #4; \
280    sub     sp, sp, #4                  @ align 64
281
282    .fnstart
283    MTERP_ENTRY1
284    MTERP_ENTRY2
285
286    /* save stack pointer, add magic word for debuggerd */
287    str     sp, [r0, #offGlue_bailPtr]  @ save SP for eventual return
288
289    /* set up "named" registers, figure out entry point */
290    mov     rGLUE, r0                   @ set rGLUE
291    ldr     r1, [r0, #offGlue_entryPoint]   @ enum is 4 bytes in aapcs-EABI
292    LOAD_PC_FP_FROM_GLUE()              @ load rPC and rFP from "glue"
293    adr     rIBASE, dvmAsmInstructionStart  @ set rIBASE
294    cmp     r1, #kInterpEntryInstr      @ usual case?
295    bne     .Lnot_instr                 @ no, handle it
296
297#if defined(WITH_JIT)
298.LentryInstr:
299    ldr     r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
300    /* Entry is always a possible trace start */
301    GET_JIT_PROF_TABLE(r0)
302    FETCH_INST()
303    mov     r1, #0                      @ prepare the value for the new state
304    str     r1, [r10, #offThread_inJitCodeCache] @ back to the interp land
305    cmp     r0,#0                       @ is profiling disabled?
306#if !defined(WITH_SELF_VERIFICATION)
307    bne     common_updateProfile        @ profiling is enabled
308#else
309    ldr     r2, [r10, #offThread_shadowSpace]   @ to find out the jit exit state
310    beq     1f                          @ profiling is disabled
311    ldr     r3, [r2, #offShadowSpace_jitExitState]  @ jit exit state
312    cmp     r3, #kSVSTraceSelect        @ hot trace following?
313    moveq   r2,#kJitTSelectRequestHot   @ ask for trace selection
314    beq     common_selectTrace          @ go build the trace
315    cmp     r3, #kSVSNoProfile          @ don't profile the next instruction?
316    beq     1f                          @ intrepret the next instruction
317    b       common_updateProfile        @ collect profiles
318#endif
3191:
320    GET_INST_OPCODE(ip)
321    GOTO_OPCODE(ip)
322#else
323    /* start executing the instruction at rPC */
324    FETCH_INST()                        @ load rINST from rPC
325    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
326    GOTO_OPCODE(ip)                     @ jump to next instruction
327#endif
328
329.Lnot_instr:
330    cmp     r1, #kInterpEntryReturn     @ were we returning from a method?
331    beq     common_returnFromMethod
332
333.Lnot_return:
334    cmp     r1, #kInterpEntryThrow      @ were we throwing an exception?
335    beq     common_exceptionThrown
336
337#if defined(WITH_JIT)
338.Lnot_throw:
339    ldr     r10,[rGLUE, #offGlue_jitResumeNPC]
340    ldr     r2,[rGLUE, #offGlue_jitResumeDPC]
341    cmp     r1, #kInterpEntryResume     @ resuming after Jit single-step?
342    bne     .Lbad_arg
343    cmp     rPC,r2
344    bne     .LentryInstr                @ must have branched, don't resume
345#if defined(WITH_SELF_VERIFICATION)
346    @ glue->entryPoint will be set in dvmSelfVerificationSaveState
347    b       jitSVShadowRunStart         @ re-enter the translation after the
348                                        @ single-stepped instruction
349    @noreturn
350#endif
351    mov     r1, #kInterpEntryInstr
352    str     r1, [rGLUE, #offGlue_entryPoint]
353    bx      r10                         @ re-enter the translation
354#endif
355
356.Lbad_arg:
357    ldr     r0, strBadEntryPoint
358    @ r1 holds value of entryPoint
359    bl      printf
360    bl      dvmAbort
361    .fnend
362
363
364    .global dvmMterpStdBail
365    .type   dvmMterpStdBail, %function
366
367/*
368 * Restore the stack pointer and PC from the save point established on entry.
369 * This is essentially the same as a longjmp, but should be cheaper.  The
370 * last instruction causes us to return to whoever called dvmMterpStdRun.
371 *
372 * We pushed some registers on the stack in dvmMterpStdRun, then saved
373 * SP and LR.  Here we restore SP, restore the registers, and then restore
374 * LR to PC.
375 *
376 * On entry:
377 *  r0  MterpGlue* glue
378 *  r1  bool changeInterp
379 */
380dvmMterpStdBail:
381    ldr     sp, [r0, #offGlue_bailPtr]      @ sp<- saved SP
382    mov     r0, r1                          @ return the changeInterp value
383    add     sp, sp, #4                      @ un-align 64
384    ldmfd   sp!, {r4-r10,fp,pc}             @ restore 9 regs and return
385
386
387/*
388 * String references.
389 */
390strBadEntryPoint:
391    .word   .LstrBadEntryPoint
392
393
394    .global dvmAsmInstructionStart
395    .type   dvmAsmInstructionStart, %function
396dvmAsmInstructionStart = .L_OP_NOP
397    .text
398
399/* ------------------------------ */
400    .balign 64
401.L_OP_NOP: /* 0x00 */
402/* File: armv5te/OP_NOP.S */
403    FETCH_ADVANCE_INST(1)               @ advance to next instr, load rINST
404    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
405    GOTO_OPCODE(ip)                     @ execute it
406
407#ifdef ASSIST_DEBUGGER
408    /* insert fake function header to help gdb find the stack frame */
409    .type   dalvik_inst, %function
410dalvik_inst:
411    .fnstart
412    MTERP_ENTRY1
413    MTERP_ENTRY2
414    .fnend
415#endif
416
417/* ------------------------------ */
418    .balign 64
419.L_OP_MOVE: /* 0x01 */
420/* File: armv5te/OP_MOVE.S */
421    /* for move, move-object, long-to-int */
422    /* op vA, vB */
423    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
424    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
425    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
426    GET_VREG(r2, r1)                    @ r2<- fp[B]
427    and     r0, r0, #15
428    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
429    SET_VREG(r2, r0)                    @ fp[A]<- r2
430    GOTO_OPCODE(ip)                     @ execute next instruction
431
432/* ------------------------------ */
433    .balign 64
434.L_OP_MOVE_FROM16: /* 0x02 */
435/* File: armv5te/OP_MOVE_FROM16.S */
436    /* for: move/from16, move-object/from16 */
437    /* op vAA, vBBBB */
438    FETCH(r1, 1)                        @ r1<- BBBB
439    mov     r0, rINST, lsr #8           @ r0<- AA
440    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
441    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
442    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
443    SET_VREG(r2, r0)                    @ fp[AA]<- r2
444    GOTO_OPCODE(ip)                     @ jump to next instruction
445
446/* ------------------------------ */
447    .balign 64
448.L_OP_MOVE_16: /* 0x03 */
449/* File: armv5te/OP_MOVE_16.S */
450    /* for: move/16, move-object/16 */
451    /* op vAAAA, vBBBB */
452    FETCH(r1, 2)                        @ r1<- BBBB
453    FETCH(r0, 1)                        @ r0<- AAAA
454    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
455    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
456    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
457    SET_VREG(r2, r0)                    @ fp[AAAA]<- r2
458    GOTO_OPCODE(ip)                     @ jump to next instruction
459
460/* ------------------------------ */
461    .balign 64
462.L_OP_MOVE_WIDE: /* 0x04 */
463/* File: armv5te/OP_MOVE_WIDE.S */
464    /* move-wide vA, vB */
465    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
466    mov     r2, rINST, lsr #8           @ r2<- A(+)
467    mov     r3, rINST, lsr #12          @ r3<- B
468    and     r2, r2, #15
469    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
470    add     r2, rFP, r2, lsl #2         @ r2<- &fp[A]
471    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[B]
472    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
473    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
474    stmia   r2, {r0-r1}                 @ fp[A]<- r0/r1
475    GOTO_OPCODE(ip)                     @ jump to next instruction
476
477/* ------------------------------ */
478    .balign 64
479.L_OP_MOVE_WIDE_FROM16: /* 0x05 */
480/* File: armv5te/OP_MOVE_WIDE_FROM16.S */
481    /* move-wide/from16 vAA, vBBBB */
482    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
483    FETCH(r3, 1)                        @ r3<- BBBB
484    mov     r2, rINST, lsr #8           @ r2<- AA
485    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BBBB]
486    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
487    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[BBBB]
488    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
489    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
490    stmia   r2, {r0-r1}                 @ fp[AA]<- r0/r1
491    GOTO_OPCODE(ip)                     @ jump to next instruction
492
493/* ------------------------------ */
494    .balign 64
495.L_OP_MOVE_WIDE_16: /* 0x06 */
496/* File: armv5te/OP_MOVE_WIDE_16.S */
497    /* move-wide/16 vAAAA, vBBBB */
498    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
499    FETCH(r3, 2)                        @ r3<- BBBB
500    FETCH(r2, 1)                        @ r2<- AAAA
501    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BBBB]
502    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AAAA]
503    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[BBBB]
504    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
505    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
506    stmia   r2, {r0-r1}                 @ fp[AAAA]<- r0/r1
507    GOTO_OPCODE(ip)                     @ jump to next instruction
508
509/* ------------------------------ */
510    .balign 64
511.L_OP_MOVE_OBJECT: /* 0x07 */
512/* File: armv5te/OP_MOVE_OBJECT.S */
513/* File: armv5te/OP_MOVE.S */
514    /* for move, move-object, long-to-int */
515    /* op vA, vB */
516    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
517    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
518    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
519    GET_VREG(r2, r1)                    @ r2<- fp[B]
520    and     r0, r0, #15
521    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
522    SET_VREG(r2, r0)                    @ fp[A]<- r2
523    GOTO_OPCODE(ip)                     @ execute next instruction
524
525
526/* ------------------------------ */
527    .balign 64
528.L_OP_MOVE_OBJECT_FROM16: /* 0x08 */
529/* File: armv5te/OP_MOVE_OBJECT_FROM16.S */
530/* File: armv5te/OP_MOVE_FROM16.S */
531    /* for: move/from16, move-object/from16 */
532    /* op vAA, vBBBB */
533    FETCH(r1, 1)                        @ r1<- BBBB
534    mov     r0, rINST, lsr #8           @ r0<- AA
535    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
536    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
537    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
538    SET_VREG(r2, r0)                    @ fp[AA]<- r2
539    GOTO_OPCODE(ip)                     @ jump to next instruction
540
541
542/* ------------------------------ */
543    .balign 64
544.L_OP_MOVE_OBJECT_16: /* 0x09 */
545/* File: armv5te/OP_MOVE_OBJECT_16.S */
546/* File: armv5te/OP_MOVE_16.S */
547    /* for: move/16, move-object/16 */
548    /* op vAAAA, vBBBB */
549    FETCH(r1, 2)                        @ r1<- BBBB
550    FETCH(r0, 1)                        @ r0<- AAAA
551    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
552    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
553    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
554    SET_VREG(r2, r0)                    @ fp[AAAA]<- r2
555    GOTO_OPCODE(ip)                     @ jump to next instruction
556
557
558/* ------------------------------ */
559    .balign 64
560.L_OP_MOVE_RESULT: /* 0x0a */
561/* File: armv5te/OP_MOVE_RESULT.S */
562    /* for: move-result, move-result-object */
563    /* op vAA */
564    mov     r2, rINST, lsr #8           @ r2<- AA
565    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
566    ldr     r0, [rGLUE, #offGlue_retval]    @ r0<- glue->retval.i
567    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
568    SET_VREG(r0, r2)                    @ fp[AA]<- r0
569    GOTO_OPCODE(ip)                     @ jump to next instruction
570
571/* ------------------------------ */
572    .balign 64
573.L_OP_MOVE_RESULT_WIDE: /* 0x0b */
574/* File: armv5te/OP_MOVE_RESULT_WIDE.S */
575    /* move-result-wide vAA */
576    mov     r2, rINST, lsr #8           @ r2<- AA
577    add     r3, rGLUE, #offGlue_retval  @ r3<- &glue->retval
578    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
579    ldmia   r3, {r0-r1}                 @ r0/r1<- retval.j
580    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
581    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
582    stmia   r2, {r0-r1}                 @ fp[AA]<- r0/r1
583    GOTO_OPCODE(ip)                     @ jump to next instruction
584
585/* ------------------------------ */
586    .balign 64
587.L_OP_MOVE_RESULT_OBJECT: /* 0x0c */
588/* File: armv5te/OP_MOVE_RESULT_OBJECT.S */
589/* File: armv5te/OP_MOVE_RESULT.S */
590    /* for: move-result, move-result-object */
591    /* op vAA */
592    mov     r2, rINST, lsr #8           @ r2<- AA
593    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
594    ldr     r0, [rGLUE, #offGlue_retval]    @ r0<- glue->retval.i
595    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
596    SET_VREG(r0, r2)                    @ fp[AA]<- r0
597    GOTO_OPCODE(ip)                     @ jump to next instruction
598
599
600/* ------------------------------ */
601    .balign 64
602.L_OP_MOVE_EXCEPTION: /* 0x0d */
603/* File: armv5te/OP_MOVE_EXCEPTION.S */
604    /* move-exception vAA */
605    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
606    mov     r2, rINST, lsr #8           @ r2<- AA
607    ldr     r3, [r0, #offThread_exception]  @ r3<- dvmGetException bypass
608    mov     r1, #0                      @ r1<- 0
609    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
610    SET_VREG(r3, r2)                    @ fp[AA]<- exception obj
611    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
612    str     r1, [r0, #offThread_exception]  @ dvmClearException bypass
613    GOTO_OPCODE(ip)                     @ jump to next instruction
614
615/* ------------------------------ */
616    .balign 64
617.L_OP_RETURN_VOID: /* 0x0e */
618/* File: armv5te/OP_RETURN_VOID.S */
619    b       common_returnFromMethod
620
621/* ------------------------------ */
622    .balign 64
623.L_OP_RETURN: /* 0x0f */
624/* File: armv5te/OP_RETURN.S */
625    /*
626     * Return a 32-bit value.  Copies the return value into the "glue"
627     * structure, then jumps to the return handler.
628     *
629     * for: return, return-object
630     */
631    /* op vAA */
632    mov     r2, rINST, lsr #8           @ r2<- AA
633    GET_VREG(r0, r2)                    @ r0<- vAA
634    str     r0, [rGLUE, #offGlue_retval] @ retval.i <- vAA
635    b       common_returnFromMethod
636
637/* ------------------------------ */
638    .balign 64
639.L_OP_RETURN_WIDE: /* 0x10 */
640/* File: armv5te/OP_RETURN_WIDE.S */
641    /*
642     * Return a 64-bit value.  Copies the return value into the "glue"
643     * structure, then jumps to the return handler.
644     */
645    /* return-wide vAA */
646    mov     r2, rINST, lsr #8           @ r2<- AA
647    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
648    add     r3, rGLUE, #offGlue_retval  @ r3<- &glue->retval
649    ldmia   r2, {r0-r1}                 @ r0/r1 <- vAA/vAA+1
650    stmia   r3, {r0-r1}                 @ retval<- r0/r1
651    b       common_returnFromMethod
652
653/* ------------------------------ */
654    .balign 64
655.L_OP_RETURN_OBJECT: /* 0x11 */
656/* File: armv5te/OP_RETURN_OBJECT.S */
657/* File: armv5te/OP_RETURN.S */
658    /*
659     * Return a 32-bit value.  Copies the return value into the "glue"
660     * structure, then jumps to the return handler.
661     *
662     * for: return, return-object
663     */
664    /* op vAA */
665    mov     r2, rINST, lsr #8           @ r2<- AA
666    GET_VREG(r0, r2)                    @ r0<- vAA
667    str     r0, [rGLUE, #offGlue_retval] @ retval.i <- vAA
668    b       common_returnFromMethod
669
670
671/* ------------------------------ */
672    .balign 64
673.L_OP_CONST_4: /* 0x12 */
674/* File: armv5te/OP_CONST_4.S */
675    /* const/4 vA, #+B */
676    mov     r1, rINST, lsl #16          @ r1<- Bxxx0000
677    mov     r0, rINST, lsr #8           @ r0<- A+
678    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
679    mov     r1, r1, asr #28             @ r1<- sssssssB (sign-extended)
680    and     r0, r0, #15
681    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
682    SET_VREG(r1, r0)                    @ fp[A]<- r1
683    GOTO_OPCODE(ip)                     @ execute next instruction
684
685/* ------------------------------ */
686    .balign 64
687.L_OP_CONST_16: /* 0x13 */
688/* File: armv5te/OP_CONST_16.S */
689    /* const/16 vAA, #+BBBB */
690    FETCH_S(r0, 1)                      @ r0<- ssssBBBB (sign-extended)
691    mov     r3, rINST, lsr #8           @ r3<- AA
692    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
693    SET_VREG(r0, r3)                    @ vAA<- r0
694    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
695    GOTO_OPCODE(ip)                     @ jump to next instruction
696
697/* ------------------------------ */
698    .balign 64
699.L_OP_CONST: /* 0x14 */
700/* File: armv5te/OP_CONST.S */
701    /* const vAA, #+BBBBbbbb */
702    mov     r3, rINST, lsr #8           @ r3<- AA
703    FETCH(r0, 1)                        @ r0<- bbbb (low)
704    FETCH(r1, 2)                        @ r1<- BBBB (high)
705    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
706    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
707    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
708    SET_VREG(r0, r3)                    @ vAA<- r0
709    GOTO_OPCODE(ip)                     @ jump to next instruction
710
711/* ------------------------------ */
712    .balign 64
713.L_OP_CONST_HIGH16: /* 0x15 */
714/* File: armv5te/OP_CONST_HIGH16.S */
715    /* const/high16 vAA, #+BBBB0000 */
716    FETCH(r0, 1)                        @ r0<- 0000BBBB (zero-extended)
717    mov     r3, rINST, lsr #8           @ r3<- AA
718    mov     r0, r0, lsl #16             @ r0<- BBBB0000
719    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
720    SET_VREG(r0, r3)                    @ vAA<- r0
721    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
722    GOTO_OPCODE(ip)                     @ jump to next instruction
723
724/* ------------------------------ */
725    .balign 64
726.L_OP_CONST_WIDE_16: /* 0x16 */
727/* File: armv5te/OP_CONST_WIDE_16.S */
728    /* const-wide/16 vAA, #+BBBB */
729    FETCH_S(r0, 1)                      @ r0<- ssssBBBB (sign-extended)
730    mov     r3, rINST, lsr #8           @ r3<- AA
731    mov     r1, r0, asr #31             @ r1<- ssssssss
732    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
733    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
734    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
735    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
736    GOTO_OPCODE(ip)                     @ jump to next instruction
737
738/* ------------------------------ */
739    .balign 64
740.L_OP_CONST_WIDE_32: /* 0x17 */
741/* File: armv5te/OP_CONST_WIDE_32.S */
742    /* const-wide/32 vAA, #+BBBBbbbb */
743    FETCH(r0, 1)                        @ r0<- 0000bbbb (low)
744    mov     r3, rINST, lsr #8           @ r3<- AA
745    FETCH_S(r2, 2)                      @ r2<- ssssBBBB (high)
746    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
747    orr     r0, r0, r2, lsl #16         @ r0<- BBBBbbbb
748    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
749    mov     r1, r0, asr #31             @ r1<- ssssssss
750    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
751    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
752    GOTO_OPCODE(ip)                     @ jump to next instruction
753
754/* ------------------------------ */
755    .balign 64
756.L_OP_CONST_WIDE: /* 0x18 */
757/* File: armv5te/OP_CONST_WIDE.S */
758    /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
759    FETCH(r0, 1)                        @ r0<- bbbb (low)
760    FETCH(r1, 2)                        @ r1<- BBBB (low middle)
761    FETCH(r2, 3)                        @ r2<- hhhh (high middle)
762    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb (low word)
763    FETCH(r3, 4)                        @ r3<- HHHH (high)
764    mov     r9, rINST, lsr #8           @ r9<- AA
765    orr     r1, r2, r3, lsl #16         @ r1<- HHHHhhhh (high word)
766    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
767    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
768    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
769    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
770    GOTO_OPCODE(ip)                     @ jump to next instruction
771
772/* ------------------------------ */
773    .balign 64
774.L_OP_CONST_WIDE_HIGH16: /* 0x19 */
775/* File: armv5te/OP_CONST_WIDE_HIGH16.S */
776    /* const-wide/high16 vAA, #+BBBB000000000000 */
777    FETCH(r1, 1)                        @ r1<- 0000BBBB (zero-extended)
778    mov     r3, rINST, lsr #8           @ r3<- AA
779    mov     r0, #0                      @ r0<- 00000000
780    mov     r1, r1, lsl #16             @ r1<- BBBB0000
781    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
782    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
783    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
784    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
785    GOTO_OPCODE(ip)                     @ jump to next instruction
786
787/* ------------------------------ */
788    .balign 64
789.L_OP_CONST_STRING: /* 0x1a */
790/* File: armv5te/OP_CONST_STRING.S */
791    /* const/string vAA, String@BBBB */
792    FETCH(r1, 1)                        @ r1<- BBBB
793    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- glue->methodClassDex
794    mov     r9, rINST, lsr #8           @ r9<- AA
795    ldr     r2, [r2, #offDvmDex_pResStrings]   @ r2<- dvmDex->pResStrings
796    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResStrings[BBBB]
797    cmp     r0, #0                      @ not yet resolved?
798    beq     .LOP_CONST_STRING_resolve
799    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
800    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
801    SET_VREG(r0, r9)                    @ vAA<- r0
802    GOTO_OPCODE(ip)                     @ jump to next instruction
803
804/* ------------------------------ */
805    .balign 64
806.L_OP_CONST_STRING_JUMBO: /* 0x1b */
807/* File: armv5te/OP_CONST_STRING_JUMBO.S */
808    /* const/string vAA, String@BBBBBBBB */
809    FETCH(r0, 1)                        @ r0<- bbbb (low)
810    FETCH(r1, 2)                        @ r1<- BBBB (high)
811    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- glue->methodClassDex
812    mov     r9, rINST, lsr #8           @ r9<- AA
813    ldr     r2, [r2, #offDvmDex_pResStrings]   @ r2<- dvmDex->pResStrings
814    orr     r1, r0, r1, lsl #16         @ r1<- BBBBbbbb
815    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResStrings[BBBB]
816    cmp     r0, #0
817    beq     .LOP_CONST_STRING_JUMBO_resolve
818    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
819    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
820    SET_VREG(r0, r9)                    @ vAA<- r0
821    GOTO_OPCODE(ip)                     @ jump to next instruction
822
823/* ------------------------------ */
824    .balign 64
825.L_OP_CONST_CLASS: /* 0x1c */
826/* File: armv5te/OP_CONST_CLASS.S */
827    /* const/class vAA, Class@BBBB */
828    FETCH(r1, 1)                        @ r1<- BBBB
829    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- glue->methodClassDex
830    mov     r9, rINST, lsr #8           @ r9<- AA
831    ldr     r2, [r2, #offDvmDex_pResClasses]   @ r2<- dvmDex->pResClasses
832    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResClasses[BBBB]
833    cmp     r0, #0                      @ not yet resolved?
834    beq     .LOP_CONST_CLASS_resolve
835    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
836    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
837    SET_VREG(r0, r9)                    @ vAA<- r0
838    GOTO_OPCODE(ip)                     @ jump to next instruction
839
840/* ------------------------------ */
841    .balign 64
842.L_OP_MONITOR_ENTER: /* 0x1d */
843/* File: armv5te/OP_MONITOR_ENTER.S */
844    /*
845     * Synchronize on an object.
846     */
847    /* monitor-enter vAA */
848    mov     r2, rINST, lsr #8           @ r2<- AA
849    GET_VREG(r1, r2)                    @ r1<- vAA (object)
850    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
851    cmp     r1, #0                      @ null object?
852    EXPORT_PC()                         @ need for precise GC
853    beq     common_errNullObject        @ null object, throw an exception
854    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
855    bl      dvmLockObject               @ call(self, obj)
856    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
857    GOTO_OPCODE(ip)                     @ jump to next instruction
858
859/* ------------------------------ */
860    .balign 64
861.L_OP_MONITOR_EXIT: /* 0x1e */
862/* File: armv5te/OP_MONITOR_EXIT.S */
863    /*
864     * Unlock an object.
865     *
866     * Exceptions that occur when unlocking a monitor need to appear as
867     * if they happened at the following instruction.  See the Dalvik
868     * instruction spec.
869     */
870    /* monitor-exit vAA */
871    mov     r2, rINST, lsr #8           @ r2<- AA
872    EXPORT_PC()                         @ before fetch: export the PC
873    GET_VREG(r1, r2)                    @ r1<- vAA (object)
874    cmp     r1, #0                      @ null object?
875    beq     1f                          @ yes
876    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
877    bl      dvmUnlockObject             @ r0<- success for unlock(self, obj)
878    cmp     r0, #0                      @ failed?
879    FETCH_ADVANCE_INST(1)               @ before throw: advance rPC, load rINST
880    beq     common_exceptionThrown      @ yes, exception is pending
881    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
882    GOTO_OPCODE(ip)                     @ jump to next instruction
8831:
884    FETCH_ADVANCE_INST(1)               @ advance before throw
885    b      common_errNullObject
886
887/* ------------------------------ */
888    .balign 64
889.L_OP_CHECK_CAST: /* 0x1f */
890/* File: armv5te/OP_CHECK_CAST.S */
891    /*
892     * Check to see if a cast from one class to another is allowed.
893     */
894    /* check-cast vAA, class@BBBB */
895    mov     r3, rINST, lsr #8           @ r3<- AA
896    FETCH(r2, 1)                        @ r2<- BBBB
897    GET_VREG(r9, r3)                    @ r9<- object
898    ldr     r0, [rGLUE, #offGlue_methodClassDex]    @ r0<- pDvmDex
899    cmp     r9, #0                      @ is object null?
900    ldr     r0, [r0, #offDvmDex_pResClasses]    @ r0<- pDvmDex->pResClasses
901    beq     .LOP_CHECK_CAST_okay            @ null obj, cast always succeeds
902    ldr     r1, [r0, r2, lsl #2]        @ r1<- resolved class
903    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
904    cmp     r1, #0                      @ have we resolved this before?
905    beq     .LOP_CHECK_CAST_resolve         @ not resolved, do it now
906.LOP_CHECK_CAST_resolved:
907    cmp     r0, r1                      @ same class (trivial success)?
908    bne     .LOP_CHECK_CAST_fullcheck       @ no, do full check
909.LOP_CHECK_CAST_okay:
910    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
911    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
912    GOTO_OPCODE(ip)                     @ jump to next instruction
913
914/* ------------------------------ */
915    .balign 64
916.L_OP_INSTANCE_OF: /* 0x20 */
917/* File: armv5te/OP_INSTANCE_OF.S */
918    /*
919     * Check to see if an object reference is an instance of a class.
920     *
921     * Most common situation is a non-null object, being compared against
922     * an already-resolved class.
923     */
924    /* instance-of vA, vB, class@CCCC */
925    mov     r3, rINST, lsr #12          @ r3<- B
926    mov     r9, rINST, lsr #8           @ r9<- A+
927    GET_VREG(r0, r3)                    @ r0<- vB (object)
928    and     r9, r9, #15                 @ r9<- A
929    cmp     r0, #0                      @ is object null?
930    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- pDvmDex
931    beq     .LOP_INSTANCE_OF_store           @ null obj, not an instance, store r0
932    FETCH(r3, 1)                        @ r3<- CCCC
933    ldr     r2, [r2, #offDvmDex_pResClasses]    @ r2<- pDvmDex->pResClasses
934    ldr     r1, [r2, r3, lsl #2]        @ r1<- resolved class
935    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
936    cmp     r1, #0                      @ have we resolved this before?
937    beq     .LOP_INSTANCE_OF_resolve         @ not resolved, do it now
938.LOP_INSTANCE_OF_resolved: @ r0=obj->clazz, r1=resolved class
939    cmp     r0, r1                      @ same class (trivial success)?
940    beq     .LOP_INSTANCE_OF_trivial         @ yes, trivial finish
941    b       .LOP_INSTANCE_OF_fullcheck       @ no, do full check
942
943/* ------------------------------ */
944    .balign 64
945.L_OP_ARRAY_LENGTH: /* 0x21 */
946/* File: armv5te/OP_ARRAY_LENGTH.S */
947    /*
948     * Return the length of an array.
949     */
950    mov     r1, rINST, lsr #12          @ r1<- B
951    mov     r2, rINST, lsr #8           @ r2<- A+
952    GET_VREG(r0, r1)                    @ r0<- vB (object ref)
953    and     r2, r2, #15                 @ r2<- A
954    cmp     r0, #0                      @ is object null?
955    beq     common_errNullObject        @ yup, fail
956    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
957    ldr     r3, [r0, #offArrayObject_length]    @ r3<- array length
958    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
959    SET_VREG(r3, r2)                    @ vB<- length
960    GOTO_OPCODE(ip)                     @ jump to next instruction
961
962/* ------------------------------ */
963    .balign 64
964.L_OP_NEW_INSTANCE: /* 0x22 */
965/* File: armv5te/OP_NEW_INSTANCE.S */
966    /*
967     * Create a new instance of a class.
968     */
969    /* new-instance vAA, class@BBBB */
970    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
971    FETCH(r1, 1)                        @ r1<- BBBB
972    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
973    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
974    EXPORT_PC()                         @ req'd for init, resolve, alloc
975    cmp     r0, #0                      @ already resolved?
976    beq     .LOP_NEW_INSTANCE_resolve         @ no, resolve it now
977.LOP_NEW_INSTANCE_resolved:   @ r0=class
978    ldrb    r1, [r0, #offClassObject_status]    @ r1<- ClassStatus enum
979    cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
980    bne     .LOP_NEW_INSTANCE_needinit        @ no, init class now
981.LOP_NEW_INSTANCE_initialized: @ r0=class
982    mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
983    bl      dvmAllocObject              @ r0<- new object
984    b       .LOP_NEW_INSTANCE_finish          @ continue
985
986/* ------------------------------ */
987    .balign 64
988.L_OP_NEW_ARRAY: /* 0x23 */
989/* File: armv5te/OP_NEW_ARRAY.S */
990    /*
991     * Allocate an array of objects, specified with the array class
992     * and a count.
993     *
994     * The verifier guarantees that this is an array class, so we don't
995     * check for it here.
996     */
997    /* new-array vA, vB, class@CCCC */
998    mov     r0, rINST, lsr #12          @ r0<- B
999    FETCH(r2, 1)                        @ r2<- CCCC
1000    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
1001    GET_VREG(r1, r0)                    @ r1<- vB (array length)
1002    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1003    cmp     r1, #0                      @ check length
1004    ldr     r0, [r3, r2, lsl #2]        @ r0<- resolved class
1005    bmi     common_errNegativeArraySize @ negative length, bail
1006    cmp     r0, #0                      @ already resolved?
1007    EXPORT_PC()                         @ req'd for resolve, alloc
1008    bne     .LOP_NEW_ARRAY_finish          @ resolved, continue
1009    b       .LOP_NEW_ARRAY_resolve         @ do resolve now
1010
1011/* ------------------------------ */
1012    .balign 64
1013.L_OP_FILLED_NEW_ARRAY: /* 0x24 */
1014/* File: armv5te/OP_FILLED_NEW_ARRAY.S */
1015    /*
1016     * Create a new array with elements filled from registers.
1017     *
1018     * for: filled-new-array, filled-new-array/range
1019     */
1020    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1021    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1022    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
1023    FETCH(r1, 1)                        @ r1<- BBBB
1024    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1025    EXPORT_PC()                         @ need for resolve and alloc
1026    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
1027    mov     r10, rINST, lsr #8          @ r10<- AA or BA
1028    cmp     r0, #0                      @ already resolved?
1029    bne     .LOP_FILLED_NEW_ARRAY_continue        @ yes, continue on
10308:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
1031    mov     r2, #0                      @ r2<- false
1032    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
1033    bl      dvmResolveClass             @ r0<- call(clazz, ref)
1034    cmp     r0, #0                      @ got null?
1035    beq     common_exceptionThrown      @ yes, handle exception
1036    b       .LOP_FILLED_NEW_ARRAY_continue
1037
1038/* ------------------------------ */
1039    .balign 64
1040.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
1041/* File: armv5te/OP_FILLED_NEW_ARRAY_RANGE.S */
1042/* File: armv5te/OP_FILLED_NEW_ARRAY.S */
1043    /*
1044     * Create a new array with elements filled from registers.
1045     *
1046     * for: filled-new-array, filled-new-array/range
1047     */
1048    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1049    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1050    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
1051    FETCH(r1, 1)                        @ r1<- BBBB
1052    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1053    EXPORT_PC()                         @ need for resolve and alloc
1054    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
1055    mov     r10, rINST, lsr #8          @ r10<- AA or BA
1056    cmp     r0, #0                      @ already resolved?
1057    bne     .LOP_FILLED_NEW_ARRAY_RANGE_continue        @ yes, continue on
10588:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
1059    mov     r2, #0                      @ r2<- false
1060    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
1061    bl      dvmResolveClass             @ r0<- call(clazz, ref)
1062    cmp     r0, #0                      @ got null?
1063    beq     common_exceptionThrown      @ yes, handle exception
1064    b       .LOP_FILLED_NEW_ARRAY_RANGE_continue
1065
1066
1067/* ------------------------------ */
1068    .balign 64
1069.L_OP_FILL_ARRAY_DATA: /* 0x26 */
1070/* File: armv5te/OP_FILL_ARRAY_DATA.S */
1071    /* fill-array-data vAA, +BBBBBBBB */
1072    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1073    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1074    mov     r3, rINST, lsr #8           @ r3<- AA
1075    orr     r1, r0, r1, lsl #16         @ r1<- BBBBbbbb
1076    GET_VREG(r0, r3)                    @ r0<- vAA (array object)
1077    add     r1, rPC, r1, lsl #1         @ r1<- PC + BBBBbbbb*2 (array data off.)
1078    EXPORT_PC();
1079    bl      dvmInterpHandleFillArrayData@ fill the array with predefined data
1080    cmp     r0, #0                      @ 0 means an exception is thrown
1081    beq     common_exceptionThrown      @ has exception
1082    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
1083    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1084    GOTO_OPCODE(ip)                     @ jump to next instruction
1085
1086/* ------------------------------ */
1087    .balign 64
1088.L_OP_THROW: /* 0x27 */
1089/* File: armv5te/OP_THROW.S */
1090    /*
1091     * Throw an exception object in the current thread.
1092     */
1093    /* throw vAA */
1094    mov     r2, rINST, lsr #8           @ r2<- AA
1095    GET_VREG(r1, r2)                    @ r1<- vAA (exception object)
1096    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
1097    EXPORT_PC()                         @ exception handler can throw
1098    cmp     r1, #0                      @ null object?
1099    beq     common_errNullObject        @ yes, throw an NPE instead
1100    @ bypass dvmSetException, just store it
1101    str     r1, [r0, #offThread_exception]  @ thread->exception<- obj
1102    b       common_exceptionThrown
1103
1104/* ------------------------------ */
1105    .balign 64
1106.L_OP_GOTO: /* 0x28 */
1107/* File: armv5te/OP_GOTO.S */
1108    /*
1109     * Unconditional branch, 8-bit offset.
1110     *
1111     * The branch distance is a signed code-unit offset, which we need to
1112     * double to get a byte offset.
1113     */
1114    /* goto +AA */
1115    mov     r0, rINST, lsl #16          @ r0<- AAxx0000
1116    movs    r9, r0, asr #24             @ r9<- ssssssAA (sign-extended)
1117    mov     r9, r9, lsl #1              @ r9<- byte offset
1118    bmi     common_backwardBranch       @ backward branch, do periodic checks
1119#if defined(WITH_JIT)
1120    GET_JIT_PROF_TABLE(r0)
1121    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1122    cmp     r0,#0
1123    bne     common_updateProfile
1124    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1125    GOTO_OPCODE(ip)                     @ jump to next instruction
1126#else
1127    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1128    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1129    GOTO_OPCODE(ip)                     @ jump to next instruction
1130#endif
1131
1132/* ------------------------------ */
1133    .balign 64
1134.L_OP_GOTO_16: /* 0x29 */
1135/* File: armv5te/OP_GOTO_16.S */
1136    /*
1137     * Unconditional branch, 16-bit offset.
1138     *
1139     * The branch distance is a signed code-unit offset, which we need to
1140     * double to get a byte offset.
1141     */
1142    /* goto/16 +AAAA */
1143    FETCH_S(r0, 1)                      @ r0<- ssssAAAA (sign-extended)
1144    movs    r9, r0, asl #1              @ r9<- byte offset, check sign
1145    bmi     common_backwardBranch       @ backward branch, do periodic checks
1146#if defined(WITH_JIT)
1147    GET_JIT_PROF_TABLE(r0)
1148    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1149    cmp     r0,#0
1150    bne     common_updateProfile
1151    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1152    GOTO_OPCODE(ip)                     @ jump to next instruction
1153#else
1154    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1155    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1156    GOTO_OPCODE(ip)                     @ jump to next instruction
1157#endif
1158
1159/* ------------------------------ */
1160    .balign 64
1161.L_OP_GOTO_32: /* 0x2a */
1162/* File: armv5te/OP_GOTO_32.S */
1163    /*
1164     * Unconditional branch, 32-bit offset.
1165     *
1166     * The branch distance is a signed code-unit offset, which we need to
1167     * double to get a byte offset.
1168     *
1169     * Unlike most opcodes, this one is allowed to branch to itself, so
1170     * our "backward branch" test must be "<=0" instead of "<0".  The ORRS
1171     * instruction doesn't affect the V flag, so we need to clear it
1172     * explicitly.
1173     */
1174    /* goto/32 +AAAAAAAA */
1175    FETCH(r0, 1)                        @ r0<- aaaa (lo)
1176    FETCH(r1, 2)                        @ r1<- AAAA (hi)
1177    cmp     ip, ip                      @ (clear V flag during stall)
1178    orrs    r0, r0, r1, lsl #16         @ r0<- AAAAaaaa, check sign
1179    mov     r9, r0, asl #1              @ r9<- byte offset
1180    ble     common_backwardBranch       @ backward branch, do periodic checks
1181#if defined(WITH_JIT)
1182    GET_JIT_PROF_TABLE(r0)
1183    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1184    cmp     r0,#0
1185    bne     common_updateProfile
1186    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1187    GOTO_OPCODE(ip)                     @ jump to next instruction
1188#else
1189    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1190    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1191    GOTO_OPCODE(ip)                     @ jump to next instruction
1192#endif
1193
1194/* ------------------------------ */
1195    .balign 64
1196.L_OP_PACKED_SWITCH: /* 0x2b */
1197/* File: armv5te/OP_PACKED_SWITCH.S */
1198    /*
1199     * Handle a packed-switch or sparse-switch instruction.  In both cases
1200     * we decode it and hand it off to a helper function.
1201     *
1202     * We don't really expect backward branches in a switch statement, but
1203     * they're perfectly legal, so we check for them here.
1204     *
1205     * for: packed-switch, sparse-switch
1206     */
1207    /* op vAA, +BBBB */
1208    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1209    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1210    mov     r3, rINST, lsr #8           @ r3<- AA
1211    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
1212    GET_VREG(r1, r3)                    @ r1<- vAA
1213    add     r0, rPC, r0, lsl #1         @ r0<- PC + BBBBbbbb*2
1214    bl      dvmInterpHandlePackedSwitch                       @ r0<- code-unit branch offset
1215    movs    r9, r0, asl #1              @ r9<- branch byte offset, check sign
1216    bmi     common_backwardBranch       @ backward branch, do periodic checks
1217    beq     common_backwardBranch       @ (want to use BLE but V is unknown)
1218#if defined(WITH_JIT)
1219    GET_JIT_PROF_TABLE(r0)
1220    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1221    cmp     r0,#0
1222    bne     common_updateProfile
1223    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1224    GOTO_OPCODE(ip)                     @ jump to next instruction
1225#else
1226    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1227    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1228    GOTO_OPCODE(ip)                     @ jump to next instruction
1229#endif
1230
1231/* ------------------------------ */
1232    .balign 64
1233.L_OP_SPARSE_SWITCH: /* 0x2c */
1234/* File: armv5te/OP_SPARSE_SWITCH.S */
1235/* File: armv5te/OP_PACKED_SWITCH.S */
1236    /*
1237     * Handle a packed-switch or sparse-switch instruction.  In both cases
1238     * we decode it and hand it off to a helper function.
1239     *
1240     * We don't really expect backward branches in a switch statement, but
1241     * they're perfectly legal, so we check for them here.
1242     *
1243     * for: packed-switch, sparse-switch
1244     */
1245    /* op vAA, +BBBB */
1246    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1247    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1248    mov     r3, rINST, lsr #8           @ r3<- AA
1249    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
1250    GET_VREG(r1, r3)                    @ r1<- vAA
1251    add     r0, rPC, r0, lsl #1         @ r0<- PC + BBBBbbbb*2
1252    bl      dvmInterpHandleSparseSwitch                       @ r0<- code-unit branch offset
1253    movs    r9, r0, asl #1              @ r9<- branch byte offset, check sign
1254    bmi     common_backwardBranch       @ backward branch, do periodic checks
1255    beq     common_backwardBranch       @ (want to use BLE but V is unknown)
1256#if defined(WITH_JIT)
1257    GET_JIT_PROF_TABLE(r0)
1258    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1259    cmp     r0,#0
1260    bne     common_updateProfile
1261    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1262    GOTO_OPCODE(ip)                     @ jump to next instruction
1263#else
1264    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1265    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1266    GOTO_OPCODE(ip)                     @ jump to next instruction
1267#endif
1268
1269
1270/* ------------------------------ */
1271    .balign 64
1272.L_OP_CMPL_FLOAT: /* 0x2d */
1273/* File: arm-vfp/OP_CMPL_FLOAT.S */
1274    /*
1275     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1276     * destination register based on the results of the comparison.
1277     *
1278     * int compare(x, y) {
1279     *     if (x == y) {
1280     *         return 0;
1281     *     } else if (x > y) {
1282     *         return 1;
1283     *     } else if (x < y) {
1284     *         return -1;
1285     *     } else {
1286     *         return -1;
1287     *     }
1288     * }
1289     */
1290    /* op vAA, vBB, vCC */
1291    FETCH(r0, 1)                        @ r0<- CCBB
1292    mov     r9, rINST, lsr #8           @ r9<- AA
1293    and     r2, r0, #255                @ r2<- BB
1294    mov     r3, r0, lsr #8              @ r3<- CC
1295    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1296    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1297    flds    s0, [r2]                    @ s0<- vBB
1298    flds    s1, [r3]                    @ s1<- vCC
1299    fcmpes  s0, s1                      @ compare (vBB, vCC)
1300    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1301    mvn     r0, #0                      @ r0<- -1 (default)
1302    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1303    fmstat                              @ export status flags
1304    movgt   r0, #1                      @ (greater than) r1<- 1
1305    moveq   r0, #0                      @ (equal) r1<- 0
1306    b       .LOP_CMPL_FLOAT_finish          @ argh
1307
1308
1309/* ------------------------------ */
1310    .balign 64
1311.L_OP_CMPG_FLOAT: /* 0x2e */
1312/* File: arm-vfp/OP_CMPG_FLOAT.S */
1313    /*
1314     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1315     * destination register based on the results of the comparison.
1316     *
1317     * int compare(x, y) {
1318     *     if (x == y) {
1319     *         return 0;
1320     *     } else if (x < y) {
1321     *         return -1;
1322     *     } else if (x > y) {
1323     *         return 1;
1324     *     } else {
1325     *         return 1;
1326     *     }
1327     * }
1328     */
1329    /* op vAA, vBB, vCC */
1330    FETCH(r0, 1)                        @ r0<- CCBB
1331    mov     r9, rINST, lsr #8           @ r9<- AA
1332    and     r2, r0, #255                @ r2<- BB
1333    mov     r3, r0, lsr #8              @ r3<- CC
1334    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1335    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1336    flds    s0, [r2]                    @ s0<- vBB
1337    flds    s1, [r3]                    @ s1<- vCC
1338    fcmpes  s0, s1                      @ compare (vBB, vCC)
1339    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1340    mov     r0, #1                      @ r0<- 1 (default)
1341    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1342    fmstat                              @ export status flags
1343    mvnmi   r0, #0                      @ (less than) r1<- -1
1344    moveq   r0, #0                      @ (equal) r1<- 0
1345    b       .LOP_CMPG_FLOAT_finish          @ argh
1346
1347
1348/* ------------------------------ */
1349    .balign 64
1350.L_OP_CMPL_DOUBLE: /* 0x2f */
1351/* File: arm-vfp/OP_CMPL_DOUBLE.S */
1352    /*
1353     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1354     * destination register based on the results of the comparison.
1355     *
1356     * int compare(x, y) {
1357     *     if (x == y) {
1358     *         return 0;
1359     *     } else if (x > y) {
1360     *         return 1;
1361     *     } else if (x < y) {
1362     *         return -1;
1363     *     } else {
1364     *         return -1;
1365     *     }
1366     * }
1367     */
1368    /* op vAA, vBB, vCC */
1369    FETCH(r0, 1)                        @ r0<- CCBB
1370    mov     r9, rINST, lsr #8           @ r9<- AA
1371    and     r2, r0, #255                @ r2<- BB
1372    mov     r3, r0, lsr #8              @ r3<- CC
1373    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1374    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1375    fldd    d0, [r2]                    @ d0<- vBB
1376    fldd    d1, [r3]                    @ d1<- vCC
1377    fcmped  d0, d1                      @ compare (vBB, vCC)
1378    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1379    mvn     r0, #0                      @ r0<- -1 (default)
1380    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1381    fmstat                              @ export status flags
1382    movgt   r0, #1                      @ (greater than) r1<- 1
1383    moveq   r0, #0                      @ (equal) r1<- 0
1384    b       .LOP_CMPL_DOUBLE_finish          @ argh
1385
1386
1387/* ------------------------------ */
1388    .balign 64
1389.L_OP_CMPG_DOUBLE: /* 0x30 */
1390/* File: arm-vfp/OP_CMPG_DOUBLE.S */
1391    /*
1392     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1393     * destination register based on the results of the comparison.
1394     *
1395     * int compare(x, y) {
1396     *     if (x == y) {
1397     *         return 0;
1398     *     } else if (x < y) {
1399     *         return -1;
1400     *     } else if (x > y) {
1401     *         return 1;
1402     *     } else {
1403     *         return 1;
1404     *     }
1405     * }
1406     */
1407    /* op vAA, vBB, vCC */
1408    FETCH(r0, 1)                        @ r0<- CCBB
1409    mov     r9, rINST, lsr #8           @ r9<- AA
1410    and     r2, r0, #255                @ r2<- BB
1411    mov     r3, r0, lsr #8              @ r3<- CC
1412    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1413    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1414    fldd    d0, [r2]                    @ d0<- vBB
1415    fldd    d1, [r3]                    @ d1<- vCC
1416    fcmped  d0, d1                      @ compare (vBB, vCC)
1417    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1418    mov     r0, #1                      @ r0<- 1 (default)
1419    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1420    fmstat                              @ export status flags
1421    mvnmi   r0, #0                      @ (less than) r1<- -1
1422    moveq   r0, #0                      @ (equal) r1<- 0
1423    b       .LOP_CMPG_DOUBLE_finish          @ argh
1424
1425
1426/* ------------------------------ */
1427    .balign 64
1428.L_OP_CMP_LONG: /* 0x31 */
1429/* File: armv5te/OP_CMP_LONG.S */
1430    /*
1431     * Compare two 64-bit values.  Puts 0, 1, or -1 into the destination
1432     * register based on the results of the comparison.
1433     *
1434     * We load the full values with LDM, but in practice many values could
1435     * be resolved by only looking at the high word.  This could be made
1436     * faster or slower by splitting the LDM into a pair of LDRs.
1437     *
1438     * If we just wanted to set condition flags, we could do this:
1439     *  subs    ip, r0, r2
1440     *  sbcs    ip, r1, r3
1441     *  subeqs  ip, r0, r2
1442     * Leaving { <0, 0, >0 } in ip.  However, we have to set it to a specific
1443     * integer value, which we can do with 2 conditional mov/mvn instructions
1444     * (set 1, set -1; if they're equal we already have 0 in ip), giving
1445     * us a constant 5-cycle path plus a branch at the end to the
1446     * instruction epilogue code.  The multi-compare approach below needs
1447     * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch
1448     * in the worst case (the 64-bit values are equal).
1449     */
1450    /* cmp-long vAA, vBB, vCC */
1451    FETCH(r0, 1)                        @ r0<- CCBB
1452    mov     r9, rINST, lsr #8           @ r9<- AA
1453    and     r2, r0, #255                @ r2<- BB
1454    mov     r3, r0, lsr #8              @ r3<- CC
1455    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
1456    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
1457    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
1458    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
1459    cmp     r1, r3                      @ compare (vBB+1, vCC+1)
1460    blt     .LOP_CMP_LONG_less            @ signed compare on high part
1461    bgt     .LOP_CMP_LONG_greater
1462    subs    r1, r0, r2                  @ r1<- r0 - r2
1463    bhi     .LOP_CMP_LONG_greater         @ unsigned compare on low part
1464    bne     .LOP_CMP_LONG_less
1465    b       .LOP_CMP_LONG_finish          @ equal; r1 already holds 0
1466
1467/* ------------------------------ */
1468    .balign 64
1469.L_OP_IF_EQ: /* 0x32 */
1470/* File: armv5te/OP_IF_EQ.S */
1471/* File: armv5te/bincmp.S */
1472    /*
1473     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1474     * fragment that specifies the *reverse* comparison to perform, e.g.
1475     * for "if-le" you would use "gt".
1476     *
1477     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1478     */
1479    /* if-cmp vA, vB, +CCCC */
1480    mov     r0, rINST, lsr #8           @ r0<- A+
1481    mov     r1, rINST, lsr #12          @ r1<- B
1482    and     r0, r0, #15
1483    GET_VREG(r3, r1)                    @ r3<- vB
1484    GET_VREG(r2, r0)                    @ r2<- vA
1485    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1486    cmp     r2, r3                      @ compare (vA, vB)
1487    bne  1f                      @ branch to 1 if comparison failed
1488    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1489    movs    r9, r9, asl #1              @ convert to bytes, check sign
1490    bmi     common_backwardBranch       @ yes, do periodic checks
14911:
1492#if defined(WITH_JIT)
1493    GET_JIT_PROF_TABLE(r0)
1494    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1495    b        common_testUpdateProfile
1496#else
1497    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1498    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1499    GOTO_OPCODE(ip)                     @ jump to next instruction
1500#endif
1501
1502
1503/* ------------------------------ */
1504    .balign 64
1505.L_OP_IF_NE: /* 0x33 */
1506/* File: armv5te/OP_IF_NE.S */
1507/* File: armv5te/bincmp.S */
1508    /*
1509     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1510     * fragment that specifies the *reverse* comparison to perform, e.g.
1511     * for "if-le" you would use "gt".
1512     *
1513     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1514     */
1515    /* if-cmp vA, vB, +CCCC */
1516    mov     r0, rINST, lsr #8           @ r0<- A+
1517    mov     r1, rINST, lsr #12          @ r1<- B
1518    and     r0, r0, #15
1519    GET_VREG(r3, r1)                    @ r3<- vB
1520    GET_VREG(r2, r0)                    @ r2<- vA
1521    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1522    cmp     r2, r3                      @ compare (vA, vB)
1523    beq  1f                      @ branch to 1 if comparison failed
1524    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1525    movs    r9, r9, asl #1              @ convert to bytes, check sign
1526    bmi     common_backwardBranch       @ yes, do periodic checks
15271:
1528#if defined(WITH_JIT)
1529    GET_JIT_PROF_TABLE(r0)
1530    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1531    b        common_testUpdateProfile
1532#else
1533    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1534    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1535    GOTO_OPCODE(ip)                     @ jump to next instruction
1536#endif
1537
1538
1539/* ------------------------------ */
1540    .balign 64
1541.L_OP_IF_LT: /* 0x34 */
1542/* File: armv5te/OP_IF_LT.S */
1543/* File: armv5te/bincmp.S */
1544    /*
1545     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1546     * fragment that specifies the *reverse* comparison to perform, e.g.
1547     * for "if-le" you would use "gt".
1548     *
1549     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1550     */
1551    /* if-cmp vA, vB, +CCCC */
1552    mov     r0, rINST, lsr #8           @ r0<- A+
1553    mov     r1, rINST, lsr #12          @ r1<- B
1554    and     r0, r0, #15
1555    GET_VREG(r3, r1)                    @ r3<- vB
1556    GET_VREG(r2, r0)                    @ r2<- vA
1557    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1558    cmp     r2, r3                      @ compare (vA, vB)
1559    bge  1f                      @ branch to 1 if comparison failed
1560    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1561    movs    r9, r9, asl #1              @ convert to bytes, check sign
1562    bmi     common_backwardBranch       @ yes, do periodic checks
15631:
1564#if defined(WITH_JIT)
1565    GET_JIT_PROF_TABLE(r0)
1566    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1567    b        common_testUpdateProfile
1568#else
1569    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1570    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1571    GOTO_OPCODE(ip)                     @ jump to next instruction
1572#endif
1573
1574
1575/* ------------------------------ */
1576    .balign 64
1577.L_OP_IF_GE: /* 0x35 */
1578/* File: armv5te/OP_IF_GE.S */
1579/* File: armv5te/bincmp.S */
1580    /*
1581     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1582     * fragment that specifies the *reverse* comparison to perform, e.g.
1583     * for "if-le" you would use "gt".
1584     *
1585     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1586     */
1587    /* if-cmp vA, vB, +CCCC */
1588    mov     r0, rINST, lsr #8           @ r0<- A+
1589    mov     r1, rINST, lsr #12          @ r1<- B
1590    and     r0, r0, #15
1591    GET_VREG(r3, r1)                    @ r3<- vB
1592    GET_VREG(r2, r0)                    @ r2<- vA
1593    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1594    cmp     r2, r3                      @ compare (vA, vB)
1595    blt  1f                      @ branch to 1 if comparison failed
1596    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1597    movs    r9, r9, asl #1              @ convert to bytes, check sign
1598    bmi     common_backwardBranch       @ yes, do periodic checks
15991:
1600#if defined(WITH_JIT)
1601    GET_JIT_PROF_TABLE(r0)
1602    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1603    b        common_testUpdateProfile
1604#else
1605    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1606    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1607    GOTO_OPCODE(ip)                     @ jump to next instruction
1608#endif
1609
1610
1611/* ------------------------------ */
1612    .balign 64
1613.L_OP_IF_GT: /* 0x36 */
1614/* File: armv5te/OP_IF_GT.S */
1615/* File: armv5te/bincmp.S */
1616    /*
1617     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1618     * fragment that specifies the *reverse* comparison to perform, e.g.
1619     * for "if-le" you would use "gt".
1620     *
1621     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1622     */
1623    /* if-cmp vA, vB, +CCCC */
1624    mov     r0, rINST, lsr #8           @ r0<- A+
1625    mov     r1, rINST, lsr #12          @ r1<- B
1626    and     r0, r0, #15
1627    GET_VREG(r3, r1)                    @ r3<- vB
1628    GET_VREG(r2, r0)                    @ r2<- vA
1629    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1630    cmp     r2, r3                      @ compare (vA, vB)
1631    ble  1f                      @ branch to 1 if comparison failed
1632    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1633    movs    r9, r9, asl #1              @ convert to bytes, check sign
1634    bmi     common_backwardBranch       @ yes, do periodic checks
16351:
1636#if defined(WITH_JIT)
1637    GET_JIT_PROF_TABLE(r0)
1638    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1639    b        common_testUpdateProfile
1640#else
1641    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1642    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1643    GOTO_OPCODE(ip)                     @ jump to next instruction
1644#endif
1645
1646
1647/* ------------------------------ */
1648    .balign 64
1649.L_OP_IF_LE: /* 0x37 */
1650/* File: armv5te/OP_IF_LE.S */
1651/* File: armv5te/bincmp.S */
1652    /*
1653     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1654     * fragment that specifies the *reverse* comparison to perform, e.g.
1655     * for "if-le" you would use "gt".
1656     *
1657     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1658     */
1659    /* if-cmp vA, vB, +CCCC */
1660    mov     r0, rINST, lsr #8           @ r0<- A+
1661    mov     r1, rINST, lsr #12          @ r1<- B
1662    and     r0, r0, #15
1663    GET_VREG(r3, r1)                    @ r3<- vB
1664    GET_VREG(r2, r0)                    @ r2<- vA
1665    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1666    cmp     r2, r3                      @ compare (vA, vB)
1667    bgt  1f                      @ branch to 1 if comparison failed
1668    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1669    movs    r9, r9, asl #1              @ convert to bytes, check sign
1670    bmi     common_backwardBranch       @ yes, do periodic checks
16711:
1672#if defined(WITH_JIT)
1673    GET_JIT_PROF_TABLE(r0)
1674    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1675    b        common_testUpdateProfile
1676#else
1677    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1678    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1679    GOTO_OPCODE(ip)                     @ jump to next instruction
1680#endif
1681
1682
1683/* ------------------------------ */
1684    .balign 64
1685.L_OP_IF_EQZ: /* 0x38 */
1686/* File: armv5te/OP_IF_EQZ.S */
1687/* File: armv5te/zcmp.S */
1688    /*
1689     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1690     * fragment that specifies the *reverse* comparison to perform, e.g.
1691     * for "if-le" you would use "gt".
1692     *
1693     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1694     */
1695    /* if-cmp vAA, +BBBB */
1696    mov     r0, rINST, lsr #8           @ r0<- AA
1697    GET_VREG(r2, r0)                    @ r2<- vAA
1698    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1699    cmp     r2, #0                      @ compare (vA, 0)
1700    bne  1f                      @ branch to 1 if comparison failed
1701    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1702    movs    r9, r9, asl #1              @ convert to bytes, check sign
1703    bmi     common_backwardBranch       @ backward branch, do periodic checks
17041:
1705#if defined(WITH_JIT)
1706    GET_JIT_PROF_TABLE(r0)
1707    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1708    cmp     r0,#0
1709    bne     common_updateProfile
1710    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1711    GOTO_OPCODE(ip)                     @ jump to next instruction
1712#else
1713    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1714    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1715    GOTO_OPCODE(ip)                     @ jump to next instruction
1716#endif
1717
1718
1719/* ------------------------------ */
1720    .balign 64
1721.L_OP_IF_NEZ: /* 0x39 */
1722/* File: armv5te/OP_IF_NEZ.S */
1723/* File: armv5te/zcmp.S */
1724    /*
1725     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1726     * fragment that specifies the *reverse* comparison to perform, e.g.
1727     * for "if-le" you would use "gt".
1728     *
1729     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1730     */
1731    /* if-cmp vAA, +BBBB */
1732    mov     r0, rINST, lsr #8           @ r0<- AA
1733    GET_VREG(r2, r0)                    @ r2<- vAA
1734    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1735    cmp     r2, #0                      @ compare (vA, 0)
1736    beq  1f                      @ branch to 1 if comparison failed
1737    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1738    movs    r9, r9, asl #1              @ convert to bytes, check sign
1739    bmi     common_backwardBranch       @ backward branch, do periodic checks
17401:
1741#if defined(WITH_JIT)
1742    GET_JIT_PROF_TABLE(r0)
1743    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1744    cmp     r0,#0
1745    bne     common_updateProfile
1746    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1747    GOTO_OPCODE(ip)                     @ jump to next instruction
1748#else
1749    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1750    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1751    GOTO_OPCODE(ip)                     @ jump to next instruction
1752#endif
1753
1754
1755/* ------------------------------ */
1756    .balign 64
1757.L_OP_IF_LTZ: /* 0x3a */
1758/* File: armv5te/OP_IF_LTZ.S */
1759/* File: armv5te/zcmp.S */
1760    /*
1761     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1762     * fragment that specifies the *reverse* comparison to perform, e.g.
1763     * for "if-le" you would use "gt".
1764     *
1765     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1766     */
1767    /* if-cmp vAA, +BBBB */
1768    mov     r0, rINST, lsr #8           @ r0<- AA
1769    GET_VREG(r2, r0)                    @ r2<- vAA
1770    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1771    cmp     r2, #0                      @ compare (vA, 0)
1772    bge  1f                      @ branch to 1 if comparison failed
1773    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1774    movs    r9, r9, asl #1              @ convert to bytes, check sign
1775    bmi     common_backwardBranch       @ backward branch, do periodic checks
17761:
1777#if defined(WITH_JIT)
1778    GET_JIT_PROF_TABLE(r0)
1779    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1780    cmp     r0,#0
1781    bne     common_updateProfile
1782    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1783    GOTO_OPCODE(ip)                     @ jump to next instruction
1784#else
1785    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1786    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1787    GOTO_OPCODE(ip)                     @ jump to next instruction
1788#endif
1789
1790
1791/* ------------------------------ */
1792    .balign 64
1793.L_OP_IF_GEZ: /* 0x3b */
1794/* File: armv5te/OP_IF_GEZ.S */
1795/* File: armv5te/zcmp.S */
1796    /*
1797     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1798     * fragment that specifies the *reverse* comparison to perform, e.g.
1799     * for "if-le" you would use "gt".
1800     *
1801     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1802     */
1803    /* if-cmp vAA, +BBBB */
1804    mov     r0, rINST, lsr #8           @ r0<- AA
1805    GET_VREG(r2, r0)                    @ r2<- vAA
1806    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1807    cmp     r2, #0                      @ compare (vA, 0)
1808    blt  1f                      @ branch to 1 if comparison failed
1809    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1810    movs    r9, r9, asl #1              @ convert to bytes, check sign
1811    bmi     common_backwardBranch       @ backward branch, do periodic checks
18121:
1813#if defined(WITH_JIT)
1814    GET_JIT_PROF_TABLE(r0)
1815    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1816    cmp     r0,#0
1817    bne     common_updateProfile
1818    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1819    GOTO_OPCODE(ip)                     @ jump to next instruction
1820#else
1821    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1822    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1823    GOTO_OPCODE(ip)                     @ jump to next instruction
1824#endif
1825
1826
1827/* ------------------------------ */
1828    .balign 64
1829.L_OP_IF_GTZ: /* 0x3c */
1830/* File: armv5te/OP_IF_GTZ.S */
1831/* File: armv5te/zcmp.S */
1832    /*
1833     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1834     * fragment that specifies the *reverse* comparison to perform, e.g.
1835     * for "if-le" you would use "gt".
1836     *
1837     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1838     */
1839    /* if-cmp vAA, +BBBB */
1840    mov     r0, rINST, lsr #8           @ r0<- AA
1841    GET_VREG(r2, r0)                    @ r2<- vAA
1842    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1843    cmp     r2, #0                      @ compare (vA, 0)
1844    ble  1f                      @ branch to 1 if comparison failed
1845    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1846    movs    r9, r9, asl #1              @ convert to bytes, check sign
1847    bmi     common_backwardBranch       @ backward branch, do periodic checks
18481:
1849#if defined(WITH_JIT)
1850    GET_JIT_PROF_TABLE(r0)
1851    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1852    cmp     r0,#0
1853    bne     common_updateProfile
1854    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1855    GOTO_OPCODE(ip)                     @ jump to next instruction
1856#else
1857    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1858    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1859    GOTO_OPCODE(ip)                     @ jump to next instruction
1860#endif
1861
1862
1863/* ------------------------------ */
1864    .balign 64
1865.L_OP_IF_LEZ: /* 0x3d */
1866/* File: armv5te/OP_IF_LEZ.S */
1867/* File: armv5te/zcmp.S */
1868    /*
1869     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1870     * fragment that specifies the *reverse* comparison to perform, e.g.
1871     * for "if-le" you would use "gt".
1872     *
1873     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1874     */
1875    /* if-cmp vAA, +BBBB */
1876    mov     r0, rINST, lsr #8           @ r0<- AA
1877    GET_VREG(r2, r0)                    @ r2<- vAA
1878    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1879    cmp     r2, #0                      @ compare (vA, 0)
1880    bgt  1f                      @ branch to 1 if comparison failed
1881    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1882    movs    r9, r9, asl #1              @ convert to bytes, check sign
1883    bmi     common_backwardBranch       @ backward branch, do periodic checks
18841:
1885#if defined(WITH_JIT)
1886    GET_JIT_PROF_TABLE(r0)
1887    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1888    cmp     r0,#0
1889    bne     common_updateProfile
1890    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1891    GOTO_OPCODE(ip)                     @ jump to next instruction
1892#else
1893    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1894    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1895    GOTO_OPCODE(ip)                     @ jump to next instruction
1896#endif
1897
1898
1899/* ------------------------------ */
1900    .balign 64
1901.L_OP_UNUSED_3E: /* 0x3e */
1902/* File: armv5te/OP_UNUSED_3E.S */
1903/* File: armv5te/unused.S */
1904    bl      common_abort
1905
1906
1907/* ------------------------------ */
1908    .balign 64
1909.L_OP_UNUSED_3F: /* 0x3f */
1910/* File: armv5te/OP_UNUSED_3F.S */
1911/* File: armv5te/unused.S */
1912    bl      common_abort
1913
1914
1915/* ------------------------------ */
1916    .balign 64
1917.L_OP_UNUSED_40: /* 0x40 */
1918/* File: armv5te/OP_UNUSED_40.S */
1919/* File: armv5te/unused.S */
1920    bl      common_abort
1921
1922
1923/* ------------------------------ */
1924    .balign 64
1925.L_OP_UNUSED_41: /* 0x41 */
1926/* File: armv5te/OP_UNUSED_41.S */
1927/* File: armv5te/unused.S */
1928    bl      common_abort
1929
1930
1931/* ------------------------------ */
1932    .balign 64
1933.L_OP_UNUSED_42: /* 0x42 */
1934/* File: armv5te/OP_UNUSED_42.S */
1935/* File: armv5te/unused.S */
1936    bl      common_abort
1937
1938
1939/* ------------------------------ */
1940    .balign 64
1941.L_OP_UNUSED_43: /* 0x43 */
1942/* File: armv5te/OP_UNUSED_43.S */
1943/* File: armv5te/unused.S */
1944    bl      common_abort
1945
1946
1947/* ------------------------------ */
1948    .balign 64
1949.L_OP_AGET: /* 0x44 */
1950/* File: armv5te/OP_AGET.S */
1951    /*
1952     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1953     *
1954     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
1955     * instructions.  We use a pair of FETCH_Bs instead.
1956     *
1957     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1958     */
1959    /* op vAA, vBB, vCC */
1960    FETCH_B(r2, 1, 0)                   @ r2<- BB
1961    mov     r9, rINST, lsr #8           @ r9<- AA
1962    FETCH_B(r3, 1, 1)                   @ r3<- CC
1963    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1964    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1965    cmp     r0, #0                      @ null array object?
1966    beq     common_errNullObject        @ yes, bail
1967    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1968    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
1969    cmp     r1, r3                      @ compare unsigned index, length
1970    bcs     common_errArrayIndex        @ index >= length, bail
1971    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1972    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
1973    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1974    SET_VREG(r2, r9)                    @ vAA<- r2
1975    GOTO_OPCODE(ip)                     @ jump to next instruction
1976
1977/* ------------------------------ */
1978    .balign 64
1979.L_OP_AGET_WIDE: /* 0x45 */
1980/* File: armv5te/OP_AGET_WIDE.S */
1981    /*
1982     * Array get, 64 bits.  vAA <- vBB[vCC].
1983     *
1984     * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD.
1985     */
1986    /* aget-wide vAA, vBB, vCC */
1987    FETCH(r0, 1)                        @ r0<- CCBB
1988    mov     r9, rINST, lsr #8           @ r9<- AA
1989    and     r2, r0, #255                @ r2<- BB
1990    mov     r3, r0, lsr #8              @ r3<- CC
1991    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1992    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1993    cmp     r0, #0                      @ null array object?
1994    beq     common_errNullObject        @ yes, bail
1995    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1996    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
1997    cmp     r1, r3                      @ compare unsigned index, length
1998    bcc     .LOP_AGET_WIDE_finish          @ okay, continue below
1999    b       common_errArrayIndex        @ index >= length, bail
2000    @ May want to swap the order of these two branches depending on how the
2001    @ branch prediction (if any) handles conditional forward branches vs.
2002    @ unconditional forward branches.
2003
2004/* ------------------------------ */
2005    .balign 64
2006.L_OP_AGET_OBJECT: /* 0x46 */
2007/* File: armv5te/OP_AGET_OBJECT.S */
2008/* File: armv5te/OP_AGET.S */
2009    /*
2010     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2011     *
2012     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2013     * instructions.  We use a pair of FETCH_Bs instead.
2014     *
2015     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2016     */
2017    /* op vAA, vBB, vCC */
2018    FETCH_B(r2, 1, 0)                   @ r2<- BB
2019    mov     r9, rINST, lsr #8           @ r9<- AA
2020    FETCH_B(r3, 1, 1)                   @ r3<- CC
2021    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2022    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2023    cmp     r0, #0                      @ null array object?
2024    beq     common_errNullObject        @ yes, bail
2025    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2026    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
2027    cmp     r1, r3                      @ compare unsigned index, length
2028    bcs     common_errArrayIndex        @ index >= length, bail
2029    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2030    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2031    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2032    SET_VREG(r2, r9)                    @ vAA<- r2
2033    GOTO_OPCODE(ip)                     @ jump to next instruction
2034
2035
2036/* ------------------------------ */
2037    .balign 64
2038.L_OP_AGET_BOOLEAN: /* 0x47 */
2039/* File: armv5te/OP_AGET_BOOLEAN.S */
2040/* File: armv5te/OP_AGET.S */
2041    /*
2042     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2043     *
2044     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2045     * instructions.  We use a pair of FETCH_Bs instead.
2046     *
2047     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2048     */
2049    /* op vAA, vBB, vCC */
2050    FETCH_B(r2, 1, 0)                   @ r2<- BB
2051    mov     r9, rINST, lsr #8           @ r9<- AA
2052    FETCH_B(r3, 1, 1)                   @ r3<- CC
2053    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2054    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2055    cmp     r0, #0                      @ null array object?
2056    beq     common_errNullObject        @ yes, bail
2057    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2058    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2059    cmp     r1, r3                      @ compare unsigned index, length
2060    bcs     common_errArrayIndex        @ index >= length, bail
2061    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2062    ldrb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2063    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2064    SET_VREG(r2, r9)                    @ vAA<- r2
2065    GOTO_OPCODE(ip)                     @ jump to next instruction
2066
2067
2068/* ------------------------------ */
2069    .balign 64
2070.L_OP_AGET_BYTE: /* 0x48 */
2071/* File: armv5te/OP_AGET_BYTE.S */
2072/* File: armv5te/OP_AGET.S */
2073    /*
2074     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2075     *
2076     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2077     * instructions.  We use a pair of FETCH_Bs instead.
2078     *
2079     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2080     */
2081    /* op vAA, vBB, vCC */
2082    FETCH_B(r2, 1, 0)                   @ r2<- BB
2083    mov     r9, rINST, lsr #8           @ r9<- AA
2084    FETCH_B(r3, 1, 1)                   @ r3<- CC
2085    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2086    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2087    cmp     r0, #0                      @ null array object?
2088    beq     common_errNullObject        @ yes, bail
2089    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2090    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2091    cmp     r1, r3                      @ compare unsigned index, length
2092    bcs     common_errArrayIndex        @ index >= length, bail
2093    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2094    ldrsb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2095    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2096    SET_VREG(r2, r9)                    @ vAA<- r2
2097    GOTO_OPCODE(ip)                     @ jump to next instruction
2098
2099
2100/* ------------------------------ */
2101    .balign 64
2102.L_OP_AGET_CHAR: /* 0x49 */
2103/* File: armv5te/OP_AGET_CHAR.S */
2104/* File: armv5te/OP_AGET.S */
2105    /*
2106     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2107     *
2108     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2109     * instructions.  We use a pair of FETCH_Bs instead.
2110     *
2111     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2112     */
2113    /* op vAA, vBB, vCC */
2114    FETCH_B(r2, 1, 0)                   @ r2<- BB
2115    mov     r9, rINST, lsr #8           @ r9<- AA
2116    FETCH_B(r3, 1, 1)                   @ r3<- CC
2117    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2118    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2119    cmp     r0, #0                      @ null array object?
2120    beq     common_errNullObject        @ yes, bail
2121    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2122    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2123    cmp     r1, r3                      @ compare unsigned index, length
2124    bcs     common_errArrayIndex        @ index >= length, bail
2125    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2126    ldrh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2127    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2128    SET_VREG(r2, r9)                    @ vAA<- r2
2129    GOTO_OPCODE(ip)                     @ jump to next instruction
2130
2131
2132/* ------------------------------ */
2133    .balign 64
2134.L_OP_AGET_SHORT: /* 0x4a */
2135/* File: armv5te/OP_AGET_SHORT.S */
2136/* File: armv5te/OP_AGET.S */
2137    /*
2138     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2139     *
2140     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2141     * instructions.  We use a pair of FETCH_Bs instead.
2142     *
2143     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2144     */
2145    /* op vAA, vBB, vCC */
2146    FETCH_B(r2, 1, 0)                   @ r2<- BB
2147    mov     r9, rINST, lsr #8           @ r9<- AA
2148    FETCH_B(r3, 1, 1)                   @ r3<- CC
2149    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2150    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2151    cmp     r0, #0                      @ null array object?
2152    beq     common_errNullObject        @ yes, bail
2153    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2154    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2155    cmp     r1, r3                      @ compare unsigned index, length
2156    bcs     common_errArrayIndex        @ index >= length, bail
2157    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2158    ldrsh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2159    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2160    SET_VREG(r2, r9)                    @ vAA<- r2
2161    GOTO_OPCODE(ip)                     @ jump to next instruction
2162
2163
2164/* ------------------------------ */
2165    .balign 64
2166.L_OP_APUT: /* 0x4b */
2167/* File: armv5te/OP_APUT.S */
2168    /*
2169     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2170     *
2171     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2172     * instructions.  We use a pair of FETCH_Bs instead.
2173     *
2174     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2175     */
2176    /* op vAA, vBB, vCC */
2177    FETCH_B(r2, 1, 0)                   @ r2<- BB
2178    mov     r9, rINST, lsr #8           @ r9<- AA
2179    FETCH_B(r3, 1, 1)                   @ r3<- CC
2180    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2181    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2182    cmp     r0, #0                      @ null array object?
2183    beq     common_errNullObject        @ yes, bail
2184    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2185    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
2186    cmp     r1, r3                      @ compare unsigned index, length
2187    bcs     common_errArrayIndex        @ index >= length, bail
2188    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2189    GET_VREG(r2, r9)                    @ r2<- vAA
2190    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2191    str  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2192    GOTO_OPCODE(ip)                     @ jump to next instruction
2193
2194/* ------------------------------ */
2195    .balign 64
2196.L_OP_APUT_WIDE: /* 0x4c */
2197/* File: armv5te/OP_APUT_WIDE.S */
2198    /*
2199     * Array put, 64 bits.  vBB[vCC] <- vAA.
2200     *
2201     * Arrays of long/double are 64-bit aligned, so it's okay to use STRD.
2202     */
2203    /* aput-wide vAA, vBB, vCC */
2204    FETCH(r0, 1)                        @ r0<- CCBB
2205    mov     r9, rINST, lsr #8           @ r9<- AA
2206    and     r2, r0, #255                @ r2<- BB
2207    mov     r3, r0, lsr #8              @ r3<- CC
2208    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2209    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2210    cmp     r0, #0                      @ null array object?
2211    beq     common_errNullObject        @ yes, bail
2212    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2213    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
2214    cmp     r1, r3                      @ compare unsigned index, length
2215    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2216    bcc     .LOP_APUT_WIDE_finish          @ okay, continue below
2217    b       common_errArrayIndex        @ index >= length, bail
2218    @ May want to swap the order of these two branches depending on how the
2219    @ branch prediction (if any) handles conditional forward branches vs.
2220    @ unconditional forward branches.
2221
2222/* ------------------------------ */
2223    .balign 64
2224.L_OP_APUT_OBJECT: /* 0x4d */
2225/* File: armv5te/OP_APUT_OBJECT.S */
2226    /*
2227     * Store an object into an array.  vBB[vCC] <- vAA.
2228     */
2229    /* op vAA, vBB, vCC */
2230    FETCH(r0, 1)                        @ r0<- CCBB
2231    mov     r9, rINST, lsr #8           @ r9<- AA
2232    and     r2, r0, #255                @ r2<- BB
2233    mov     r3, r0, lsr #8              @ r3<- CC
2234    GET_VREG(rINST, r2)                 @ rINST<- vBB (array object)
2235    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2236    cmp     rINST, #0                   @ null array object?
2237    GET_VREG(r9, r9)                    @ r9<- vAA
2238    beq     common_errNullObject        @ yes, bail
2239    ldr     r3, [rINST, #offArrayObject_length]   @ r3<- arrayObj->length
2240    add     r10, rINST, r1, lsl #2      @ r10<- arrayObj + index*width
2241    cmp     r1, r3                      @ compare unsigned index, length
2242    bcc     .LOP_APUT_OBJECT_finish          @ we're okay, continue on
2243    b       common_errArrayIndex        @ index >= length, bail
2244
2245
2246/* ------------------------------ */
2247    .balign 64
2248.L_OP_APUT_BOOLEAN: /* 0x4e */
2249/* File: armv5te/OP_APUT_BOOLEAN.S */
2250/* File: armv5te/OP_APUT.S */
2251    /*
2252     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2253     *
2254     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2255     * instructions.  We use a pair of FETCH_Bs instead.
2256     *
2257     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2258     */
2259    /* op vAA, vBB, vCC */
2260    FETCH_B(r2, 1, 0)                   @ r2<- BB
2261    mov     r9, rINST, lsr #8           @ r9<- AA
2262    FETCH_B(r3, 1, 1)                   @ r3<- CC
2263    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2264    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2265    cmp     r0, #0                      @ null array object?
2266    beq     common_errNullObject        @ yes, bail
2267    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2268    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2269    cmp     r1, r3                      @ compare unsigned index, length
2270    bcs     common_errArrayIndex        @ index >= length, bail
2271    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2272    GET_VREG(r2, r9)                    @ r2<- vAA
2273    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2274    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2275    GOTO_OPCODE(ip)                     @ jump to next instruction
2276
2277
2278/* ------------------------------ */
2279    .balign 64
2280.L_OP_APUT_BYTE: /* 0x4f */
2281/* File: armv5te/OP_APUT_BYTE.S */
2282/* File: armv5te/OP_APUT.S */
2283    /*
2284     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2285     *
2286     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2287     * instructions.  We use a pair of FETCH_Bs instead.
2288     *
2289     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2290     */
2291    /* op vAA, vBB, vCC */
2292    FETCH_B(r2, 1, 0)                   @ r2<- BB
2293    mov     r9, rINST, lsr #8           @ r9<- AA
2294    FETCH_B(r3, 1, 1)                   @ r3<- CC
2295    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2296    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2297    cmp     r0, #0                      @ null array object?
2298    beq     common_errNullObject        @ yes, bail
2299    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2300    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2301    cmp     r1, r3                      @ compare unsigned index, length
2302    bcs     common_errArrayIndex        @ index >= length, bail
2303    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2304    GET_VREG(r2, r9)                    @ r2<- vAA
2305    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2306    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2307    GOTO_OPCODE(ip)                     @ jump to next instruction
2308
2309
2310/* ------------------------------ */
2311    .balign 64
2312.L_OP_APUT_CHAR: /* 0x50 */
2313/* File: armv5te/OP_APUT_CHAR.S */
2314/* File: armv5te/OP_APUT.S */
2315    /*
2316     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2317     *
2318     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2319     * instructions.  We use a pair of FETCH_Bs instead.
2320     *
2321     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2322     */
2323    /* op vAA, vBB, vCC */
2324    FETCH_B(r2, 1, 0)                   @ r2<- BB
2325    mov     r9, rINST, lsr #8           @ r9<- AA
2326    FETCH_B(r3, 1, 1)                   @ r3<- CC
2327    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2328    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2329    cmp     r0, #0                      @ null array object?
2330    beq     common_errNullObject        @ yes, bail
2331    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2332    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2333    cmp     r1, r3                      @ compare unsigned index, length
2334    bcs     common_errArrayIndex        @ index >= length, bail
2335    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2336    GET_VREG(r2, r9)                    @ r2<- vAA
2337    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2338    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2339    GOTO_OPCODE(ip)                     @ jump to next instruction
2340
2341
2342/* ------------------------------ */
2343    .balign 64
2344.L_OP_APUT_SHORT: /* 0x51 */
2345/* File: armv5te/OP_APUT_SHORT.S */
2346/* File: armv5te/OP_APUT.S */
2347    /*
2348     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2349     *
2350     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2351     * instructions.  We use a pair of FETCH_Bs instead.
2352     *
2353     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2354     */
2355    /* op vAA, vBB, vCC */
2356    FETCH_B(r2, 1, 0)                   @ r2<- BB
2357    mov     r9, rINST, lsr #8           @ r9<- AA
2358    FETCH_B(r3, 1, 1)                   @ r3<- CC
2359    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2360    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2361    cmp     r0, #0                      @ null array object?
2362    beq     common_errNullObject        @ yes, bail
2363    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2364    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2365    cmp     r1, r3                      @ compare unsigned index, length
2366    bcs     common_errArrayIndex        @ index >= length, bail
2367    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2368    GET_VREG(r2, r9)                    @ r2<- vAA
2369    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2370    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2371    GOTO_OPCODE(ip)                     @ jump to next instruction
2372
2373
2374/* ------------------------------ */
2375    .balign 64
2376.L_OP_IGET: /* 0x52 */
2377/* File: armv5te/OP_IGET.S */
2378    /*
2379     * General 32-bit instance field get.
2380     *
2381     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2382     */
2383    /* op vA, vB, field@CCCC */
2384    mov     r0, rINST, lsr #12          @ r0<- B
2385    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2386    FETCH(r1, 1)                        @ r1<- field ref CCCC
2387    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2388    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2389    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2390    cmp     r0, #0                      @ is resolved entry null?
2391    bne     .LOP_IGET_finish          @ no, already resolved
23928:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2393    EXPORT_PC()                         @ resolve() could throw
2394    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2395    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2396    cmp     r0, #0
2397    bne     .LOP_IGET_finish
2398    b       common_exceptionThrown
2399
2400/* ------------------------------ */
2401    .balign 64
2402.L_OP_IGET_WIDE: /* 0x53 */
2403/* File: armv5te/OP_IGET_WIDE.S */
2404    /*
2405     * Wide 32-bit instance field get.
2406     */
2407    /* iget-wide vA, vB, field@CCCC */
2408    mov     r0, rINST, lsr #12          @ r0<- B
2409    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2410    FETCH(r1, 1)                        @ r1<- field ref CCCC
2411    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
2412    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2413    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2414    cmp     r0, #0                      @ is resolved entry null?
2415    bne     .LOP_IGET_WIDE_finish          @ no, already resolved
24168:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
2417    EXPORT_PC()                         @ resolve() could throw
2418    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2419    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2420    cmp     r0, #0
2421    bne     .LOP_IGET_WIDE_finish
2422    b       common_exceptionThrown
2423
2424/* ------------------------------ */
2425    .balign 64
2426.L_OP_IGET_OBJECT: /* 0x54 */
2427/* File: armv5te/OP_IGET_OBJECT.S */
2428/* File: armv5te/OP_IGET.S */
2429    /*
2430     * General 32-bit instance field get.
2431     *
2432     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2433     */
2434    /* op vA, vB, field@CCCC */
2435    mov     r0, rINST, lsr #12          @ r0<- B
2436    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2437    FETCH(r1, 1)                        @ r1<- field ref CCCC
2438    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2439    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2440    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2441    cmp     r0, #0                      @ is resolved entry null?
2442    bne     .LOP_IGET_OBJECT_finish          @ no, already resolved
24438:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2444    EXPORT_PC()                         @ resolve() could throw
2445    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2446    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2447    cmp     r0, #0
2448    bne     .LOP_IGET_OBJECT_finish
2449    b       common_exceptionThrown
2450
2451
2452/* ------------------------------ */
2453    .balign 64
2454.L_OP_IGET_BOOLEAN: /* 0x55 */
2455/* File: armv5te/OP_IGET_BOOLEAN.S */
2456@include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" }
2457/* File: armv5te/OP_IGET.S */
2458    /*
2459     * General 32-bit instance field get.
2460     *
2461     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2462     */
2463    /* op vA, vB, field@CCCC */
2464    mov     r0, rINST, lsr #12          @ r0<- B
2465    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2466    FETCH(r1, 1)                        @ r1<- field ref CCCC
2467    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2468    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2469    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2470    cmp     r0, #0                      @ is resolved entry null?
2471    bne     .LOP_IGET_BOOLEAN_finish          @ no, already resolved
24728:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2473    EXPORT_PC()                         @ resolve() could throw
2474    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2475    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2476    cmp     r0, #0
2477    bne     .LOP_IGET_BOOLEAN_finish
2478    b       common_exceptionThrown
2479
2480
2481/* ------------------------------ */
2482    .balign 64
2483.L_OP_IGET_BYTE: /* 0x56 */
2484/* File: armv5te/OP_IGET_BYTE.S */
2485@include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" }
2486/* File: armv5te/OP_IGET.S */
2487    /*
2488     * General 32-bit instance field get.
2489     *
2490     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2491     */
2492    /* op vA, vB, field@CCCC */
2493    mov     r0, rINST, lsr #12          @ r0<- B
2494    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2495    FETCH(r1, 1)                        @ r1<- field ref CCCC
2496    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2497    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2498    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2499    cmp     r0, #0                      @ is resolved entry null?
2500    bne     .LOP_IGET_BYTE_finish          @ no, already resolved
25018:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2502    EXPORT_PC()                         @ resolve() could throw
2503    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2504    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2505    cmp     r0, #0
2506    bne     .LOP_IGET_BYTE_finish
2507    b       common_exceptionThrown
2508
2509
2510/* ------------------------------ */
2511    .balign 64
2512.L_OP_IGET_CHAR: /* 0x57 */
2513/* File: armv5te/OP_IGET_CHAR.S */
2514@include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" }
2515/* File: armv5te/OP_IGET.S */
2516    /*
2517     * General 32-bit instance field get.
2518     *
2519     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2520     */
2521    /* op vA, vB, field@CCCC */
2522    mov     r0, rINST, lsr #12          @ r0<- B
2523    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2524    FETCH(r1, 1)                        @ r1<- field ref CCCC
2525    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2526    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2527    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2528    cmp     r0, #0                      @ is resolved entry null?
2529    bne     .LOP_IGET_CHAR_finish          @ no, already resolved
25308:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2531    EXPORT_PC()                         @ resolve() could throw
2532    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2533    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2534    cmp     r0, #0
2535    bne     .LOP_IGET_CHAR_finish
2536    b       common_exceptionThrown
2537
2538
2539/* ------------------------------ */
2540    .balign 64
2541.L_OP_IGET_SHORT: /* 0x58 */
2542/* File: armv5te/OP_IGET_SHORT.S */
2543@include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" }
2544/* File: armv5te/OP_IGET.S */
2545    /*
2546     * General 32-bit instance field get.
2547     *
2548     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2549     */
2550    /* op vA, vB, field@CCCC */
2551    mov     r0, rINST, lsr #12          @ r0<- B
2552    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2553    FETCH(r1, 1)                        @ r1<- field ref CCCC
2554    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2555    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2556    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2557    cmp     r0, #0                      @ is resolved entry null?
2558    bne     .LOP_IGET_SHORT_finish          @ no, already resolved
25598:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2560    EXPORT_PC()                         @ resolve() could throw
2561    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2562    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2563    cmp     r0, #0
2564    bne     .LOP_IGET_SHORT_finish
2565    b       common_exceptionThrown
2566
2567
2568/* ------------------------------ */
2569    .balign 64
2570.L_OP_IPUT: /* 0x59 */
2571/* File: armv5te/OP_IPUT.S */
2572    /*
2573     * General 32-bit instance field put.
2574     *
2575     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2576     */
2577    /* op vA, vB, field@CCCC */
2578    mov     r0, rINST, lsr #12          @ r0<- B
2579    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2580    FETCH(r1, 1)                        @ r1<- field ref CCCC
2581    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2582    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2583    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2584    cmp     r0, #0                      @ is resolved entry null?
2585    bne     .LOP_IPUT_finish          @ no, already resolved
25868:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2587    EXPORT_PC()                         @ resolve() could throw
2588    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2589    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2590    cmp     r0, #0                      @ success?
2591    bne     .LOP_IPUT_finish          @ yes, finish up
2592    b       common_exceptionThrown
2593
2594/* ------------------------------ */
2595    .balign 64
2596.L_OP_IPUT_WIDE: /* 0x5a */
2597/* File: armv5te/OP_IPUT_WIDE.S */
2598    /* iput-wide vA, vB, field@CCCC */
2599    mov     r0, rINST, lsr #12          @ r0<- B
2600    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2601    FETCH(r1, 1)                        @ r1<- field ref CCCC
2602    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
2603    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2604    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2605    cmp     r0, #0                      @ is resolved entry null?
2606    bne     .LOP_IPUT_WIDE_finish          @ no, already resolved
26078:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
2608    EXPORT_PC()                         @ resolve() could throw
2609    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2610    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2611    cmp     r0, #0                      @ success?
2612    bne     .LOP_IPUT_WIDE_finish          @ yes, finish up
2613    b       common_exceptionThrown
2614
2615/* ------------------------------ */
2616    .balign 64
2617.L_OP_IPUT_OBJECT: /* 0x5b */
2618/* File: armv5te/OP_IPUT_OBJECT.S */
2619    /*
2620     * 32-bit instance field put.
2621     *
2622     * for: iput-object, iput-object-volatile
2623     */
2624    /* op vA, vB, field@CCCC */
2625    mov     r0, rINST, lsr #12          @ r0<- B
2626    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2627    FETCH(r1, 1)                        @ r1<- field ref CCCC
2628    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2629    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2630    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2631    cmp     r0, #0                      @ is resolved entry null?
2632    bne     .LOP_IPUT_OBJECT_finish          @ no, already resolved
26338:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2634    EXPORT_PC()                         @ resolve() could throw
2635    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2636    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2637    cmp     r0, #0                      @ success?
2638    bne     .LOP_IPUT_OBJECT_finish          @ yes, finish up
2639    b       common_exceptionThrown
2640
2641/* ------------------------------ */
2642    .balign 64
2643.L_OP_IPUT_BOOLEAN: /* 0x5c */
2644/* File: armv5te/OP_IPUT_BOOLEAN.S */
2645@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" }
2646/* File: armv5te/OP_IPUT.S */
2647    /*
2648     * General 32-bit instance field put.
2649     *
2650     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2651     */
2652    /* op vA, vB, field@CCCC */
2653    mov     r0, rINST, lsr #12          @ r0<- B
2654    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2655    FETCH(r1, 1)                        @ r1<- field ref CCCC
2656    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2657    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2658    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2659    cmp     r0, #0                      @ is resolved entry null?
2660    bne     .LOP_IPUT_BOOLEAN_finish          @ no, already resolved
26618:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2662    EXPORT_PC()                         @ resolve() could throw
2663    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2664    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2665    cmp     r0, #0                      @ success?
2666    bne     .LOP_IPUT_BOOLEAN_finish          @ yes, finish up
2667    b       common_exceptionThrown
2668
2669
2670/* ------------------------------ */
2671    .balign 64
2672.L_OP_IPUT_BYTE: /* 0x5d */
2673/* File: armv5te/OP_IPUT_BYTE.S */
2674@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" }
2675/* File: armv5te/OP_IPUT.S */
2676    /*
2677     * General 32-bit instance field put.
2678     *
2679     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2680     */
2681    /* op vA, vB, field@CCCC */
2682    mov     r0, rINST, lsr #12          @ r0<- B
2683    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2684    FETCH(r1, 1)                        @ r1<- field ref CCCC
2685    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2686    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2687    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2688    cmp     r0, #0                      @ is resolved entry null?
2689    bne     .LOP_IPUT_BYTE_finish          @ no, already resolved
26908:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2691    EXPORT_PC()                         @ resolve() could throw
2692    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2693    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2694    cmp     r0, #0                      @ success?
2695    bne     .LOP_IPUT_BYTE_finish          @ yes, finish up
2696    b       common_exceptionThrown
2697
2698
2699/* ------------------------------ */
2700    .balign 64
2701.L_OP_IPUT_CHAR: /* 0x5e */
2702/* File: armv5te/OP_IPUT_CHAR.S */
2703@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" }
2704/* File: armv5te/OP_IPUT.S */
2705    /*
2706     * General 32-bit instance field put.
2707     *
2708     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2709     */
2710    /* op vA, vB, field@CCCC */
2711    mov     r0, rINST, lsr #12          @ r0<- B
2712    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2713    FETCH(r1, 1)                        @ r1<- field ref CCCC
2714    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2715    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2716    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2717    cmp     r0, #0                      @ is resolved entry null?
2718    bne     .LOP_IPUT_CHAR_finish          @ no, already resolved
27198:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2720    EXPORT_PC()                         @ resolve() could throw
2721    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2722    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2723    cmp     r0, #0                      @ success?
2724    bne     .LOP_IPUT_CHAR_finish          @ yes, finish up
2725    b       common_exceptionThrown
2726
2727
2728/* ------------------------------ */
2729    .balign 64
2730.L_OP_IPUT_SHORT: /* 0x5f */
2731/* File: armv5te/OP_IPUT_SHORT.S */
2732@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" }
2733/* File: armv5te/OP_IPUT.S */
2734    /*
2735     * General 32-bit instance field put.
2736     *
2737     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2738     */
2739    /* op vA, vB, field@CCCC */
2740    mov     r0, rINST, lsr #12          @ r0<- B
2741    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2742    FETCH(r1, 1)                        @ r1<- field ref CCCC
2743    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2744    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2745    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2746    cmp     r0, #0                      @ is resolved entry null?
2747    bne     .LOP_IPUT_SHORT_finish          @ no, already resolved
27488:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2749    EXPORT_PC()                         @ resolve() could throw
2750    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2751    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2752    cmp     r0, #0                      @ success?
2753    bne     .LOP_IPUT_SHORT_finish          @ yes, finish up
2754    b       common_exceptionThrown
2755
2756
2757/* ------------------------------ */
2758    .balign 64
2759.L_OP_SGET: /* 0x60 */
2760/* File: armv5te/OP_SGET.S */
2761    /*
2762     * General 32-bit SGET handler.
2763     *
2764     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2765     */
2766    /* op vAA, field@BBBB */
2767    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2768    FETCH(r1, 1)                        @ r1<- field ref BBBB
2769    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2770    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2771    cmp     r0, #0                      @ is resolved entry null?
2772    beq     .LOP_SGET_resolve         @ yes, do resolve
2773.LOP_SGET_finish: @ field ptr in r0
2774    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2775    @ no-op                             @ acquiring load
2776    mov     r2, rINST, lsr #8           @ r2<- AA
2777    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2778    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2779    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2780    GOTO_OPCODE(ip)                     @ jump to next instruction
2781
2782/* ------------------------------ */
2783    .balign 64
2784.L_OP_SGET_WIDE: /* 0x61 */
2785/* File: armv5te/OP_SGET_WIDE.S */
2786    /*
2787     * 64-bit SGET handler.
2788     */
2789    /* sget-wide vAA, field@BBBB */
2790    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2791    FETCH(r1, 1)                        @ r1<- field ref BBBB
2792    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2793    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2794    cmp     r0, #0                      @ is resolved entry null?
2795    beq     .LOP_SGET_WIDE_resolve         @ yes, do resolve
2796.LOP_SGET_WIDE_finish:
2797    mov     r9, rINST, lsr #8           @ r9<- AA
2798    .if 0
2799    add     r0, r0, #offStaticField_value @ r0<- pointer to data
2800    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
2801    .else
2802    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
2803    .endif
2804    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2805    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2806    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
2807    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2808    GOTO_OPCODE(ip)                     @ jump to next instruction
2809
2810/* ------------------------------ */
2811    .balign 64
2812.L_OP_SGET_OBJECT: /* 0x62 */
2813/* File: armv5te/OP_SGET_OBJECT.S */
2814/* File: armv5te/OP_SGET.S */
2815    /*
2816     * General 32-bit SGET handler.
2817     *
2818     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2819     */
2820    /* op vAA, field@BBBB */
2821    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2822    FETCH(r1, 1)                        @ r1<- field ref BBBB
2823    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2824    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2825    cmp     r0, #0                      @ is resolved entry null?
2826    beq     .LOP_SGET_OBJECT_resolve         @ yes, do resolve
2827.LOP_SGET_OBJECT_finish: @ field ptr in r0
2828    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2829    @ no-op                             @ acquiring load
2830    mov     r2, rINST, lsr #8           @ r2<- AA
2831    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2832    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2833    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2834    GOTO_OPCODE(ip)                     @ jump to next instruction
2835
2836
2837/* ------------------------------ */
2838    .balign 64
2839.L_OP_SGET_BOOLEAN: /* 0x63 */
2840/* File: armv5te/OP_SGET_BOOLEAN.S */
2841/* File: armv5te/OP_SGET.S */
2842    /*
2843     * General 32-bit SGET handler.
2844     *
2845     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2846     */
2847    /* op vAA, field@BBBB */
2848    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2849    FETCH(r1, 1)                        @ r1<- field ref BBBB
2850    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2851    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2852    cmp     r0, #0                      @ is resolved entry null?
2853    beq     .LOP_SGET_BOOLEAN_resolve         @ yes, do resolve
2854.LOP_SGET_BOOLEAN_finish: @ field ptr in r0
2855    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2856    @ no-op                             @ acquiring load
2857    mov     r2, rINST, lsr #8           @ r2<- AA
2858    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2859    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2860    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2861    GOTO_OPCODE(ip)                     @ jump to next instruction
2862
2863
2864/* ------------------------------ */
2865    .balign 64
2866.L_OP_SGET_BYTE: /* 0x64 */
2867/* File: armv5te/OP_SGET_BYTE.S */
2868/* File: armv5te/OP_SGET.S */
2869    /*
2870     * General 32-bit SGET handler.
2871     *
2872     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2873     */
2874    /* op vAA, field@BBBB */
2875    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2876    FETCH(r1, 1)                        @ r1<- field ref BBBB
2877    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2878    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2879    cmp     r0, #0                      @ is resolved entry null?
2880    beq     .LOP_SGET_BYTE_resolve         @ yes, do resolve
2881.LOP_SGET_BYTE_finish: @ field ptr in r0
2882    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2883    @ no-op                             @ acquiring load
2884    mov     r2, rINST, lsr #8           @ r2<- AA
2885    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2886    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2887    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2888    GOTO_OPCODE(ip)                     @ jump to next instruction
2889
2890
2891/* ------------------------------ */
2892    .balign 64
2893.L_OP_SGET_CHAR: /* 0x65 */
2894/* File: armv5te/OP_SGET_CHAR.S */
2895/* File: armv5te/OP_SGET.S */
2896    /*
2897     * General 32-bit SGET handler.
2898     *
2899     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2900     */
2901    /* op vAA, field@BBBB */
2902    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2903    FETCH(r1, 1)                        @ r1<- field ref BBBB
2904    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2905    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2906    cmp     r0, #0                      @ is resolved entry null?
2907    beq     .LOP_SGET_CHAR_resolve         @ yes, do resolve
2908.LOP_SGET_CHAR_finish: @ field ptr in r0
2909    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2910    @ no-op                             @ acquiring load
2911    mov     r2, rINST, lsr #8           @ r2<- AA
2912    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2913    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2914    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2915    GOTO_OPCODE(ip)                     @ jump to next instruction
2916
2917
2918/* ------------------------------ */
2919    .balign 64
2920.L_OP_SGET_SHORT: /* 0x66 */
2921/* File: armv5te/OP_SGET_SHORT.S */
2922/* File: armv5te/OP_SGET.S */
2923    /*
2924     * General 32-bit SGET handler.
2925     *
2926     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2927     */
2928    /* op vAA, field@BBBB */
2929    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2930    FETCH(r1, 1)                        @ r1<- field ref BBBB
2931    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2932    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2933    cmp     r0, #0                      @ is resolved entry null?
2934    beq     .LOP_SGET_SHORT_resolve         @ yes, do resolve
2935.LOP_SGET_SHORT_finish: @ field ptr in r0
2936    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2937    @ no-op                             @ acquiring load
2938    mov     r2, rINST, lsr #8           @ r2<- AA
2939    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2940    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2941    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2942    GOTO_OPCODE(ip)                     @ jump to next instruction
2943
2944
2945/* ------------------------------ */
2946    .balign 64
2947.L_OP_SPUT: /* 0x67 */
2948/* File: armv5te/OP_SPUT.S */
2949    /*
2950     * General 32-bit SPUT handler.
2951     *
2952     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2953     */
2954    /* op vAA, field@BBBB */
2955    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2956    FETCH(r1, 1)                        @ r1<- field ref BBBB
2957    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2958    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2959    cmp     r0, #0                      @ is resolved entry null?
2960    beq     .LOP_SPUT_resolve         @ yes, do resolve
2961.LOP_SPUT_finish:   @ field ptr in r0
2962    mov     r2, rINST, lsr #8           @ r2<- AA
2963    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2964    GET_VREG(r1, r2)                    @ r1<- fp[AA]
2965    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2966    @ no-op                             @ releasing store
2967    str     r1, [r0, #offStaticField_value] @ field<- vAA
2968    GOTO_OPCODE(ip)                     @ jump to next instruction
2969
2970/* ------------------------------ */
2971    .balign 64
2972.L_OP_SPUT_WIDE: /* 0x68 */
2973/* File: armv5te/OP_SPUT_WIDE.S */
2974    /*
2975     * 64-bit SPUT handler.
2976     */
2977    /* sput-wide vAA, field@BBBB */
2978    ldr     r0, [rGLUE, #offGlue_methodClassDex]  @ r0<- DvmDex
2979    FETCH(r1, 1)                        @ r1<- field ref BBBB
2980    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
2981    mov     r9, rINST, lsr #8           @ r9<- AA
2982    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
2983    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2984    cmp     r2, #0                      @ is resolved entry null?
2985    beq     .LOP_SPUT_WIDE_resolve         @ yes, do resolve
2986.LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9
2987    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2988    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
2989    GET_INST_OPCODE(r10)                @ extract opcode from rINST
2990    .if 0
2991    add     r2, r2, #offStaticField_value @ r2<- pointer to data
2992    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
2993    .else
2994    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
2995    .endif
2996    GOTO_OPCODE(r10)                    @ jump to next instruction
2997
2998/* ------------------------------ */
2999    .balign 64
3000.L_OP_SPUT_OBJECT: /* 0x69 */
3001/* File: armv5te/OP_SPUT_OBJECT.S */
3002    /*
3003     * 32-bit SPUT handler for objects
3004     *
3005     * for: sput-object, sput-object-volatile
3006     */
3007    /* op vAA, field@BBBB */
3008    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3009    FETCH(r1, 1)                        @ r1<- field ref BBBB
3010    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3011    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3012    cmp     r0, #0                      @ is resolved entry null?
3013    bne     .LOP_SPUT_OBJECT_finish          @ no, continue
3014    ldr     r9, [rGLUE, #offGlue_method]    @ r9<- current method
3015    EXPORT_PC()                         @ resolve() could throw, so export now
3016    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
3017    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
3018    cmp     r0, #0                      @ success?
3019    bne     .LOP_SPUT_OBJECT_finish          @ yes, finish
3020    b       common_exceptionThrown      @ no, handle exception
3021
3022
3023/* ------------------------------ */
3024    .balign 64
3025.L_OP_SPUT_BOOLEAN: /* 0x6a */
3026/* File: armv5te/OP_SPUT_BOOLEAN.S */
3027/* File: armv5te/OP_SPUT.S */
3028    /*
3029     * General 32-bit SPUT handler.
3030     *
3031     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3032     */
3033    /* op vAA, field@BBBB */
3034    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3035    FETCH(r1, 1)                        @ r1<- field ref BBBB
3036    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3037    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3038    cmp     r0, #0                      @ is resolved entry null?
3039    beq     .LOP_SPUT_BOOLEAN_resolve         @ yes, do resolve
3040.LOP_SPUT_BOOLEAN_finish:   @ field ptr in r0
3041    mov     r2, rINST, lsr #8           @ r2<- AA
3042    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3043    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3044    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3045    @ no-op                             @ releasing store
3046    str     r1, [r0, #offStaticField_value] @ field<- vAA
3047    GOTO_OPCODE(ip)                     @ jump to next instruction
3048
3049
3050/* ------------------------------ */
3051    .balign 64
3052.L_OP_SPUT_BYTE: /* 0x6b */
3053/* File: armv5te/OP_SPUT_BYTE.S */
3054/* File: armv5te/OP_SPUT.S */
3055    /*
3056     * General 32-bit SPUT handler.
3057     *
3058     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3059     */
3060    /* op vAA, field@BBBB */
3061    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3062    FETCH(r1, 1)                        @ r1<- field ref BBBB
3063    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3064    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3065    cmp     r0, #0                      @ is resolved entry null?
3066    beq     .LOP_SPUT_BYTE_resolve         @ yes, do resolve
3067.LOP_SPUT_BYTE_finish:   @ field ptr in r0
3068    mov     r2, rINST, lsr #8           @ r2<- AA
3069    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3070    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3071    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3072    @ no-op                             @ releasing store
3073    str     r1, [r0, #offStaticField_value] @ field<- vAA
3074    GOTO_OPCODE(ip)                     @ jump to next instruction
3075
3076
3077/* ------------------------------ */
3078    .balign 64
3079.L_OP_SPUT_CHAR: /* 0x6c */
3080/* File: armv5te/OP_SPUT_CHAR.S */
3081/* File: armv5te/OP_SPUT.S */
3082    /*
3083     * General 32-bit SPUT handler.
3084     *
3085     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3086     */
3087    /* op vAA, field@BBBB */
3088    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3089    FETCH(r1, 1)                        @ r1<- field ref BBBB
3090    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3091    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3092    cmp     r0, #0                      @ is resolved entry null?
3093    beq     .LOP_SPUT_CHAR_resolve         @ yes, do resolve
3094.LOP_SPUT_CHAR_finish:   @ field ptr in r0
3095    mov     r2, rINST, lsr #8           @ r2<- AA
3096    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3097    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3098    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3099    @ no-op                             @ releasing store
3100    str     r1, [r0, #offStaticField_value] @ field<- vAA
3101    GOTO_OPCODE(ip)                     @ jump to next instruction
3102
3103
3104/* ------------------------------ */
3105    .balign 64
3106.L_OP_SPUT_SHORT: /* 0x6d */
3107/* File: armv5te/OP_SPUT_SHORT.S */
3108/* File: armv5te/OP_SPUT.S */
3109    /*
3110     * General 32-bit SPUT handler.
3111     *
3112     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3113     */
3114    /* op vAA, field@BBBB */
3115    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3116    FETCH(r1, 1)                        @ r1<- field ref BBBB
3117    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3118    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3119    cmp     r0, #0                      @ is resolved entry null?
3120    beq     .LOP_SPUT_SHORT_resolve         @ yes, do resolve
3121.LOP_SPUT_SHORT_finish:   @ field ptr in r0
3122    mov     r2, rINST, lsr #8           @ r2<- AA
3123    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3124    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3125    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3126    @ no-op                             @ releasing store
3127    str     r1, [r0, #offStaticField_value] @ field<- vAA
3128    GOTO_OPCODE(ip)                     @ jump to next instruction
3129
3130
3131/* ------------------------------ */
3132    .balign 64
3133.L_OP_INVOKE_VIRTUAL: /* 0x6e */
3134/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3135    /*
3136     * Handle a virtual method call.
3137     *
3138     * for: invoke-virtual, invoke-virtual/range
3139     */
3140    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3141    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3142    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3143    FETCH(r1, 1)                        @ r1<- BBBB
3144    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3145    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3146    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3147    .if     (!0)
3148    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3149    .endif
3150    cmp     r0, #0                      @ already resolved?
3151    EXPORT_PC()                         @ must export for invoke
3152    bne     .LOP_INVOKE_VIRTUAL_continue        @ yes, continue on
3153    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
3154    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3155    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3156    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3157    cmp     r0, #0                      @ got null?
3158    bne     .LOP_INVOKE_VIRTUAL_continue        @ no, continue
3159    b       common_exceptionThrown      @ yes, handle exception
3160
3161/* ------------------------------ */
3162    .balign 64
3163.L_OP_INVOKE_SUPER: /* 0x6f */
3164/* File: armv5te/OP_INVOKE_SUPER.S */
3165    /*
3166     * Handle a "super" method call.
3167     *
3168     * for: invoke-super, invoke-super/range
3169     */
3170    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3171    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3172    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3173    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3174    .if     (!0)
3175    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3176    .endif
3177    FETCH(r1, 1)                        @ r1<- BBBB
3178    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3179    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3180    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3181    cmp     r2, #0                      @ null "this"?
3182    ldr     r9, [rGLUE, #offGlue_method] @ r9<- current method
3183    beq     common_errNullObject        @ null "this", throw exception
3184    cmp     r0, #0                      @ already resolved?
3185    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
3186    EXPORT_PC()                         @ must export for invoke
3187    bne     .LOP_INVOKE_SUPER_continue        @ resolved, continue on
3188    b       .LOP_INVOKE_SUPER_resolve         @ do resolve now
3189
3190/* ------------------------------ */
3191    .balign 64
3192.L_OP_INVOKE_DIRECT: /* 0x70 */
3193/* File: armv5te/OP_INVOKE_DIRECT.S */
3194    /*
3195     * Handle a direct method call.
3196     *
3197     * (We could defer the "is 'this' pointer null" test to the common
3198     * method invocation code, and use a flag to indicate that static
3199     * calls don't count.  If we do this as part of copying the arguments
3200     * out we could avoiding loading the first arg twice.)
3201     *
3202     * for: invoke-direct, invoke-direct/range
3203     */
3204    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3205    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3206    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3207    FETCH(r1, 1)                        @ r1<- BBBB
3208    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3209    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3210    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3211    .if     (!0)
3212    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3213    .endif
3214    cmp     r0, #0                      @ already resolved?
3215    EXPORT_PC()                         @ must export for invoke
3216    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3217    beq     .LOP_INVOKE_DIRECT_resolve         @ not resolved, do it now
3218.LOP_INVOKE_DIRECT_finish:
3219    cmp     r2, #0                      @ null "this" ref?
3220    bne     common_invokeMethodNoRange   @ no, continue on
3221    b       common_errNullObject        @ yes, throw exception
3222
3223/* ------------------------------ */
3224    .balign 64
3225.L_OP_INVOKE_STATIC: /* 0x71 */
3226/* File: armv5te/OP_INVOKE_STATIC.S */
3227    /*
3228     * Handle a static method call.
3229     *
3230     * for: invoke-static, invoke-static/range
3231     */
3232    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3233    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3234    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3235    FETCH(r1, 1)                        @ r1<- BBBB
3236    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3237    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3238    cmp     r0, #0                      @ already resolved?
3239    EXPORT_PC()                         @ must export for invoke
3240    bne     common_invokeMethodNoRange @ yes, continue on
32410:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
3242    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3243    mov     r2, #METHOD_STATIC          @ resolver method type
3244    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3245    cmp     r0, #0                      @ got null?
3246    bne     common_invokeMethodNoRange @ no, continue
3247    b       common_exceptionThrown      @ yes, handle exception
3248
3249/* ------------------------------ */
3250    .balign 64
3251.L_OP_INVOKE_INTERFACE: /* 0x72 */
3252/* File: armv5te/OP_INVOKE_INTERFACE.S */
3253    /*
3254     * Handle an interface method call.
3255     *
3256     * for: invoke-interface, invoke-interface/range
3257     */
3258    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3259    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3260    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3261    FETCH(r1, 1)                        @ r1<- BBBB
3262    .if     (!0)
3263    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3264    .endif
3265    EXPORT_PC()                         @ must export for invoke
3266    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
3267    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- methodClassDex
3268    cmp     r0, #0                      @ null obj?
3269    ldr     r2, [rGLUE, #offGlue_method]  @ r2<- method
3270    beq     common_errNullObject        @ yes, fail
3271    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
3272    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3273    cmp     r0, #0                      @ failed?
3274    beq     common_exceptionThrown      @ yes, handle exception
3275    b       common_invokeMethodNoRange @ jump to common handler
3276
3277/* ------------------------------ */
3278    .balign 64
3279.L_OP_UNUSED_73: /* 0x73 */
3280/* File: armv5te/OP_UNUSED_73.S */
3281/* File: armv5te/unused.S */
3282    bl      common_abort
3283
3284
3285/* ------------------------------ */
3286    .balign 64
3287.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
3288/* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */
3289/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3290    /*
3291     * Handle a virtual method call.
3292     *
3293     * for: invoke-virtual, invoke-virtual/range
3294     */
3295    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3296    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3297    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3298    FETCH(r1, 1)                        @ r1<- BBBB
3299    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3300    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3301    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3302    .if     (!1)
3303    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3304    .endif
3305    cmp     r0, #0                      @ already resolved?
3306    EXPORT_PC()                         @ must export for invoke
3307    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ yes, continue on
3308    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
3309    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3310    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3311    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3312    cmp     r0, #0                      @ got null?
3313    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ no, continue
3314    b       common_exceptionThrown      @ yes, handle exception
3315
3316
3317/* ------------------------------ */
3318    .balign 64
3319.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */
3320/* File: armv5te/OP_INVOKE_SUPER_RANGE.S */
3321/* File: armv5te/OP_INVOKE_SUPER.S */
3322    /*
3323     * Handle a "super" method call.
3324     *
3325     * for: invoke-super, invoke-super/range
3326     */
3327    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3328    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3329    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3330    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3331    .if     (!1)
3332    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3333    .endif
3334    FETCH(r1, 1)                        @ r1<- BBBB
3335    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3336    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3337    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3338    cmp     r2, #0                      @ null "this"?
3339    ldr     r9, [rGLUE, #offGlue_method] @ r9<- current method
3340    beq     common_errNullObject        @ null "this", throw exception
3341    cmp     r0, #0                      @ already resolved?
3342    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
3343    EXPORT_PC()                         @ must export for invoke
3344    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ resolved, continue on
3345    b       .LOP_INVOKE_SUPER_RANGE_resolve         @ do resolve now
3346
3347
3348/* ------------------------------ */
3349    .balign 64
3350.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
3351/* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */
3352/* File: armv5te/OP_INVOKE_DIRECT.S */
3353    /*
3354     * Handle a direct method call.
3355     *
3356     * (We could defer the "is 'this' pointer null" test to the common
3357     * method invocation code, and use a flag to indicate that static
3358     * calls don't count.  If we do this as part of copying the arguments
3359     * out we could avoiding loading the first arg twice.)
3360     *
3361     * for: invoke-direct, invoke-direct/range
3362     */
3363    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3364    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3365    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3366    FETCH(r1, 1)                        @ r1<- BBBB
3367    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3368    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3369    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3370    .if     (!1)
3371    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3372    .endif
3373    cmp     r0, #0                      @ already resolved?
3374    EXPORT_PC()                         @ must export for invoke
3375    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3376    beq     .LOP_INVOKE_DIRECT_RANGE_resolve         @ not resolved, do it now
3377.LOP_INVOKE_DIRECT_RANGE_finish:
3378    cmp     r2, #0                      @ null "this" ref?
3379    bne     common_invokeMethodRange   @ no, continue on
3380    b       common_errNullObject        @ yes, throw exception
3381
3382
3383/* ------------------------------ */
3384    .balign 64
3385.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */
3386/* File: armv5te/OP_INVOKE_STATIC_RANGE.S */
3387/* File: armv5te/OP_INVOKE_STATIC.S */
3388    /*
3389     * Handle a static method call.
3390     *
3391     * for: invoke-static, invoke-static/range
3392     */
3393    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3394    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3395    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3396    FETCH(r1, 1)                        @ r1<- BBBB
3397    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3398    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3399    cmp     r0, #0                      @ already resolved?
3400    EXPORT_PC()                         @ must export for invoke
3401    bne     common_invokeMethodRange @ yes, continue on
34020:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
3403    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3404    mov     r2, #METHOD_STATIC          @ resolver method type
3405    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3406    cmp     r0, #0                      @ got null?
3407    bne     common_invokeMethodRange @ no, continue
3408    b       common_exceptionThrown      @ yes, handle exception
3409
3410
3411/* ------------------------------ */
3412    .balign 64
3413.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
3414/* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */
3415/* File: armv5te/OP_INVOKE_INTERFACE.S */
3416    /*
3417     * Handle an interface method call.
3418     *
3419     * for: invoke-interface, invoke-interface/range
3420     */
3421    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3422    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3423    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3424    FETCH(r1, 1)                        @ r1<- BBBB
3425    .if     (!1)
3426    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3427    .endif
3428    EXPORT_PC()                         @ must export for invoke
3429    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
3430    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- methodClassDex
3431    cmp     r0, #0                      @ null obj?
3432    ldr     r2, [rGLUE, #offGlue_method]  @ r2<- method
3433    beq     common_errNullObject        @ yes, fail
3434    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
3435    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3436    cmp     r0, #0                      @ failed?
3437    beq     common_exceptionThrown      @ yes, handle exception
3438    b       common_invokeMethodRange @ jump to common handler
3439
3440
3441/* ------------------------------ */
3442    .balign 64
3443.L_OP_UNUSED_79: /* 0x79 */
3444/* File: armv5te/OP_UNUSED_79.S */
3445/* File: armv5te/unused.S */
3446    bl      common_abort
3447
3448
3449/* ------------------------------ */
3450    .balign 64
3451.L_OP_UNUSED_7A: /* 0x7a */
3452/* File: armv5te/OP_UNUSED_7A.S */
3453/* File: armv5te/unused.S */
3454    bl      common_abort
3455
3456
3457/* ------------------------------ */
3458    .balign 64
3459.L_OP_NEG_INT: /* 0x7b */
3460/* File: armv5te/OP_NEG_INT.S */
3461/* File: armv5te/unop.S */
3462    /*
3463     * Generic 32-bit unary operation.  Provide an "instr" line that
3464     * specifies an instruction that performs "result = op r0".
3465     * This could be an ARM instruction or a function call.
3466     *
3467     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3468     *      int-to-byte, int-to-char, int-to-short
3469     */
3470    /* unop vA, vB */
3471    mov     r3, rINST, lsr #12          @ r3<- B
3472    mov     r9, rINST, lsr #8           @ r9<- A+
3473    GET_VREG(r0, r3)                    @ r0<- vB
3474    and     r9, r9, #15
3475                               @ optional op; may set condition codes
3476    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3477    rsb     r0, r0, #0                              @ r0<- op, r0-r3 changed
3478    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3479    SET_VREG(r0, r9)                    @ vAA<- r0
3480    GOTO_OPCODE(ip)                     @ jump to next instruction
3481    /* 9-10 instructions */
3482
3483
3484/* ------------------------------ */
3485    .balign 64
3486.L_OP_NOT_INT: /* 0x7c */
3487/* File: armv5te/OP_NOT_INT.S */
3488/* File: armv5te/unop.S */
3489    /*
3490     * Generic 32-bit unary operation.  Provide an "instr" line that
3491     * specifies an instruction that performs "result = op r0".
3492     * This could be an ARM instruction or a function call.
3493     *
3494     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3495     *      int-to-byte, int-to-char, int-to-short
3496     */
3497    /* unop vA, vB */
3498    mov     r3, rINST, lsr #12          @ r3<- B
3499    mov     r9, rINST, lsr #8           @ r9<- A+
3500    GET_VREG(r0, r3)                    @ r0<- vB
3501    and     r9, r9, #15
3502                               @ optional op; may set condition codes
3503    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3504    mvn     r0, r0                              @ r0<- op, r0-r3 changed
3505    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3506    SET_VREG(r0, r9)                    @ vAA<- r0
3507    GOTO_OPCODE(ip)                     @ jump to next instruction
3508    /* 9-10 instructions */
3509
3510
3511/* ------------------------------ */
3512    .balign 64
3513.L_OP_NEG_LONG: /* 0x7d */
3514/* File: armv5te/OP_NEG_LONG.S */
3515/* File: armv5te/unopWide.S */
3516    /*
3517     * Generic 64-bit unary operation.  Provide an "instr" line that
3518     * specifies an instruction that performs "result = op r0/r1".
3519     * This could be an ARM instruction or a function call.
3520     *
3521     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3522     */
3523    /* unop vA, vB */
3524    mov     r9, rINST, lsr #8           @ r9<- A+
3525    mov     r3, rINST, lsr #12          @ r3<- B
3526    and     r9, r9, #15
3527    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3528    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3529    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3530    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3531    rsbs    r0, r0, #0                           @ optional op; may set condition codes
3532    rsc     r1, r1, #0                              @ r0/r1<- op, r2-r3 changed
3533    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3534    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3535    GOTO_OPCODE(ip)                     @ jump to next instruction
3536    /* 12-13 instructions */
3537
3538
3539/* ------------------------------ */
3540    .balign 64
3541.L_OP_NOT_LONG: /* 0x7e */
3542/* File: armv5te/OP_NOT_LONG.S */
3543/* File: armv5te/unopWide.S */
3544    /*
3545     * Generic 64-bit unary operation.  Provide an "instr" line that
3546     * specifies an instruction that performs "result = op r0/r1".
3547     * This could be an ARM instruction or a function call.
3548     *
3549     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3550     */
3551    /* unop vA, vB */
3552    mov     r9, rINST, lsr #8           @ r9<- A+
3553    mov     r3, rINST, lsr #12          @ r3<- B
3554    and     r9, r9, #15
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    /* 12-13 instructions */
3565
3566
3567/* ------------------------------ */
3568    .balign 64
3569.L_OP_NEG_FLOAT: /* 0x7f */
3570/* File: armv5te/OP_NEG_FLOAT.S */
3571/* File: armv5te/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    mov     r9, rINST, lsr #8           @ r9<- A+
3583    GET_VREG(r0, r3)                    @ r0<- vB
3584    and     r9, r9, #15
3585                               @ optional op; may set condition codes
3586    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3587    add     r0, r0, #0x80000000                              @ r0<- op, r0-r3 changed
3588    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3589    SET_VREG(r0, r9)                    @ vAA<- r0
3590    GOTO_OPCODE(ip)                     @ jump to next instruction
3591    /* 9-10 instructions */
3592
3593
3594/* ------------------------------ */
3595    .balign 64
3596.L_OP_NEG_DOUBLE: /* 0x80 */
3597/* File: armv5te/OP_NEG_DOUBLE.S */
3598/* File: armv5te/unopWide.S */
3599    /*
3600     * Generic 64-bit unary operation.  Provide an "instr" line that
3601     * specifies an instruction that performs "result = op r0/r1".
3602     * This could be an ARM instruction or a function call.
3603     *
3604     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3605     */
3606    /* unop vA, vB */
3607    mov     r9, rINST, lsr #8           @ r9<- A+
3608    mov     r3, rINST, lsr #12          @ r3<- B
3609    and     r9, r9, #15
3610    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3611    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3612    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3613    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3614                               @ optional op; may set condition codes
3615    add     r1, r1, #0x80000000                              @ r0/r1<- op, r2-r3 changed
3616    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3617    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3618    GOTO_OPCODE(ip)                     @ jump to next instruction
3619    /* 12-13 instructions */
3620
3621
3622/* ------------------------------ */
3623    .balign 64
3624.L_OP_INT_TO_LONG: /* 0x81 */
3625/* File: armv5te/OP_INT_TO_LONG.S */
3626/* File: armv5te/unopWider.S */
3627    /*
3628     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3629     * that specifies an instruction that performs "result = op r0", where
3630     * "result" is a 64-bit quantity in r0/r1.
3631     *
3632     * For: int-to-long, int-to-double, float-to-long, float-to-double
3633     */
3634    /* unop vA, vB */
3635    mov     r9, rINST, lsr #8           @ r9<- A+
3636    mov     r3, rINST, lsr #12          @ r3<- B
3637    and     r9, r9, #15
3638    GET_VREG(r0, r3)                    @ r0<- vB
3639    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3640                               @ optional op; may set condition codes
3641    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3642    mov     r1, r0, asr #31                              @ r0<- op, r0-r3 changed
3643    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3644    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3645    GOTO_OPCODE(ip)                     @ jump to next instruction
3646    /* 10-11 instructions */
3647
3648
3649/* ------------------------------ */
3650    .balign 64
3651.L_OP_INT_TO_FLOAT: /* 0x82 */
3652/* File: arm-vfp/OP_INT_TO_FLOAT.S */
3653/* File: arm-vfp/funop.S */
3654    /*
3655     * Generic 32-bit unary floating-point operation.  Provide an "instr"
3656     * line that specifies an instruction that performs "s1 = op s0".
3657     *
3658     * for: int-to-float, float-to-int
3659     */
3660    /* unop vA, vB */
3661    mov     r3, rINST, lsr #12          @ r3<- B
3662    mov     r9, rINST, lsr #8           @ r9<- A+
3663    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3664    flds    s0, [r3]                    @ s0<- vB
3665    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3666    and     r9, r9, #15                 @ r9<- A
3667    fsitos  s1, s0                              @ s1<- op
3668    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3669    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3670    fsts    s1, [r9]                    @ vA<- s1
3671    GOTO_OPCODE(ip)                     @ jump to next instruction
3672
3673
3674/* ------------------------------ */
3675    .balign 64
3676.L_OP_INT_TO_DOUBLE: /* 0x83 */
3677/* File: arm-vfp/OP_INT_TO_DOUBLE.S */
3678/* File: arm-vfp/funopWider.S */
3679    /*
3680     * Generic 32bit-to-64bit floating point unary operation.  Provide an
3681     * "instr" line that specifies an instruction that performs "d0 = op s0".
3682     *
3683     * For: int-to-double, float-to-double
3684     */
3685    /* unop vA, vB */
3686    mov     r3, rINST, lsr #12          @ r3<- B
3687    mov     r9, rINST, lsr #8           @ r9<- A+
3688    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3689    flds    s0, [r3]                    @ s0<- vB
3690    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3691    and     r9, r9, #15                 @ r9<- A
3692    fsitod  d0, s0                              @ d0<- op
3693    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3694    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3695    fstd    d0, [r9]                    @ vA<- d0
3696    GOTO_OPCODE(ip)                     @ jump to next instruction
3697
3698
3699/* ------------------------------ */
3700    .balign 64
3701.L_OP_LONG_TO_INT: /* 0x84 */
3702/* File: armv5te/OP_LONG_TO_INT.S */
3703/* we ignore the high word, making this equivalent to a 32-bit reg move */
3704/* File: armv5te/OP_MOVE.S */
3705    /* for move, move-object, long-to-int */
3706    /* op vA, vB */
3707    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
3708    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
3709    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3710    GET_VREG(r2, r1)                    @ r2<- fp[B]
3711    and     r0, r0, #15
3712    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
3713    SET_VREG(r2, r0)                    @ fp[A]<- r2
3714    GOTO_OPCODE(ip)                     @ execute next instruction
3715
3716
3717/* ------------------------------ */
3718    .balign 64
3719.L_OP_LONG_TO_FLOAT: /* 0x85 */
3720/* File: armv5te/OP_LONG_TO_FLOAT.S */
3721/* File: armv5te/unopNarrower.S */
3722    /*
3723     * Generic 64bit-to-32bit unary operation.  Provide an "instr" line
3724     * that specifies an instruction that performs "result = op r0/r1", where
3725     * "result" is a 32-bit quantity in r0.
3726     *
3727     * For: long-to-float, double-to-int, double-to-float
3728     *
3729     * (This would work for long-to-int, but that instruction is actually
3730     * an exact match for OP_MOVE.)
3731     */
3732    /* unop vA, vB */
3733    mov     r3, rINST, lsr #12          @ r3<- B
3734    mov     r9, rINST, lsr #8           @ r9<- A+
3735    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3736    and     r9, r9, #15
3737    ldmia   r3, {r0-r1}                 @ r0/r1<- vB/vB+1
3738    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3739                               @ optional op; may set condition codes
3740    bl      __aeabi_l2f                              @ r0<- op, r0-r3 changed
3741    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3742    SET_VREG(r0, r9)                    @ vA<- r0
3743    GOTO_OPCODE(ip)                     @ jump to next instruction
3744    /* 10-11 instructions */
3745
3746
3747/* ------------------------------ */
3748    .balign 64
3749.L_OP_LONG_TO_DOUBLE: /* 0x86 */
3750/* File: armv5te/OP_LONG_TO_DOUBLE.S */
3751/* File: armv5te/unopWide.S */
3752    /*
3753     * Generic 64-bit unary operation.  Provide an "instr" line that
3754     * specifies an instruction that performs "result = op r0/r1".
3755     * This could be an ARM instruction or a function call.
3756     *
3757     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3758     */
3759    /* unop vA, vB */
3760    mov     r9, rINST, lsr #8           @ r9<- A+
3761    mov     r3, rINST, lsr #12          @ r3<- B
3762    and     r9, r9, #15
3763    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3764    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3765    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3766    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3767                               @ optional op; may set condition codes
3768    bl      __aeabi_l2d                              @ r0/r1<- op, r2-r3 changed
3769    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3770    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3771    GOTO_OPCODE(ip)                     @ jump to next instruction
3772    /* 12-13 instructions */
3773
3774
3775/* ------------------------------ */
3776    .balign 64
3777.L_OP_FLOAT_TO_INT: /* 0x87 */
3778/* File: arm-vfp/OP_FLOAT_TO_INT.S */
3779/* File: arm-vfp/funop.S */
3780    /*
3781     * Generic 32-bit unary floating-point operation.  Provide an "instr"
3782     * line that specifies an instruction that performs "s1 = op s0".
3783     *
3784     * for: int-to-float, float-to-int
3785     */
3786    /* unop vA, vB */
3787    mov     r3, rINST, lsr #12          @ r3<- B
3788    mov     r9, rINST, lsr #8           @ r9<- A+
3789    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3790    flds    s0, [r3]                    @ s0<- vB
3791    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3792    and     r9, r9, #15                 @ r9<- A
3793    ftosizs s1, s0                              @ s1<- op
3794    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3795    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3796    fsts    s1, [r9]                    @ vA<- s1
3797    GOTO_OPCODE(ip)                     @ jump to next instruction
3798
3799
3800/* ------------------------------ */
3801    .balign 64
3802.L_OP_FLOAT_TO_LONG: /* 0x88 */
3803/* File: armv5te/OP_FLOAT_TO_LONG.S */
3804@include "armv5te/unopWider.S" {"instr":"bl      __aeabi_f2lz"}
3805/* File: armv5te/unopWider.S */
3806    /*
3807     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3808     * that specifies an instruction that performs "result = op r0", where
3809     * "result" is a 64-bit quantity in r0/r1.
3810     *
3811     * For: int-to-long, int-to-double, float-to-long, float-to-double
3812     */
3813    /* unop vA, vB */
3814    mov     r9, rINST, lsr #8           @ r9<- A+
3815    mov     r3, rINST, lsr #12          @ r3<- B
3816    and     r9, r9, #15
3817    GET_VREG(r0, r3)                    @ r0<- vB
3818    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3819                               @ optional op; may set condition codes
3820    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3821    bl      f2l_doconv                              @ r0<- op, r0-r3 changed
3822    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3823    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3824    GOTO_OPCODE(ip)                     @ jump to next instruction
3825    /* 10-11 instructions */
3826
3827
3828
3829/* ------------------------------ */
3830    .balign 64
3831.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */
3832/* File: arm-vfp/OP_FLOAT_TO_DOUBLE.S */
3833/* File: arm-vfp/funopWider.S */
3834    /*
3835     * Generic 32bit-to-64bit floating point unary operation.  Provide an
3836     * "instr" line that specifies an instruction that performs "d0 = op s0".
3837     *
3838     * For: int-to-double, float-to-double
3839     */
3840    /* unop vA, vB */
3841    mov     r3, rINST, lsr #12          @ r3<- B
3842    mov     r9, rINST, lsr #8           @ r9<- A+
3843    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3844    flds    s0, [r3]                    @ s0<- vB
3845    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3846    and     r9, r9, #15                 @ r9<- A
3847    fcvtds  d0, s0                              @ d0<- op
3848    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3849    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3850    fstd    d0, [r9]                    @ vA<- d0
3851    GOTO_OPCODE(ip)                     @ jump to next instruction
3852
3853
3854/* ------------------------------ */
3855    .balign 64
3856.L_OP_DOUBLE_TO_INT: /* 0x8a */
3857/* File: arm-vfp/OP_DOUBLE_TO_INT.S */
3858/* File: arm-vfp/funopNarrower.S */
3859    /*
3860     * Generic 64bit-to-32bit unary floating point operation.  Provide an
3861     * "instr" line that specifies an instruction that performs "s0 = op d0".
3862     *
3863     * For: double-to-int, double-to-float
3864     */
3865    /* unop vA, vB */
3866    mov     r3, rINST, lsr #12          @ r3<- B
3867    mov     r9, rINST, lsr #8           @ r9<- A+
3868    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3869    fldd    d0, [r3]                    @ d0<- vB
3870    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3871    and     r9, r9, #15                 @ r9<- A
3872    ftosizd  s0, d0                              @ s0<- op
3873    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3874    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3875    fsts    s0, [r9]                    @ vA<- s0
3876    GOTO_OPCODE(ip)                     @ jump to next instruction
3877
3878
3879/* ------------------------------ */
3880    .balign 64
3881.L_OP_DOUBLE_TO_LONG: /* 0x8b */
3882/* File: armv5te/OP_DOUBLE_TO_LONG.S */
3883@include "armv5te/unopWide.S" {"instr":"bl      __aeabi_d2lz"}
3884/* File: armv5te/unopWide.S */
3885    /*
3886     * Generic 64-bit unary operation.  Provide an "instr" line that
3887     * specifies an instruction that performs "result = op r0/r1".
3888     * This could be an ARM instruction or a function call.
3889     *
3890     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3891     */
3892    /* unop vA, vB */
3893    mov     r9, rINST, lsr #8           @ r9<- A+
3894    mov     r3, rINST, lsr #12          @ r3<- B
3895    and     r9, r9, #15
3896    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3897    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3898    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3899    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3900                               @ optional op; may set condition codes
3901    bl      d2l_doconv                              @ r0/r1<- op, r2-r3 changed
3902    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3903    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3904    GOTO_OPCODE(ip)                     @ jump to next instruction
3905    /* 12-13 instructions */
3906
3907
3908
3909/* ------------------------------ */
3910    .balign 64
3911.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */
3912/* File: arm-vfp/OP_DOUBLE_TO_FLOAT.S */
3913/* File: arm-vfp/funopNarrower.S */
3914    /*
3915     * Generic 64bit-to-32bit unary floating point operation.  Provide an
3916     * "instr" line that specifies an instruction that performs "s0 = op d0".
3917     *
3918     * For: double-to-int, double-to-float
3919     */
3920    /* unop vA, vB */
3921    mov     r3, rINST, lsr #12          @ r3<- B
3922    mov     r9, rINST, lsr #8           @ r9<- A+
3923    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3924    fldd    d0, [r3]                    @ d0<- vB
3925    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3926    and     r9, r9, #15                 @ r9<- A
3927    fcvtsd  s0, d0                              @ s0<- op
3928    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3929    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3930    fsts    s0, [r9]                    @ vA<- s0
3931    GOTO_OPCODE(ip)                     @ jump to next instruction
3932
3933
3934/* ------------------------------ */
3935    .balign 64
3936.L_OP_INT_TO_BYTE: /* 0x8d */
3937/* File: armv5te/OP_INT_TO_BYTE.S */
3938/* File: armv5te/unop.S */
3939    /*
3940     * Generic 32-bit unary operation.  Provide an "instr" line that
3941     * specifies an instruction that performs "result = op r0".
3942     * This could be an ARM instruction or a function call.
3943     *
3944     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3945     *      int-to-byte, int-to-char, int-to-short
3946     */
3947    /* unop vA, vB */
3948    mov     r3, rINST, lsr #12          @ r3<- B
3949    mov     r9, rINST, lsr #8           @ r9<- A+
3950    GET_VREG(r0, r3)                    @ r0<- vB
3951    and     r9, r9, #15
3952    mov     r0, r0, asl #24                           @ optional op; may set condition codes
3953    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3954    mov     r0, r0, asr #24                              @ r0<- op, r0-r3 changed
3955    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3956    SET_VREG(r0, r9)                    @ vAA<- r0
3957    GOTO_OPCODE(ip)                     @ jump to next instruction
3958    /* 9-10 instructions */
3959
3960
3961/* ------------------------------ */
3962    .balign 64
3963.L_OP_INT_TO_CHAR: /* 0x8e */
3964/* File: armv5te/OP_INT_TO_CHAR.S */
3965/* File: armv5te/unop.S */
3966    /*
3967     * Generic 32-bit unary operation.  Provide an "instr" line that
3968     * specifies an instruction that performs "result = op r0".
3969     * This could be an ARM instruction or a function call.
3970     *
3971     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3972     *      int-to-byte, int-to-char, int-to-short
3973     */
3974    /* unop vA, vB */
3975    mov     r3, rINST, lsr #12          @ r3<- B
3976    mov     r9, rINST, lsr #8           @ r9<- A+
3977    GET_VREG(r0, r3)                    @ r0<- vB
3978    and     r9, r9, #15
3979    mov     r0, r0, asl #16                           @ optional op; may set condition codes
3980    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3981    mov     r0, r0, lsr #16                              @ r0<- op, r0-r3 changed
3982    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3983    SET_VREG(r0, r9)                    @ vAA<- r0
3984    GOTO_OPCODE(ip)                     @ jump to next instruction
3985    /* 9-10 instructions */
3986
3987
3988/* ------------------------------ */
3989    .balign 64
3990.L_OP_INT_TO_SHORT: /* 0x8f */
3991/* File: armv5te/OP_INT_TO_SHORT.S */
3992/* File: armv5te/unop.S */
3993    /*
3994     * Generic 32-bit unary operation.  Provide an "instr" line that
3995     * specifies an instruction that performs "result = op r0".
3996     * This could be an ARM instruction or a function call.
3997     *
3998     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3999     *      int-to-byte, int-to-char, int-to-short
4000     */
4001    /* unop vA, vB */
4002    mov     r3, rINST, lsr #12          @ r3<- B
4003    mov     r9, rINST, lsr #8           @ r9<- A+
4004    GET_VREG(r0, r3)                    @ r0<- vB
4005    and     r9, r9, #15
4006    mov     r0, r0, asl #16                           @ optional op; may set condition codes
4007    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
4008    mov     r0, r0, asr #16                              @ r0<- op, r0-r3 changed
4009    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4010    SET_VREG(r0, r9)                    @ vAA<- r0
4011    GOTO_OPCODE(ip)                     @ jump to next instruction
4012    /* 9-10 instructions */
4013
4014
4015/* ------------------------------ */
4016    .balign 64
4017.L_OP_ADD_INT: /* 0x90 */
4018/* File: armv5te/OP_ADD_INT.S */
4019/* File: armv5te/binop.S */
4020    /*
4021     * Generic 32-bit binary operation.  Provide an "instr" line that
4022     * specifies an instruction that performs "result = r0 op r1".
4023     * This could be an ARM instruction or a function call.  (If the result
4024     * comes back in a register other than r0, you can override "result".)
4025     *
4026     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4027     * vCC (r1).  Useful for integer division and modulus.  Note that we
4028     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4029     * handles it correctly.
4030     *
4031     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4032     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4033     *      mul-float, div-float, rem-float
4034     */
4035    /* binop vAA, vBB, vCC */
4036    FETCH(r0, 1)                        @ r0<- CCBB
4037    mov     r9, rINST, lsr #8           @ r9<- AA
4038    mov     r3, r0, lsr #8              @ r3<- CC
4039    and     r2, r0, #255                @ r2<- BB
4040    GET_VREG(r1, r3)                    @ r1<- vCC
4041    GET_VREG(r0, r2)                    @ r0<- vBB
4042    .if 0
4043    cmp     r1, #0                      @ is second operand zero?
4044    beq     common_errDivideByZero
4045    .endif
4046
4047    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4048                               @ optional op; may set condition codes
4049    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
4050    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4051    SET_VREG(r0, r9)               @ vAA<- r0
4052    GOTO_OPCODE(ip)                     @ jump to next instruction
4053    /* 11-14 instructions */
4054
4055
4056/* ------------------------------ */
4057    .balign 64
4058.L_OP_SUB_INT: /* 0x91 */
4059/* File: armv5te/OP_SUB_INT.S */
4060/* File: armv5te/binop.S */
4061    /*
4062     * Generic 32-bit binary operation.  Provide an "instr" line that
4063     * specifies an instruction that performs "result = r0 op r1".
4064     * This could be an ARM instruction or a function call.  (If the result
4065     * comes back in a register other than r0, you can override "result".)
4066     *
4067     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4068     * vCC (r1).  Useful for integer division and modulus.  Note that we
4069     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4070     * handles it correctly.
4071     *
4072     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4073     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4074     *      mul-float, div-float, rem-float
4075     */
4076    /* binop vAA, vBB, vCC */
4077    FETCH(r0, 1)                        @ r0<- CCBB
4078    mov     r9, rINST, lsr #8           @ r9<- AA
4079    mov     r3, r0, lsr #8              @ r3<- CC
4080    and     r2, r0, #255                @ r2<- BB
4081    GET_VREG(r1, r3)                    @ r1<- vCC
4082    GET_VREG(r0, r2)                    @ r0<- vBB
4083    .if 0
4084    cmp     r1, #0                      @ is second operand zero?
4085    beq     common_errDivideByZero
4086    .endif
4087
4088    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4089                               @ optional op; may set condition codes
4090    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
4091    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4092    SET_VREG(r0, r9)               @ vAA<- r0
4093    GOTO_OPCODE(ip)                     @ jump to next instruction
4094    /* 11-14 instructions */
4095
4096
4097/* ------------------------------ */
4098    .balign 64
4099.L_OP_MUL_INT: /* 0x92 */
4100/* File: armv5te/OP_MUL_INT.S */
4101/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
4102/* File: armv5te/binop.S */
4103    /*
4104     * Generic 32-bit binary operation.  Provide an "instr" line that
4105     * specifies an instruction that performs "result = r0 op r1".
4106     * This could be an ARM instruction or a function call.  (If the result
4107     * comes back in a register other than r0, you can override "result".)
4108     *
4109     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4110     * vCC (r1).  Useful for integer division and modulus.  Note that we
4111     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4112     * handles it correctly.
4113     *
4114     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4115     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4116     *      mul-float, div-float, rem-float
4117     */
4118    /* binop vAA, vBB, vCC */
4119    FETCH(r0, 1)                        @ r0<- CCBB
4120    mov     r9, rINST, lsr #8           @ r9<- AA
4121    mov     r3, r0, lsr #8              @ r3<- CC
4122    and     r2, r0, #255                @ r2<- BB
4123    GET_VREG(r1, r3)                    @ r1<- vCC
4124    GET_VREG(r0, r2)                    @ r0<- vBB
4125    .if 0
4126    cmp     r1, #0                      @ is second operand zero?
4127    beq     common_errDivideByZero
4128    .endif
4129
4130    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4131                               @ optional op; may set condition codes
4132    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
4133    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4134    SET_VREG(r0, r9)               @ vAA<- r0
4135    GOTO_OPCODE(ip)                     @ jump to next instruction
4136    /* 11-14 instructions */
4137
4138
4139/* ------------------------------ */
4140    .balign 64
4141.L_OP_DIV_INT: /* 0x93 */
4142/* File: armv5te/OP_DIV_INT.S */
4143/* File: armv5te/binop.S */
4144    /*
4145     * Generic 32-bit binary operation.  Provide an "instr" line that
4146     * specifies an instruction that performs "result = r0 op r1".
4147     * This could be an ARM instruction or a function call.  (If the result
4148     * comes back in a register other than r0, you can override "result".)
4149     *
4150     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4151     * vCC (r1).  Useful for integer division and modulus.  Note that we
4152     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4153     * handles it correctly.
4154     *
4155     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4156     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4157     *      mul-float, div-float, rem-float
4158     */
4159    /* binop vAA, vBB, vCC */
4160    FETCH(r0, 1)                        @ r0<- CCBB
4161    mov     r9, rINST, lsr #8           @ r9<- AA
4162    mov     r3, r0, lsr #8              @ r3<- CC
4163    and     r2, r0, #255                @ r2<- BB
4164    GET_VREG(r1, r3)                    @ r1<- vCC
4165    GET_VREG(r0, r2)                    @ r0<- vBB
4166    .if 1
4167    cmp     r1, #0                      @ is second operand zero?
4168    beq     common_errDivideByZero
4169    .endif
4170
4171    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4172                               @ optional op; may set condition codes
4173    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
4174    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4175    SET_VREG(r0, r9)               @ vAA<- r0
4176    GOTO_OPCODE(ip)                     @ jump to next instruction
4177    /* 11-14 instructions */
4178
4179
4180/* ------------------------------ */
4181    .balign 64
4182.L_OP_REM_INT: /* 0x94 */
4183/* File: armv5te/OP_REM_INT.S */
4184/* idivmod returns quotient in r0 and remainder in r1 */
4185/* File: armv5te/binop.S */
4186    /*
4187     * Generic 32-bit binary operation.  Provide an "instr" line that
4188     * specifies an instruction that performs "result = r0 op r1".
4189     * This could be an ARM instruction or a function call.  (If the result
4190     * comes back in a register other than r0, you can override "result".)
4191     *
4192     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4193     * vCC (r1).  Useful for integer division and modulus.  Note that we
4194     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4195     * handles it correctly.
4196     *
4197     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4198     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4199     *      mul-float, div-float, rem-float
4200     */
4201    /* binop vAA, vBB, vCC */
4202    FETCH(r0, 1)                        @ r0<- CCBB
4203    mov     r9, rINST, lsr #8           @ r9<- AA
4204    mov     r3, r0, lsr #8              @ r3<- CC
4205    and     r2, r0, #255                @ r2<- BB
4206    GET_VREG(r1, r3)                    @ r1<- vCC
4207    GET_VREG(r0, r2)                    @ r0<- vBB
4208    .if 1
4209    cmp     r1, #0                      @ is second operand zero?
4210    beq     common_errDivideByZero
4211    .endif
4212
4213    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4214                               @ optional op; may set condition codes
4215    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
4216    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4217    SET_VREG(r1, r9)               @ vAA<- r1
4218    GOTO_OPCODE(ip)                     @ jump to next instruction
4219    /* 11-14 instructions */
4220
4221
4222/* ------------------------------ */
4223    .balign 64
4224.L_OP_AND_INT: /* 0x95 */
4225/* File: armv5te/OP_AND_INT.S */
4226/* File: armv5te/binop.S */
4227    /*
4228     * Generic 32-bit binary operation.  Provide an "instr" line that
4229     * specifies an instruction that performs "result = r0 op r1".
4230     * This could be an ARM instruction or a function call.  (If the result
4231     * comes back in a register other than r0, you can override "result".)
4232     *
4233     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4234     * vCC (r1).  Useful for integer division and modulus.  Note that we
4235     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4236     * handles it correctly.
4237     *
4238     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4239     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4240     *      mul-float, div-float, rem-float
4241     */
4242    /* binop vAA, vBB, vCC */
4243    FETCH(r0, 1)                        @ r0<- CCBB
4244    mov     r9, rINST, lsr #8           @ r9<- AA
4245    mov     r3, r0, lsr #8              @ r3<- CC
4246    and     r2, r0, #255                @ r2<- BB
4247    GET_VREG(r1, r3)                    @ r1<- vCC
4248    GET_VREG(r0, r2)                    @ r0<- vBB
4249    .if 0
4250    cmp     r1, #0                      @ is second operand zero?
4251    beq     common_errDivideByZero
4252    .endif
4253
4254    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4255                               @ optional op; may set condition codes
4256    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
4257    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4258    SET_VREG(r0, r9)               @ vAA<- r0
4259    GOTO_OPCODE(ip)                     @ jump to next instruction
4260    /* 11-14 instructions */
4261
4262
4263/* ------------------------------ */
4264    .balign 64
4265.L_OP_OR_INT: /* 0x96 */
4266/* File: armv5te/OP_OR_INT.S */
4267/* File: armv5te/binop.S */
4268    /*
4269     * Generic 32-bit binary operation.  Provide an "instr" line that
4270     * specifies an instruction that performs "result = r0 op r1".
4271     * This could be an ARM instruction or a function call.  (If the result
4272     * comes back in a register other than r0, you can override "result".)
4273     *
4274     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4275     * vCC (r1).  Useful for integer division and modulus.  Note that we
4276     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4277     * handles it correctly.
4278     *
4279     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4280     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4281     *      mul-float, div-float, rem-float
4282     */
4283    /* binop vAA, vBB, vCC */
4284    FETCH(r0, 1)                        @ r0<- CCBB
4285    mov     r9, rINST, lsr #8           @ r9<- AA
4286    mov     r3, r0, lsr #8              @ r3<- CC
4287    and     r2, r0, #255                @ r2<- BB
4288    GET_VREG(r1, r3)                    @ r1<- vCC
4289    GET_VREG(r0, r2)                    @ r0<- vBB
4290    .if 0
4291    cmp     r1, #0                      @ is second operand zero?
4292    beq     common_errDivideByZero
4293    .endif
4294
4295    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4296                               @ optional op; may set condition codes
4297    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
4298    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4299    SET_VREG(r0, r9)               @ vAA<- r0
4300    GOTO_OPCODE(ip)                     @ jump to next instruction
4301    /* 11-14 instructions */
4302
4303
4304/* ------------------------------ */
4305    .balign 64
4306.L_OP_XOR_INT: /* 0x97 */
4307/* File: armv5te/OP_XOR_INT.S */
4308/* File: armv5te/binop.S */
4309    /*
4310     * Generic 32-bit binary operation.  Provide an "instr" line that
4311     * specifies an instruction that performs "result = r0 op r1".
4312     * This could be an ARM instruction or a function call.  (If the result
4313     * comes back in a register other than r0, you can override "result".)
4314     *
4315     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4316     * vCC (r1).  Useful for integer division and modulus.  Note that we
4317     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4318     * handles it correctly.
4319     *
4320     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4321     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4322     *      mul-float, div-float, rem-float
4323     */
4324    /* binop vAA, vBB, vCC */
4325    FETCH(r0, 1)                        @ r0<- CCBB
4326    mov     r9, rINST, lsr #8           @ r9<- AA
4327    mov     r3, r0, lsr #8              @ r3<- CC
4328    and     r2, r0, #255                @ r2<- BB
4329    GET_VREG(r1, r3)                    @ r1<- vCC
4330    GET_VREG(r0, r2)                    @ r0<- vBB
4331    .if 0
4332    cmp     r1, #0                      @ is second operand zero?
4333    beq     common_errDivideByZero
4334    .endif
4335
4336    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4337                               @ optional op; may set condition codes
4338    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
4339    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4340    SET_VREG(r0, r9)               @ vAA<- r0
4341    GOTO_OPCODE(ip)                     @ jump to next instruction
4342    /* 11-14 instructions */
4343
4344
4345/* ------------------------------ */
4346    .balign 64
4347.L_OP_SHL_INT: /* 0x98 */
4348/* File: armv5te/OP_SHL_INT.S */
4349/* File: armv5te/binop.S */
4350    /*
4351     * Generic 32-bit binary operation.  Provide an "instr" line that
4352     * specifies an instruction that performs "result = r0 op r1".
4353     * This could be an ARM instruction or a function call.  (If the result
4354     * comes back in a register other than r0, you can override "result".)
4355     *
4356     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4357     * vCC (r1).  Useful for integer division and modulus.  Note that we
4358     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4359     * handles it correctly.
4360     *
4361     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4362     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4363     *      mul-float, div-float, rem-float
4364     */
4365    /* binop vAA, vBB, vCC */
4366    FETCH(r0, 1)                        @ r0<- CCBB
4367    mov     r9, rINST, lsr #8           @ r9<- AA
4368    mov     r3, r0, lsr #8              @ r3<- CC
4369    and     r2, r0, #255                @ r2<- BB
4370    GET_VREG(r1, r3)                    @ r1<- vCC
4371    GET_VREG(r0, r2)                    @ r0<- vBB
4372    .if 0
4373    cmp     r1, #0                      @ is second operand zero?
4374    beq     common_errDivideByZero
4375    .endif
4376
4377    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4378    and     r1, r1, #31                           @ optional op; may set condition codes
4379    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
4380    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4381    SET_VREG(r0, r9)               @ vAA<- r0
4382    GOTO_OPCODE(ip)                     @ jump to next instruction
4383    /* 11-14 instructions */
4384
4385
4386/* ------------------------------ */
4387    .balign 64
4388.L_OP_SHR_INT: /* 0x99 */
4389/* File: armv5te/OP_SHR_INT.S */
4390/* File: armv5te/binop.S */
4391    /*
4392     * Generic 32-bit binary operation.  Provide an "instr" line that
4393     * specifies an instruction that performs "result = r0 op r1".
4394     * This could be an ARM instruction or a function call.  (If the result
4395     * comes back in a register other than r0, you can override "result".)
4396     *
4397     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4398     * vCC (r1).  Useful for integer division and modulus.  Note that we
4399     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4400     * handles it correctly.
4401     *
4402     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4403     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4404     *      mul-float, div-float, rem-float
4405     */
4406    /* binop vAA, vBB, vCC */
4407    FETCH(r0, 1)                        @ r0<- CCBB
4408    mov     r9, rINST, lsr #8           @ r9<- AA
4409    mov     r3, r0, lsr #8              @ r3<- CC
4410    and     r2, r0, #255                @ r2<- BB
4411    GET_VREG(r1, r3)                    @ r1<- vCC
4412    GET_VREG(r0, r2)                    @ r0<- vBB
4413    .if 0
4414    cmp     r1, #0                      @ is second operand zero?
4415    beq     common_errDivideByZero
4416    .endif
4417
4418    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4419    and     r1, r1, #31                           @ optional op; may set condition codes
4420    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
4421    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4422    SET_VREG(r0, r9)               @ vAA<- r0
4423    GOTO_OPCODE(ip)                     @ jump to next instruction
4424    /* 11-14 instructions */
4425
4426
4427/* ------------------------------ */
4428    .balign 64
4429.L_OP_USHR_INT: /* 0x9a */
4430/* File: armv5te/OP_USHR_INT.S */
4431/* File: armv5te/binop.S */
4432    /*
4433     * Generic 32-bit binary operation.  Provide an "instr" line that
4434     * specifies an instruction that performs "result = r0 op r1".
4435     * This could be an ARM instruction or a function call.  (If the result
4436     * comes back in a register other than r0, you can override "result".)
4437     *
4438     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4439     * vCC (r1).  Useful for integer division and modulus.  Note that we
4440     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4441     * handles it correctly.
4442     *
4443     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4444     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4445     *      mul-float, div-float, rem-float
4446     */
4447    /* binop vAA, vBB, vCC */
4448    FETCH(r0, 1)                        @ r0<- CCBB
4449    mov     r9, rINST, lsr #8           @ r9<- AA
4450    mov     r3, r0, lsr #8              @ r3<- CC
4451    and     r2, r0, #255                @ r2<- BB
4452    GET_VREG(r1, r3)                    @ r1<- vCC
4453    GET_VREG(r0, r2)                    @ r0<- vBB
4454    .if 0
4455    cmp     r1, #0                      @ is second operand zero?
4456    beq     common_errDivideByZero
4457    .endif
4458
4459    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4460    and     r1, r1, #31                           @ optional op; may set condition codes
4461    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
4462    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4463    SET_VREG(r0, r9)               @ vAA<- r0
4464    GOTO_OPCODE(ip)                     @ jump to next instruction
4465    /* 11-14 instructions */
4466
4467
4468/* ------------------------------ */
4469    .balign 64
4470.L_OP_ADD_LONG: /* 0x9b */
4471/* File: armv5te/OP_ADD_LONG.S */
4472/* File: armv5te/binopWide.S */
4473    /*
4474     * Generic 64-bit binary operation.  Provide an "instr" line that
4475     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4476     * This could be an ARM instruction or a function call.  (If the result
4477     * comes back in a register other than r0, you can override "result".)
4478     *
4479     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4480     * vCC (r1).  Useful for integer division and modulus.
4481     *
4482     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4483     *      xor-long, add-double, sub-double, mul-double, div-double,
4484     *      rem-double
4485     *
4486     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4487     */
4488    /* binop vAA, vBB, vCC */
4489    FETCH(r0, 1)                        @ r0<- CCBB
4490    mov     r9, rINST, lsr #8           @ r9<- AA
4491    and     r2, r0, #255                @ r2<- BB
4492    mov     r3, r0, lsr #8              @ r3<- CC
4493    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4494    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4495    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4496    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4497    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4498    .if 0
4499    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4500    beq     common_errDivideByZero
4501    .endif
4502    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4503
4504    adds    r0, r0, r2                           @ optional op; may set condition codes
4505    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
4506    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4507    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4508    GOTO_OPCODE(ip)                     @ jump to next instruction
4509    /* 14-17 instructions */
4510
4511
4512/* ------------------------------ */
4513    .balign 64
4514.L_OP_SUB_LONG: /* 0x9c */
4515/* File: armv5te/OP_SUB_LONG.S */
4516/* File: armv5te/binopWide.S */
4517    /*
4518     * Generic 64-bit binary operation.  Provide an "instr" line that
4519     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4520     * This could be an ARM instruction or a function call.  (If the result
4521     * comes back in a register other than r0, you can override "result".)
4522     *
4523     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4524     * vCC (r1).  Useful for integer division and modulus.
4525     *
4526     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4527     *      xor-long, add-double, sub-double, mul-double, div-double,
4528     *      rem-double
4529     *
4530     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4531     */
4532    /* binop vAA, vBB, vCC */
4533    FETCH(r0, 1)                        @ r0<- CCBB
4534    mov     r9, rINST, lsr #8           @ r9<- AA
4535    and     r2, r0, #255                @ r2<- BB
4536    mov     r3, r0, lsr #8              @ r3<- CC
4537    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4538    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4539    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4540    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4541    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4542    .if 0
4543    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4544    beq     common_errDivideByZero
4545    .endif
4546    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4547
4548    subs    r0, r0, r2                           @ optional op; may set condition codes
4549    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
4550    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4551    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4552    GOTO_OPCODE(ip)                     @ jump to next instruction
4553    /* 14-17 instructions */
4554
4555
4556/* ------------------------------ */
4557    .balign 64
4558.L_OP_MUL_LONG: /* 0x9d */
4559/* File: armv5te/OP_MUL_LONG.S */
4560    /*
4561     * Signed 64-bit integer multiply.
4562     *
4563     * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
4564     *        WX
4565     *      x YZ
4566     *  --------
4567     *     ZW ZX
4568     *  YW YX
4569     *
4570     * The low word of the result holds ZX, the high word holds
4571     * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
4572     * it doesn't fit in the low 64 bits.
4573     *
4574     * Unlike most ARM math operations, multiply instructions have
4575     * restrictions on using the same register more than once (Rd and Rm
4576     * cannot be the same).
4577     */
4578    /* mul-long vAA, vBB, vCC */
4579    FETCH(r0, 1)                        @ r0<- CCBB
4580    and     r2, r0, #255                @ r2<- BB
4581    mov     r3, r0, lsr #8              @ r3<- CC
4582    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4583    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4584    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4585    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4586    mul     ip, r2, r1                  @  ip<- ZxW
4587    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
4588    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
4589    mov     r0, rINST, lsr #8           @ r0<- AA
4590    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
4591    add     r0, rFP, r0, lsl #2         @ r0<- &fp[AA]
4592    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4593    b       .LOP_MUL_LONG_finish
4594
4595/* ------------------------------ */
4596    .balign 64
4597.L_OP_DIV_LONG: /* 0x9e */
4598/* File: armv5te/OP_DIV_LONG.S */
4599/* File: armv5te/binopWide.S */
4600    /*
4601     * Generic 64-bit binary operation.  Provide an "instr" line that
4602     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4603     * This could be an ARM instruction or a function call.  (If the result
4604     * comes back in a register other than r0, you can override "result".)
4605     *
4606     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4607     * vCC (r1).  Useful for integer division and modulus.
4608     *
4609     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4610     *      xor-long, add-double, sub-double, mul-double, div-double,
4611     *      rem-double
4612     *
4613     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4614     */
4615    /* binop vAA, vBB, vCC */
4616    FETCH(r0, 1)                        @ r0<- CCBB
4617    mov     r9, rINST, lsr #8           @ r9<- AA
4618    and     r2, r0, #255                @ r2<- BB
4619    mov     r3, r0, lsr #8              @ r3<- CC
4620    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4621    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4622    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4623    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4624    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4625    .if 1
4626    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4627    beq     common_errDivideByZero
4628    .endif
4629    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4630
4631                               @ optional op; may set condition codes
4632    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4633    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4634    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4635    GOTO_OPCODE(ip)                     @ jump to next instruction
4636    /* 14-17 instructions */
4637
4638
4639/* ------------------------------ */
4640    .balign 64
4641.L_OP_REM_LONG: /* 0x9f */
4642/* File: armv5te/OP_REM_LONG.S */
4643/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
4644/* File: armv5te/binopWide.S */
4645    /*
4646     * Generic 64-bit binary operation.  Provide an "instr" line that
4647     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4648     * This could be an ARM instruction or a function call.  (If the result
4649     * comes back in a register other than r0, you can override "result".)
4650     *
4651     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4652     * vCC (r1).  Useful for integer division and modulus.
4653     *
4654     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4655     *      xor-long, add-double, sub-double, mul-double, div-double,
4656     *      rem-double
4657     *
4658     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4659     */
4660    /* binop vAA, vBB, vCC */
4661    FETCH(r0, 1)                        @ r0<- CCBB
4662    mov     r9, rINST, lsr #8           @ r9<- AA
4663    and     r2, r0, #255                @ r2<- BB
4664    mov     r3, r0, lsr #8              @ r3<- CC
4665    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4666    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4667    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4668    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4669    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4670    .if 1
4671    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4672    beq     common_errDivideByZero
4673    .endif
4674    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4675
4676                               @ optional op; may set condition codes
4677    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4678    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4679    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
4680    GOTO_OPCODE(ip)                     @ jump to next instruction
4681    /* 14-17 instructions */
4682
4683
4684/* ------------------------------ */
4685    .balign 64
4686.L_OP_AND_LONG: /* 0xa0 */
4687/* File: armv5te/OP_AND_LONG.S */
4688/* File: armv5te/binopWide.S */
4689    /*
4690     * Generic 64-bit binary operation.  Provide an "instr" line that
4691     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4692     * This could be an ARM instruction or a function call.  (If the result
4693     * comes back in a register other than r0, you can override "result".)
4694     *
4695     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4696     * vCC (r1).  Useful for integer division and modulus.
4697     *
4698     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4699     *      xor-long, add-double, sub-double, mul-double, div-double,
4700     *      rem-double
4701     *
4702     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4703     */
4704    /* binop vAA, vBB, vCC */
4705    FETCH(r0, 1)                        @ r0<- CCBB
4706    mov     r9, rINST, lsr #8           @ r9<- AA
4707    and     r2, r0, #255                @ r2<- BB
4708    mov     r3, r0, lsr #8              @ r3<- CC
4709    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4710    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4711    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4712    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4713    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4714    .if 0
4715    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4716    beq     common_errDivideByZero
4717    .endif
4718    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4719
4720    and     r0, r0, r2                           @ optional op; may set condition codes
4721    and     r1, r1, r3                              @ result<- op, r0-r3 changed
4722    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4723    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4724    GOTO_OPCODE(ip)                     @ jump to next instruction
4725    /* 14-17 instructions */
4726
4727
4728/* ------------------------------ */
4729    .balign 64
4730.L_OP_OR_LONG: /* 0xa1 */
4731/* File: armv5te/OP_OR_LONG.S */
4732/* File: armv5te/binopWide.S */
4733    /*
4734     * Generic 64-bit binary operation.  Provide an "instr" line that
4735     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4736     * This could be an ARM instruction or a function call.  (If the result
4737     * comes back in a register other than r0, you can override "result".)
4738     *
4739     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4740     * vCC (r1).  Useful for integer division and modulus.
4741     *
4742     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4743     *      xor-long, add-double, sub-double, mul-double, div-double,
4744     *      rem-double
4745     *
4746     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4747     */
4748    /* binop vAA, vBB, vCC */
4749    FETCH(r0, 1)                        @ r0<- CCBB
4750    mov     r9, rINST, lsr #8           @ r9<- AA
4751    and     r2, r0, #255                @ r2<- BB
4752    mov     r3, r0, lsr #8              @ r3<- CC
4753    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4754    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4755    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4756    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4757    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4758    .if 0
4759    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4760    beq     common_errDivideByZero
4761    .endif
4762    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4763
4764    orr     r0, r0, r2                           @ optional op; may set condition codes
4765    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
4766    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4767    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4768    GOTO_OPCODE(ip)                     @ jump to next instruction
4769    /* 14-17 instructions */
4770
4771
4772/* ------------------------------ */
4773    .balign 64
4774.L_OP_XOR_LONG: /* 0xa2 */
4775/* File: armv5te/OP_XOR_LONG.S */
4776/* File: armv5te/binopWide.S */
4777    /*
4778     * Generic 64-bit binary operation.  Provide an "instr" line that
4779     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4780     * This could be an ARM instruction or a function call.  (If the result
4781     * comes back in a register other than r0, you can override "result".)
4782     *
4783     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4784     * vCC (r1).  Useful for integer division and modulus.
4785     *
4786     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4787     *      xor-long, add-double, sub-double, mul-double, div-double,
4788     *      rem-double
4789     *
4790     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4791     */
4792    /* binop vAA, vBB, vCC */
4793    FETCH(r0, 1)                        @ r0<- CCBB
4794    mov     r9, rINST, lsr #8           @ r9<- AA
4795    and     r2, r0, #255                @ r2<- BB
4796    mov     r3, r0, lsr #8              @ r3<- CC
4797    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4798    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4799    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4800    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4801    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4802    .if 0
4803    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4804    beq     common_errDivideByZero
4805    .endif
4806    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4807
4808    eor     r0, r0, r2                           @ optional op; may set condition codes
4809    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
4810    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4811    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4812    GOTO_OPCODE(ip)                     @ jump to next instruction
4813    /* 14-17 instructions */
4814
4815
4816/* ------------------------------ */
4817    .balign 64
4818.L_OP_SHL_LONG: /* 0xa3 */
4819/* File: armv5te/OP_SHL_LONG.S */
4820    /*
4821     * Long integer shift.  This is different from the generic 32/64-bit
4822     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4823     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4824     * 6 bits of the shift distance.
4825     */
4826    /* shl-long vAA, vBB, vCC */
4827    FETCH(r0, 1)                        @ r0<- CCBB
4828    mov     r9, rINST, lsr #8           @ r9<- AA
4829    and     r3, r0, #255                @ r3<- BB
4830    mov     r0, r0, lsr #8              @ r0<- CC
4831    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4832    GET_VREG(r2, r0)                    @ r2<- vCC
4833    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4834    and     r2, r2, #63                 @ r2<- r2 & 0x3f
4835    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4836
4837    mov     r1, r1, asl r2              @  r1<- r1 << r2
4838    rsb     r3, r2, #32                 @  r3<- 32 - r2
4839    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
4840    subs    ip, r2, #32                 @  ip<- r2 - 32
4841    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
4842    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4843    b       .LOP_SHL_LONG_finish
4844
4845/* ------------------------------ */
4846    .balign 64
4847.L_OP_SHR_LONG: /* 0xa4 */
4848/* File: armv5te/OP_SHR_LONG.S */
4849    /*
4850     * Long integer shift.  This is different from the generic 32/64-bit
4851     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4852     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4853     * 6 bits of the shift distance.
4854     */
4855    /* shr-long vAA, vBB, vCC */
4856    FETCH(r0, 1)                        @ r0<- CCBB
4857    mov     r9, rINST, lsr #8           @ r9<- AA
4858    and     r3, r0, #255                @ r3<- BB
4859    mov     r0, r0, lsr #8              @ r0<- CC
4860    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4861    GET_VREG(r2, r0)                    @ r2<- vCC
4862    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4863    and     r2, r2, #63                 @ r0<- r0 & 0x3f
4864    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4865
4866    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
4867    rsb     r3, r2, #32                 @  r3<- 32 - r2
4868    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
4869    subs    ip, r2, #32                 @  ip<- r2 - 32
4870    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
4871    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4872    b       .LOP_SHR_LONG_finish
4873
4874/* ------------------------------ */
4875    .balign 64
4876.L_OP_USHR_LONG: /* 0xa5 */
4877/* File: armv5te/OP_USHR_LONG.S */
4878    /*
4879     * Long integer shift.  This is different from the generic 32/64-bit
4880     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4881     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4882     * 6 bits of the shift distance.
4883     */
4884    /* ushr-long vAA, vBB, vCC */
4885    FETCH(r0, 1)                        @ r0<- CCBB
4886    mov     r9, rINST, lsr #8           @ r9<- AA
4887    and     r3, r0, #255                @ r3<- BB
4888    mov     r0, r0, lsr #8              @ r0<- CC
4889    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4890    GET_VREG(r2, r0)                    @ r2<- vCC
4891    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4892    and     r2, r2, #63                 @ r0<- r0 & 0x3f
4893    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4894
4895    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
4896    rsb     r3, r2, #32                 @  r3<- 32 - r2
4897    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
4898    subs    ip, r2, #32                 @  ip<- r2 - 32
4899    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
4900    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4901    b       .LOP_USHR_LONG_finish
4902
4903/* ------------------------------ */
4904    .balign 64
4905.L_OP_ADD_FLOAT: /* 0xa6 */
4906/* File: arm-vfp/OP_ADD_FLOAT.S */
4907/* File: arm-vfp/fbinop.S */
4908    /*
4909     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4910     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4911     * use the "softfp" ABI, this must be an instruction, not a function call.
4912     *
4913     * For: add-float, sub-float, mul-float, div-float
4914     */
4915    /* floatop vAA, vBB, vCC */
4916    FETCH(r0, 1)                        @ r0<- CCBB
4917    mov     r9, rINST, lsr #8           @ r9<- AA
4918    mov     r3, r0, lsr #8              @ r3<- CC
4919    and     r2, r0, #255                @ r2<- BB
4920    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4921    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4922    flds    s1, [r3]                    @ s1<- vCC
4923    flds    s0, [r2]                    @ s0<- vBB
4924
4925    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4926    fadds   s2, s0, s1                              @ s2<- op
4927    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4928    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4929    fsts    s2, [r9]                    @ vAA<- s2
4930    GOTO_OPCODE(ip)                     @ jump to next instruction
4931
4932
4933/* ------------------------------ */
4934    .balign 64
4935.L_OP_SUB_FLOAT: /* 0xa7 */
4936/* File: arm-vfp/OP_SUB_FLOAT.S */
4937/* File: arm-vfp/fbinop.S */
4938    /*
4939     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4940     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4941     * use the "softfp" ABI, this must be an instruction, not a function call.
4942     *
4943     * For: add-float, sub-float, mul-float, div-float
4944     */
4945    /* floatop vAA, vBB, vCC */
4946    FETCH(r0, 1)                        @ r0<- CCBB
4947    mov     r9, rINST, lsr #8           @ r9<- AA
4948    mov     r3, r0, lsr #8              @ r3<- CC
4949    and     r2, r0, #255                @ r2<- BB
4950    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4951    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4952    flds    s1, [r3]                    @ s1<- vCC
4953    flds    s0, [r2]                    @ s0<- vBB
4954
4955    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4956    fsubs   s2, s0, s1                              @ s2<- op
4957    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4958    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4959    fsts    s2, [r9]                    @ vAA<- s2
4960    GOTO_OPCODE(ip)                     @ jump to next instruction
4961
4962
4963/* ------------------------------ */
4964    .balign 64
4965.L_OP_MUL_FLOAT: /* 0xa8 */
4966/* File: arm-vfp/OP_MUL_FLOAT.S */
4967/* File: arm-vfp/fbinop.S */
4968    /*
4969     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4970     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4971     * use the "softfp" ABI, this must be an instruction, not a function call.
4972     *
4973     * For: add-float, sub-float, mul-float, div-float
4974     */
4975    /* floatop vAA, vBB, vCC */
4976    FETCH(r0, 1)                        @ r0<- CCBB
4977    mov     r9, rINST, lsr #8           @ r9<- AA
4978    mov     r3, r0, lsr #8              @ r3<- CC
4979    and     r2, r0, #255                @ r2<- BB
4980    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4981    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4982    flds    s1, [r3]                    @ s1<- vCC
4983    flds    s0, [r2]                    @ s0<- vBB
4984
4985    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4986    fmuls   s2, s0, s1                              @ s2<- op
4987    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4988    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4989    fsts    s2, [r9]                    @ vAA<- s2
4990    GOTO_OPCODE(ip)                     @ jump to next instruction
4991
4992
4993/* ------------------------------ */
4994    .balign 64
4995.L_OP_DIV_FLOAT: /* 0xa9 */
4996/* File: arm-vfp/OP_DIV_FLOAT.S */
4997/* File: arm-vfp/fbinop.S */
4998    /*
4999     * Generic 32-bit floating-point operation.  Provide an "instr" line that
5000     * specifies an instruction that performs "s2 = s0 op s1".  Because we
5001     * use the "softfp" ABI, this must be an instruction, not a function call.
5002     *
5003     * For: add-float, sub-float, mul-float, div-float
5004     */
5005    /* floatop vAA, vBB, vCC */
5006    FETCH(r0, 1)                        @ r0<- CCBB
5007    mov     r9, rINST, lsr #8           @ r9<- AA
5008    mov     r3, r0, lsr #8              @ r3<- CC
5009    and     r2, r0, #255                @ r2<- BB
5010    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5011    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5012    flds    s1, [r3]                    @ s1<- vCC
5013    flds    s0, [r2]                    @ s0<- vBB
5014
5015    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5016    fdivs   s2, s0, s1                              @ s2<- op
5017    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5018    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5019    fsts    s2, [r9]                    @ vAA<- s2
5020    GOTO_OPCODE(ip)                     @ jump to next instruction
5021
5022
5023/* ------------------------------ */
5024    .balign 64
5025.L_OP_REM_FLOAT: /* 0xaa */
5026/* File: armv5te/OP_REM_FLOAT.S */
5027/* EABI doesn't define a float remainder function, but libm does */
5028/* File: armv5te/binop.S */
5029    /*
5030     * Generic 32-bit binary operation.  Provide an "instr" line that
5031     * specifies an instruction that performs "result = r0 op r1".
5032     * This could be an ARM instruction or a function call.  (If the result
5033     * comes back in a register other than r0, you can override "result".)
5034     *
5035     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5036     * vCC (r1).  Useful for integer division and modulus.  Note that we
5037     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
5038     * handles it correctly.
5039     *
5040     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
5041     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
5042     *      mul-float, div-float, rem-float
5043     */
5044    /* binop vAA, vBB, vCC */
5045    FETCH(r0, 1)                        @ r0<- CCBB
5046    mov     r9, rINST, lsr #8           @ r9<- AA
5047    mov     r3, r0, lsr #8              @ r3<- CC
5048    and     r2, r0, #255                @ r2<- BB
5049    GET_VREG(r1, r3)                    @ r1<- vCC
5050    GET_VREG(r0, r2)                    @ r0<- vBB
5051    .if 0
5052    cmp     r1, #0                      @ is second operand zero?
5053    beq     common_errDivideByZero
5054    .endif
5055
5056    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5057                               @ optional op; may set condition codes
5058    bl      fmodf                              @ r0<- op, r0-r3 changed
5059    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5060    SET_VREG(r0, r9)               @ vAA<- r0
5061    GOTO_OPCODE(ip)                     @ jump to next instruction
5062    /* 11-14 instructions */
5063
5064
5065/* ------------------------------ */
5066    .balign 64
5067.L_OP_ADD_DOUBLE: /* 0xab */
5068/* File: arm-vfp/OP_ADD_DOUBLE.S */
5069/* File: arm-vfp/fbinopWide.S */
5070    /*
5071     * Generic 64-bit double-precision floating point binary operation.
5072     * Provide an "instr" line that specifies an instruction that performs
5073     * "d2 = d0 op d1".
5074     *
5075     * for: add-double, sub-double, mul-double, div-double
5076     */
5077    /* doubleop vAA, vBB, vCC */
5078    FETCH(r0, 1)                        @ r0<- CCBB
5079    mov     r9, rINST, lsr #8           @ r9<- AA
5080    mov     r3, r0, lsr #8              @ r3<- CC
5081    and     r2, r0, #255                @ r2<- BB
5082    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5083    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5084    fldd    d1, [r3]                    @ d1<- vCC
5085    fldd    d0, [r2]                    @ d0<- vBB
5086
5087    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5088    faddd   d2, d0, d1                              @ s2<- op
5089    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5090    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5091    fstd    d2, [r9]                    @ vAA<- d2
5092    GOTO_OPCODE(ip)                     @ jump to next instruction
5093
5094
5095/* ------------------------------ */
5096    .balign 64
5097.L_OP_SUB_DOUBLE: /* 0xac */
5098/* File: arm-vfp/OP_SUB_DOUBLE.S */
5099/* File: arm-vfp/fbinopWide.S */
5100    /*
5101     * Generic 64-bit double-precision floating point binary operation.
5102     * Provide an "instr" line that specifies an instruction that performs
5103     * "d2 = d0 op d1".
5104     *
5105     * for: add-double, sub-double, mul-double, div-double
5106     */
5107    /* doubleop vAA, vBB, vCC */
5108    FETCH(r0, 1)                        @ r0<- CCBB
5109    mov     r9, rINST, lsr #8           @ r9<- AA
5110    mov     r3, r0, lsr #8              @ r3<- CC
5111    and     r2, r0, #255                @ r2<- BB
5112    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5113    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5114    fldd    d1, [r3]                    @ d1<- vCC
5115    fldd    d0, [r2]                    @ d0<- vBB
5116
5117    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5118    fsubd   d2, d0, d1                              @ s2<- op
5119    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5120    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5121    fstd    d2, [r9]                    @ vAA<- d2
5122    GOTO_OPCODE(ip)                     @ jump to next instruction
5123
5124
5125/* ------------------------------ */
5126    .balign 64
5127.L_OP_MUL_DOUBLE: /* 0xad */
5128/* File: arm-vfp/OP_MUL_DOUBLE.S */
5129/* File: arm-vfp/fbinopWide.S */
5130    /*
5131     * Generic 64-bit double-precision floating point binary operation.
5132     * Provide an "instr" line that specifies an instruction that performs
5133     * "d2 = d0 op d1".
5134     *
5135     * for: add-double, sub-double, mul-double, div-double
5136     */
5137    /* doubleop vAA, vBB, vCC */
5138    FETCH(r0, 1)                        @ r0<- CCBB
5139    mov     r9, rINST, lsr #8           @ r9<- AA
5140    mov     r3, r0, lsr #8              @ r3<- CC
5141    and     r2, r0, #255                @ r2<- BB
5142    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5143    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5144    fldd    d1, [r3]                    @ d1<- vCC
5145    fldd    d0, [r2]                    @ d0<- vBB
5146
5147    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5148    fmuld   d2, d0, d1                              @ s2<- op
5149    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5150    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5151    fstd    d2, [r9]                    @ vAA<- d2
5152    GOTO_OPCODE(ip)                     @ jump to next instruction
5153
5154
5155/* ------------------------------ */
5156    .balign 64
5157.L_OP_DIV_DOUBLE: /* 0xae */
5158/* File: arm-vfp/OP_DIV_DOUBLE.S */
5159/* File: arm-vfp/fbinopWide.S */
5160    /*
5161     * Generic 64-bit double-precision floating point binary operation.
5162     * Provide an "instr" line that specifies an instruction that performs
5163     * "d2 = d0 op d1".
5164     *
5165     * for: add-double, sub-double, mul-double, div-double
5166     */
5167    /* doubleop vAA, vBB, vCC */
5168    FETCH(r0, 1)                        @ r0<- CCBB
5169    mov     r9, rINST, lsr #8           @ r9<- AA
5170    mov     r3, r0, lsr #8              @ r3<- CC
5171    and     r2, r0, #255                @ r2<- BB
5172    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5173    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5174    fldd    d1, [r3]                    @ d1<- vCC
5175    fldd    d0, [r2]                    @ d0<- vBB
5176
5177    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5178    fdivd   d2, d0, d1                              @ s2<- op
5179    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5180    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5181    fstd    d2, [r9]                    @ vAA<- d2
5182    GOTO_OPCODE(ip)                     @ jump to next instruction
5183
5184
5185/* ------------------------------ */
5186    .balign 64
5187.L_OP_REM_DOUBLE: /* 0xaf */
5188/* File: armv5te/OP_REM_DOUBLE.S */
5189/* EABI doesn't define a double remainder function, but libm does */
5190/* File: armv5te/binopWide.S */
5191    /*
5192     * Generic 64-bit binary operation.  Provide an "instr" line that
5193     * specifies an instruction that performs "result = r0-r1 op r2-r3".
5194     * This could be an ARM instruction or a function call.  (If the result
5195     * comes back in a register other than r0, you can override "result".)
5196     *
5197     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5198     * vCC (r1).  Useful for integer division and modulus.
5199     *
5200     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
5201     *      xor-long, add-double, sub-double, mul-double, div-double,
5202     *      rem-double
5203     *
5204     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
5205     */
5206    /* binop vAA, vBB, vCC */
5207    FETCH(r0, 1)                        @ r0<- CCBB
5208    mov     r9, rINST, lsr #8           @ r9<- AA
5209    and     r2, r0, #255                @ r2<- BB
5210    mov     r3, r0, lsr #8              @ r3<- CC
5211    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5212    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
5213    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
5214    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5215    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
5216    .if 0
5217    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5218    beq     common_errDivideByZero
5219    .endif
5220    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5221
5222                               @ optional op; may set condition codes
5223    bl      fmod                              @ result<- op, r0-r3 changed
5224    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5225    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5226    GOTO_OPCODE(ip)                     @ jump to next instruction
5227    /* 14-17 instructions */
5228
5229
5230/* ------------------------------ */
5231    .balign 64
5232.L_OP_ADD_INT_2ADDR: /* 0xb0 */
5233/* File: armv5te/OP_ADD_INT_2ADDR.S */
5234/* File: armv5te/binop2addr.S */
5235    /*
5236     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5237     * that specifies an instruction that performs "result = r0 op r1".
5238     * This could be an ARM instruction or a function call.  (If the result
5239     * comes back in a register other than r0, you can override "result".)
5240     *
5241     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5242     * vCC (r1).  Useful for integer division and modulus.
5243     *
5244     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5245     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5246     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5247     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5248     */
5249    /* binop/2addr vA, vB */
5250    mov     r9, rINST, lsr #8           @ r9<- A+
5251    mov     r3, rINST, lsr #12          @ r3<- B
5252    and     r9, r9, #15
5253    GET_VREG(r1, r3)                    @ r1<- vB
5254    GET_VREG(r0, r9)                    @ r0<- vA
5255    .if 0
5256    cmp     r1, #0                      @ is second operand zero?
5257    beq     common_errDivideByZero
5258    .endif
5259    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5260
5261                               @ optional op; may set condition codes
5262    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
5263    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5264    SET_VREG(r0, r9)               @ vAA<- r0
5265    GOTO_OPCODE(ip)                     @ jump to next instruction
5266    /* 10-13 instructions */
5267
5268
5269/* ------------------------------ */
5270    .balign 64
5271.L_OP_SUB_INT_2ADDR: /* 0xb1 */
5272/* File: armv5te/OP_SUB_INT_2ADDR.S */
5273/* File: armv5te/binop2addr.S */
5274    /*
5275     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5276     * that specifies an instruction that performs "result = r0 op r1".
5277     * This could be an ARM instruction or a function call.  (If the result
5278     * comes back in a register other than r0, you can override "result".)
5279     *
5280     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5281     * vCC (r1).  Useful for integer division and modulus.
5282     *
5283     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5284     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5285     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5286     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5287     */
5288    /* binop/2addr vA, vB */
5289    mov     r9, rINST, lsr #8           @ r9<- A+
5290    mov     r3, rINST, lsr #12          @ r3<- B
5291    and     r9, r9, #15
5292    GET_VREG(r1, r3)                    @ r1<- vB
5293    GET_VREG(r0, r9)                    @ r0<- vA
5294    .if 0
5295    cmp     r1, #0                      @ is second operand zero?
5296    beq     common_errDivideByZero
5297    .endif
5298    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5299
5300                               @ optional op; may set condition codes
5301    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
5302    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5303    SET_VREG(r0, r9)               @ vAA<- r0
5304    GOTO_OPCODE(ip)                     @ jump to next instruction
5305    /* 10-13 instructions */
5306
5307
5308/* ------------------------------ */
5309    .balign 64
5310.L_OP_MUL_INT_2ADDR: /* 0xb2 */
5311/* File: armv5te/OP_MUL_INT_2ADDR.S */
5312/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
5313/* File: armv5te/binop2addr.S */
5314    /*
5315     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5316     * that specifies an instruction that performs "result = r0 op r1".
5317     * This could be an ARM instruction or a function call.  (If the result
5318     * comes back in a register other than r0, you can override "result".)
5319     *
5320     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5321     * vCC (r1).  Useful for integer division and modulus.
5322     *
5323     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5324     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5325     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5326     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5327     */
5328    /* binop/2addr vA, vB */
5329    mov     r9, rINST, lsr #8           @ r9<- A+
5330    mov     r3, rINST, lsr #12          @ r3<- B
5331    and     r9, r9, #15
5332    GET_VREG(r1, r3)                    @ r1<- vB
5333    GET_VREG(r0, r9)                    @ r0<- vA
5334    .if 0
5335    cmp     r1, #0                      @ is second operand zero?
5336    beq     common_errDivideByZero
5337    .endif
5338    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5339
5340                               @ optional op; may set condition codes
5341    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
5342    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5343    SET_VREG(r0, r9)               @ vAA<- r0
5344    GOTO_OPCODE(ip)                     @ jump to next instruction
5345    /* 10-13 instructions */
5346
5347
5348/* ------------------------------ */
5349    .balign 64
5350.L_OP_DIV_INT_2ADDR: /* 0xb3 */
5351/* File: armv5te/OP_DIV_INT_2ADDR.S */
5352/* File: armv5te/binop2addr.S */
5353    /*
5354     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5355     * that specifies an instruction that performs "result = r0 op r1".
5356     * This could be an ARM instruction or a function call.  (If the result
5357     * comes back in a register other than r0, you can override "result".)
5358     *
5359     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5360     * vCC (r1).  Useful for integer division and modulus.
5361     *
5362     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5363     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5364     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5365     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5366     */
5367    /* binop/2addr vA, vB */
5368    mov     r9, rINST, lsr #8           @ r9<- A+
5369    mov     r3, rINST, lsr #12          @ r3<- B
5370    and     r9, r9, #15
5371    GET_VREG(r1, r3)                    @ r1<- vB
5372    GET_VREG(r0, r9)                    @ r0<- vA
5373    .if 1
5374    cmp     r1, #0                      @ is second operand zero?
5375    beq     common_errDivideByZero
5376    .endif
5377    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5378
5379                               @ optional op; may set condition codes
5380    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
5381    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5382    SET_VREG(r0, r9)               @ vAA<- r0
5383    GOTO_OPCODE(ip)                     @ jump to next instruction
5384    /* 10-13 instructions */
5385
5386
5387/* ------------------------------ */
5388    .balign 64
5389.L_OP_REM_INT_2ADDR: /* 0xb4 */
5390/* File: armv5te/OP_REM_INT_2ADDR.S */
5391/* idivmod returns quotient in r0 and remainder in r1 */
5392/* File: armv5te/binop2addr.S */
5393    /*
5394     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5395     * that specifies an instruction that performs "result = r0 op r1".
5396     * This could be an ARM instruction or a function call.  (If the result
5397     * comes back in a register other than r0, you can override "result".)
5398     *
5399     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5400     * vCC (r1).  Useful for integer division and modulus.
5401     *
5402     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5403     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5404     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5405     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5406     */
5407    /* binop/2addr vA, vB */
5408    mov     r9, rINST, lsr #8           @ r9<- A+
5409    mov     r3, rINST, lsr #12          @ r3<- B
5410    and     r9, r9, #15
5411    GET_VREG(r1, r3)                    @ r1<- vB
5412    GET_VREG(r0, r9)                    @ r0<- vA
5413    .if 1
5414    cmp     r1, #0                      @ is second operand zero?
5415    beq     common_errDivideByZero
5416    .endif
5417    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5418
5419                               @ optional op; may set condition codes
5420    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
5421    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5422    SET_VREG(r1, r9)               @ vAA<- r1
5423    GOTO_OPCODE(ip)                     @ jump to next instruction
5424    /* 10-13 instructions */
5425
5426
5427/* ------------------------------ */
5428    .balign 64
5429.L_OP_AND_INT_2ADDR: /* 0xb5 */
5430/* File: armv5te/OP_AND_INT_2ADDR.S */
5431/* File: armv5te/binop2addr.S */
5432    /*
5433     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5434     * that specifies an instruction that performs "result = r0 op r1".
5435     * This could be an ARM instruction or a function call.  (If the result
5436     * comes back in a register other than r0, you can override "result".)
5437     *
5438     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5439     * vCC (r1).  Useful for integer division and modulus.
5440     *
5441     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5442     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5443     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5444     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5445     */
5446    /* binop/2addr vA, vB */
5447    mov     r9, rINST, lsr #8           @ r9<- A+
5448    mov     r3, rINST, lsr #12          @ r3<- B
5449    and     r9, r9, #15
5450    GET_VREG(r1, r3)                    @ r1<- vB
5451    GET_VREG(r0, r9)                    @ r0<- vA
5452    .if 0
5453    cmp     r1, #0                      @ is second operand zero?
5454    beq     common_errDivideByZero
5455    .endif
5456    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5457
5458                               @ optional op; may set condition codes
5459    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
5460    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5461    SET_VREG(r0, r9)               @ vAA<- r0
5462    GOTO_OPCODE(ip)                     @ jump to next instruction
5463    /* 10-13 instructions */
5464
5465
5466/* ------------------------------ */
5467    .balign 64
5468.L_OP_OR_INT_2ADDR: /* 0xb6 */
5469/* File: armv5te/OP_OR_INT_2ADDR.S */
5470/* File: armv5te/binop2addr.S */
5471    /*
5472     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5473     * that specifies an instruction that performs "result = r0 op r1".
5474     * This could be an ARM instruction or a function call.  (If the result
5475     * comes back in a register other than r0, you can override "result".)
5476     *
5477     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5478     * vCC (r1).  Useful for integer division and modulus.
5479     *
5480     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5481     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5482     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5483     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5484     */
5485    /* binop/2addr vA, vB */
5486    mov     r9, rINST, lsr #8           @ r9<- A+
5487    mov     r3, rINST, lsr #12          @ r3<- B
5488    and     r9, r9, #15
5489    GET_VREG(r1, r3)                    @ r1<- vB
5490    GET_VREG(r0, r9)                    @ r0<- vA
5491    .if 0
5492    cmp     r1, #0                      @ is second operand zero?
5493    beq     common_errDivideByZero
5494    .endif
5495    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5496
5497                               @ optional op; may set condition codes
5498    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
5499    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5500    SET_VREG(r0, r9)               @ vAA<- r0
5501    GOTO_OPCODE(ip)                     @ jump to next instruction
5502    /* 10-13 instructions */
5503
5504
5505/* ------------------------------ */
5506    .balign 64
5507.L_OP_XOR_INT_2ADDR: /* 0xb7 */
5508/* File: armv5te/OP_XOR_INT_2ADDR.S */
5509/* File: armv5te/binop2addr.S */
5510    /*
5511     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5512     * that specifies an instruction that performs "result = r0 op r1".
5513     * This could be an ARM instruction or a function call.  (If the result
5514     * comes back in a register other than r0, you can override "result".)
5515     *
5516     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5517     * vCC (r1).  Useful for integer division and modulus.
5518     *
5519     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5520     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5521     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5522     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5523     */
5524    /* binop/2addr vA, vB */
5525    mov     r9, rINST, lsr #8           @ r9<- A+
5526    mov     r3, rINST, lsr #12          @ r3<- B
5527    and     r9, r9, #15
5528    GET_VREG(r1, r3)                    @ r1<- vB
5529    GET_VREG(r0, r9)                    @ r0<- vA
5530    .if 0
5531    cmp     r1, #0                      @ is second operand zero?
5532    beq     common_errDivideByZero
5533    .endif
5534    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5535
5536                               @ optional op; may set condition codes
5537    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
5538    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5539    SET_VREG(r0, r9)               @ vAA<- r0
5540    GOTO_OPCODE(ip)                     @ jump to next instruction
5541    /* 10-13 instructions */
5542
5543
5544/* ------------------------------ */
5545    .balign 64
5546.L_OP_SHL_INT_2ADDR: /* 0xb8 */
5547/* File: armv5te/OP_SHL_INT_2ADDR.S */
5548/* File: armv5te/binop2addr.S */
5549    /*
5550     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5551     * that specifies an instruction that performs "result = r0 op r1".
5552     * This could be an ARM instruction or a function call.  (If the result
5553     * comes back in a register other than r0, you can override "result".)
5554     *
5555     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5556     * vCC (r1).  Useful for integer division and modulus.
5557     *
5558     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5559     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5560     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5561     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5562     */
5563    /* binop/2addr vA, vB */
5564    mov     r9, rINST, lsr #8           @ r9<- A+
5565    mov     r3, rINST, lsr #12          @ r3<- B
5566    and     r9, r9, #15
5567    GET_VREG(r1, r3)                    @ r1<- vB
5568    GET_VREG(r0, r9)                    @ r0<- vA
5569    .if 0
5570    cmp     r1, #0                      @ is second operand zero?
5571    beq     common_errDivideByZero
5572    .endif
5573    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5574
5575    and     r1, r1, #31                           @ optional op; may set condition codes
5576    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
5577    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5578    SET_VREG(r0, r9)               @ vAA<- r0
5579    GOTO_OPCODE(ip)                     @ jump to next instruction
5580    /* 10-13 instructions */
5581
5582
5583/* ------------------------------ */
5584    .balign 64
5585.L_OP_SHR_INT_2ADDR: /* 0xb9 */
5586/* File: armv5te/OP_SHR_INT_2ADDR.S */
5587/* File: armv5te/binop2addr.S */
5588    /*
5589     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5590     * that specifies an instruction that performs "result = r0 op r1".
5591     * This could be an ARM instruction or a function call.  (If the result
5592     * comes back in a register other than r0, you can override "result".)
5593     *
5594     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5595     * vCC (r1).  Useful for integer division and modulus.
5596     *
5597     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5598     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5599     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5600     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5601     */
5602    /* binop/2addr vA, vB */
5603    mov     r9, rINST, lsr #8           @ r9<- A+
5604    mov     r3, rINST, lsr #12          @ r3<- B
5605    and     r9, r9, #15
5606    GET_VREG(r1, r3)                    @ r1<- vB
5607    GET_VREG(r0, r9)                    @ r0<- vA
5608    .if 0
5609    cmp     r1, #0                      @ is second operand zero?
5610    beq     common_errDivideByZero
5611    .endif
5612    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5613
5614    and     r1, r1, #31                           @ optional op; may set condition codes
5615    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
5616    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5617    SET_VREG(r0, r9)               @ vAA<- r0
5618    GOTO_OPCODE(ip)                     @ jump to next instruction
5619    /* 10-13 instructions */
5620
5621
5622/* ------------------------------ */
5623    .balign 64
5624.L_OP_USHR_INT_2ADDR: /* 0xba */
5625/* File: armv5te/OP_USHR_INT_2ADDR.S */
5626/* File: armv5te/binop2addr.S */
5627    /*
5628     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5629     * that specifies an instruction that performs "result = r0 op r1".
5630     * This could be an ARM instruction or a function call.  (If the result
5631     * comes back in a register other than r0, you can override "result".)
5632     *
5633     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5634     * vCC (r1).  Useful for integer division and modulus.
5635     *
5636     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5637     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5638     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5639     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5640     */
5641    /* binop/2addr vA, vB */
5642    mov     r9, rINST, lsr #8           @ r9<- A+
5643    mov     r3, rINST, lsr #12          @ r3<- B
5644    and     r9, r9, #15
5645    GET_VREG(r1, r3)                    @ r1<- vB
5646    GET_VREG(r0, r9)                    @ r0<- vA
5647    .if 0
5648    cmp     r1, #0                      @ is second operand zero?
5649    beq     common_errDivideByZero
5650    .endif
5651    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5652
5653    and     r1, r1, #31                           @ optional op; may set condition codes
5654    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
5655    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5656    SET_VREG(r0, r9)               @ vAA<- r0
5657    GOTO_OPCODE(ip)                     @ jump to next instruction
5658    /* 10-13 instructions */
5659
5660
5661/* ------------------------------ */
5662    .balign 64
5663.L_OP_ADD_LONG_2ADDR: /* 0xbb */
5664/* File: armv5te/OP_ADD_LONG_2ADDR.S */
5665/* File: armv5te/binopWide2addr.S */
5666    /*
5667     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5668     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5669     * This could be an ARM instruction or a function call.  (If the result
5670     * comes back in a register other than r0, you can override "result".)
5671     *
5672     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5673     * vCC (r1).  Useful for integer division and modulus.
5674     *
5675     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5676     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5677     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5678     *      rem-double/2addr
5679     */
5680    /* binop/2addr vA, vB */
5681    mov     r9, rINST, lsr #8           @ r9<- A+
5682    mov     r1, rINST, lsr #12          @ r1<- B
5683    and     r9, r9, #15
5684    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5685    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5686    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5687    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5688    .if 0
5689    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5690    beq     common_errDivideByZero
5691    .endif
5692    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5693
5694    adds    r0, r0, r2                           @ optional op; may set condition codes
5695    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
5696    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5697    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5698    GOTO_OPCODE(ip)                     @ jump to next instruction
5699    /* 12-15 instructions */
5700
5701
5702/* ------------------------------ */
5703    .balign 64
5704.L_OP_SUB_LONG_2ADDR: /* 0xbc */
5705/* File: armv5te/OP_SUB_LONG_2ADDR.S */
5706/* File: armv5te/binopWide2addr.S */
5707    /*
5708     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5709     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5710     * This could be an ARM instruction or a function call.  (If the result
5711     * comes back in a register other than r0, you can override "result".)
5712     *
5713     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5714     * vCC (r1).  Useful for integer division and modulus.
5715     *
5716     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5717     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5718     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5719     *      rem-double/2addr
5720     */
5721    /* binop/2addr vA, vB */
5722    mov     r9, rINST, lsr #8           @ r9<- A+
5723    mov     r1, rINST, lsr #12          @ r1<- B
5724    and     r9, r9, #15
5725    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5726    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5727    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5728    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5729    .if 0
5730    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5731    beq     common_errDivideByZero
5732    .endif
5733    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5734
5735    subs    r0, r0, r2                           @ optional op; may set condition codes
5736    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
5737    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5738    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5739    GOTO_OPCODE(ip)                     @ jump to next instruction
5740    /* 12-15 instructions */
5741
5742
5743/* ------------------------------ */
5744    .balign 64
5745.L_OP_MUL_LONG_2ADDR: /* 0xbd */
5746/* File: armv5te/OP_MUL_LONG_2ADDR.S */
5747    /*
5748     * Signed 64-bit integer multiply, "/2addr" version.
5749     *
5750     * See OP_MUL_LONG for an explanation.
5751     *
5752     * We get a little tight on registers, so to avoid looking up &fp[A]
5753     * again we stuff it into rINST.
5754     */
5755    /* mul-long/2addr vA, vB */
5756    mov     r9, rINST, lsr #8           @ r9<- A+
5757    mov     r1, rINST, lsr #12          @ r1<- B
5758    and     r9, r9, #15
5759    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5760    add     rINST, rFP, r9, lsl #2      @ rINST<- &fp[A]
5761    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5762    ldmia   rINST, {r0-r1}              @ r0/r1<- vAA/vAA+1
5763    mul     ip, r2, r1                  @  ip<- ZxW
5764    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
5765    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
5766    mov     r0, rINST                   @ r0<- &fp[A] (free up rINST)
5767    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5768    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
5769    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5770    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
5771    GOTO_OPCODE(ip)                     @ jump to next instruction
5772
5773/* ------------------------------ */
5774    .balign 64
5775.L_OP_DIV_LONG_2ADDR: /* 0xbe */
5776/* File: armv5te/OP_DIV_LONG_2ADDR.S */
5777/* File: armv5te/binopWide2addr.S */
5778    /*
5779     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5780     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5781     * This could be an ARM instruction or a function call.  (If the result
5782     * comes back in a register other than r0, you can override "result".)
5783     *
5784     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5785     * vCC (r1).  Useful for integer division and modulus.
5786     *
5787     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5788     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5789     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5790     *      rem-double/2addr
5791     */
5792    /* binop/2addr vA, vB */
5793    mov     r9, rINST, lsr #8           @ r9<- A+
5794    mov     r1, rINST, lsr #12          @ r1<- B
5795    and     r9, r9, #15
5796    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5797    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5798    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5799    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5800    .if 1
5801    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5802    beq     common_errDivideByZero
5803    .endif
5804    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5805
5806                               @ optional op; may set condition codes
5807    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
5808    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5809    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5810    GOTO_OPCODE(ip)                     @ jump to next instruction
5811    /* 12-15 instructions */
5812
5813
5814/* ------------------------------ */
5815    .balign 64
5816.L_OP_REM_LONG_2ADDR: /* 0xbf */
5817/* File: armv5te/OP_REM_LONG_2ADDR.S */
5818/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
5819/* File: armv5te/binopWide2addr.S */
5820    /*
5821     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5822     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5823     * This could be an ARM instruction or a function call.  (If the result
5824     * comes back in a register other than r0, you can override "result".)
5825     *
5826     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5827     * vCC (r1).  Useful for integer division and modulus.
5828     *
5829     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5830     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5831     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5832     *      rem-double/2addr
5833     */
5834    /* binop/2addr vA, vB */
5835    mov     r9, rINST, lsr #8           @ r9<- A+
5836    mov     r1, rINST, lsr #12          @ r1<- B
5837    and     r9, r9, #15
5838    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5839    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5840    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5841    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5842    .if 1
5843    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5844    beq     common_errDivideByZero
5845    .endif
5846    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5847
5848                               @ optional op; may set condition codes
5849    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
5850    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5851    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
5852    GOTO_OPCODE(ip)                     @ jump to next instruction
5853    /* 12-15 instructions */
5854
5855
5856/* ------------------------------ */
5857    .balign 64
5858.L_OP_AND_LONG_2ADDR: /* 0xc0 */
5859/* File: armv5te/OP_AND_LONG_2ADDR.S */
5860/* File: armv5te/binopWide2addr.S */
5861    /*
5862     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5863     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5864     * This could be an ARM instruction or a function call.  (If the result
5865     * comes back in a register other than r0, you can override "result".)
5866     *
5867     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5868     * vCC (r1).  Useful for integer division and modulus.
5869     *
5870     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5871     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5872     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5873     *      rem-double/2addr
5874     */
5875    /* binop/2addr vA, vB */
5876    mov     r9, rINST, lsr #8           @ r9<- A+
5877    mov     r1, rINST, lsr #12          @ r1<- B
5878    and     r9, r9, #15
5879    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5880    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5881    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5882    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5883    .if 0
5884    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5885    beq     common_errDivideByZero
5886    .endif
5887    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5888
5889    and     r0, r0, r2                           @ optional op; may set condition codes
5890    and     r1, r1, r3                              @ result<- op, r0-r3 changed
5891    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5892    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5893    GOTO_OPCODE(ip)                     @ jump to next instruction
5894    /* 12-15 instructions */
5895
5896
5897/* ------------------------------ */
5898    .balign 64
5899.L_OP_OR_LONG_2ADDR: /* 0xc1 */
5900/* File: armv5te/OP_OR_LONG_2ADDR.S */
5901/* File: armv5te/binopWide2addr.S */
5902    /*
5903     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5904     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5905     * This could be an ARM instruction or a function call.  (If the result
5906     * comes back in a register other than r0, you can override "result".)
5907     *
5908     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5909     * vCC (r1).  Useful for integer division and modulus.
5910     *
5911     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5912     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5913     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5914     *      rem-double/2addr
5915     */
5916    /* binop/2addr vA, vB */
5917    mov     r9, rINST, lsr #8           @ r9<- A+
5918    mov     r1, rINST, lsr #12          @ r1<- B
5919    and     r9, r9, #15
5920    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5921    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5922    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5923    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5924    .if 0
5925    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5926    beq     common_errDivideByZero
5927    .endif
5928    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5929
5930    orr     r0, r0, r2                           @ optional op; may set condition codes
5931    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
5932    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5933    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5934    GOTO_OPCODE(ip)                     @ jump to next instruction
5935    /* 12-15 instructions */
5936
5937
5938/* ------------------------------ */
5939    .balign 64
5940.L_OP_XOR_LONG_2ADDR: /* 0xc2 */
5941/* File: armv5te/OP_XOR_LONG_2ADDR.S */
5942/* File: armv5te/binopWide2addr.S */
5943    /*
5944     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5945     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5946     * This could be an ARM instruction or a function call.  (If the result
5947     * comes back in a register other than r0, you can override "result".)
5948     *
5949     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5950     * vCC (r1).  Useful for integer division and modulus.
5951     *
5952     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5953     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5954     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5955     *      rem-double/2addr
5956     */
5957    /* binop/2addr vA, vB */
5958    mov     r9, rINST, lsr #8           @ r9<- A+
5959    mov     r1, rINST, lsr #12          @ r1<- B
5960    and     r9, r9, #15
5961    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5962    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5963    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5964    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5965    .if 0
5966    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5967    beq     common_errDivideByZero
5968    .endif
5969    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5970
5971    eor     r0, r0, r2                           @ optional op; may set condition codes
5972    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
5973    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5974    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5975    GOTO_OPCODE(ip)                     @ jump to next instruction
5976    /* 12-15 instructions */
5977
5978
5979/* ------------------------------ */
5980    .balign 64
5981.L_OP_SHL_LONG_2ADDR: /* 0xc3 */
5982/* File: armv5te/OP_SHL_LONG_2ADDR.S */
5983    /*
5984     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5985     * 32-bit shift distance.
5986     */
5987    /* shl-long/2addr vA, vB */
5988    mov     r9, rINST, lsr #8           @ r9<- A+
5989    mov     r3, rINST, lsr #12          @ r3<- B
5990    and     r9, r9, #15
5991    GET_VREG(r2, r3)                    @ r2<- vB
5992    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5993    and     r2, r2, #63                 @ r2<- r2 & 0x3f
5994    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5995
5996    mov     r1, r1, asl r2              @  r1<- r1 << r2
5997    rsb     r3, r2, #32                 @  r3<- 32 - r2
5998    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
5999    subs    ip, r2, #32                 @  ip<- r2 - 32
6000    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6001    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
6002    mov     r0, r0, asl r2              @  r0<- r0 << r2
6003    b       .LOP_SHL_LONG_2ADDR_finish
6004
6005/* ------------------------------ */
6006    .balign 64
6007.L_OP_SHR_LONG_2ADDR: /* 0xc4 */
6008/* File: armv5te/OP_SHR_LONG_2ADDR.S */
6009    /*
6010     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6011     * 32-bit shift distance.
6012     */
6013    /* shr-long/2addr vA, vB */
6014    mov     r9, rINST, lsr #8           @ r9<- A+
6015    mov     r3, rINST, lsr #12          @ r3<- B
6016    and     r9, r9, #15
6017    GET_VREG(r2, r3)                    @ r2<- vB
6018    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6019    and     r2, r2, #63                 @ r2<- r2 & 0x3f
6020    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6021
6022    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
6023    rsb     r3, r2, #32                 @  r3<- 32 - r2
6024    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
6025    subs    ip, r2, #32                 @  ip<- r2 - 32
6026    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6027    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
6028    mov     r1, r1, asr r2              @  r1<- r1 >> r2
6029    b       .LOP_SHR_LONG_2ADDR_finish
6030
6031/* ------------------------------ */
6032    .balign 64
6033.L_OP_USHR_LONG_2ADDR: /* 0xc5 */
6034/* File: armv5te/OP_USHR_LONG_2ADDR.S */
6035    /*
6036     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6037     * 32-bit shift distance.
6038     */
6039    /* ushr-long/2addr vA, vB */
6040    mov     r9, rINST, lsr #8           @ r9<- A+
6041    mov     r3, rINST, lsr #12          @ r3<- B
6042    and     r9, r9, #15
6043    GET_VREG(r2, r3)                    @ r2<- vB
6044    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6045    and     r2, r2, #63                 @ r2<- r2 & 0x3f
6046    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6047
6048    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
6049    rsb     r3, r2, #32                 @  r3<- 32 - r2
6050    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
6051    subs    ip, r2, #32                 @  ip<- r2 - 32
6052    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6053    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
6054    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
6055    b       .LOP_USHR_LONG_2ADDR_finish
6056
6057/* ------------------------------ */
6058    .balign 64
6059.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
6060/* File: arm-vfp/OP_ADD_FLOAT_2ADDR.S */
6061/* File: arm-vfp/fbinop2addr.S */
6062    /*
6063     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6064     * an "instr" line that specifies an instruction that performs
6065     * "s2 = s0 op s1".
6066     *
6067     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6068     */
6069    /* binop/2addr vA, vB */
6070    mov     r3, rINST, lsr #12          @ r3<- B
6071    mov     r9, rINST, lsr #8           @ r9<- A+
6072    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6073    and     r9, r9, #15                 @ r9<- A
6074    flds    s1, [r3]                    @ s1<- vB
6075    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6076    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6077    flds    s0, [r9]                    @ s0<- vA
6078
6079    fadds   s2, s0, s1                              @ s2<- op
6080    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6081    fsts    s2, [r9]                    @ vAA<- s2
6082    GOTO_OPCODE(ip)                     @ jump to next instruction
6083
6084
6085/* ------------------------------ */
6086    .balign 64
6087.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
6088/* File: arm-vfp/OP_SUB_FLOAT_2ADDR.S */
6089/* File: arm-vfp/fbinop2addr.S */
6090    /*
6091     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6092     * an "instr" line that specifies an instruction that performs
6093     * "s2 = s0 op s1".
6094     *
6095     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6096     */
6097    /* binop/2addr vA, vB */
6098    mov     r3, rINST, lsr #12          @ r3<- B
6099    mov     r9, rINST, lsr #8           @ r9<- A+
6100    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6101    and     r9, r9, #15                 @ r9<- A
6102    flds    s1, [r3]                    @ s1<- vB
6103    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6104    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6105    flds    s0, [r9]                    @ s0<- vA
6106
6107    fsubs   s2, s0, s1                              @ s2<- op
6108    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6109    fsts    s2, [r9]                    @ vAA<- s2
6110    GOTO_OPCODE(ip)                     @ jump to next instruction
6111
6112
6113/* ------------------------------ */
6114    .balign 64
6115.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
6116/* File: arm-vfp/OP_MUL_FLOAT_2ADDR.S */
6117/* File: arm-vfp/fbinop2addr.S */
6118    /*
6119     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6120     * an "instr" line that specifies an instruction that performs
6121     * "s2 = s0 op s1".
6122     *
6123     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6124     */
6125    /* binop/2addr vA, vB */
6126    mov     r3, rINST, lsr #12          @ r3<- B
6127    mov     r9, rINST, lsr #8           @ r9<- A+
6128    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6129    and     r9, r9, #15                 @ r9<- A
6130    flds    s1, [r3]                    @ s1<- vB
6131    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6132    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6133    flds    s0, [r9]                    @ s0<- vA
6134
6135    fmuls   s2, s0, s1                              @ s2<- op
6136    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6137    fsts    s2, [r9]                    @ vAA<- s2
6138    GOTO_OPCODE(ip)                     @ jump to next instruction
6139
6140
6141/* ------------------------------ */
6142    .balign 64
6143.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
6144/* File: arm-vfp/OP_DIV_FLOAT_2ADDR.S */
6145/* File: arm-vfp/fbinop2addr.S */
6146    /*
6147     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6148     * an "instr" line that specifies an instruction that performs
6149     * "s2 = s0 op s1".
6150     *
6151     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6152     */
6153    /* binop/2addr vA, vB */
6154    mov     r3, rINST, lsr #12          @ r3<- B
6155    mov     r9, rINST, lsr #8           @ r9<- A+
6156    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6157    and     r9, r9, #15                 @ r9<- A
6158    flds    s1, [r3]                    @ s1<- vB
6159    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6160    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6161    flds    s0, [r9]                    @ s0<- vA
6162
6163    fdivs   s2, s0, s1                              @ s2<- op
6164    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6165    fsts    s2, [r9]                    @ vAA<- s2
6166    GOTO_OPCODE(ip)                     @ jump to next instruction
6167
6168
6169/* ------------------------------ */
6170    .balign 64
6171.L_OP_REM_FLOAT_2ADDR: /* 0xca */
6172/* File: armv5te/OP_REM_FLOAT_2ADDR.S */
6173/* EABI doesn't define a float remainder function, but libm does */
6174/* File: armv5te/binop2addr.S */
6175    /*
6176     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6177     * that specifies an instruction that performs "result = r0 op r1".
6178     * This could be an ARM instruction or a function call.  (If the result
6179     * comes back in a register other than r0, you can override "result".)
6180     *
6181     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6182     * vCC (r1).  Useful for integer division and modulus.
6183     *
6184     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6185     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6186     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6187     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6188     */
6189    /* binop/2addr vA, vB */
6190    mov     r9, rINST, lsr #8           @ r9<- A+
6191    mov     r3, rINST, lsr #12          @ r3<- B
6192    and     r9, r9, #15
6193    GET_VREG(r1, r3)                    @ r1<- vB
6194    GET_VREG(r0, r9)                    @ r0<- vA
6195    .if 0
6196    cmp     r1, #0                      @ is second operand zero?
6197    beq     common_errDivideByZero
6198    .endif
6199    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6200
6201                               @ optional op; may set condition codes
6202    bl      fmodf                              @ r0<- op, r0-r3 changed
6203    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6204    SET_VREG(r0, r9)               @ vAA<- r0
6205    GOTO_OPCODE(ip)                     @ jump to next instruction
6206    /* 10-13 instructions */
6207
6208
6209/* ------------------------------ */
6210    .balign 64
6211.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
6212/* File: arm-vfp/OP_ADD_DOUBLE_2ADDR.S */
6213/* File: arm-vfp/fbinopWide2addr.S */
6214    /*
6215     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6216     * an "instr" line that specifies an instruction that performs
6217     * "d2 = d0 op d1".
6218     *
6219     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6220     *      div-double/2addr
6221     */
6222    /* binop/2addr vA, vB */
6223    mov     r3, rINST, lsr #12          @ r3<- B
6224    mov     r9, rINST, lsr #8           @ r9<- A+
6225    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6226    and     r9, r9, #15                 @ r9<- A
6227    fldd    d1, [r3]                    @ d1<- vB
6228    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6229    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6230    fldd    d0, [r9]                    @ d0<- vA
6231
6232    faddd   d2, d0, d1                              @ d2<- op
6233    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6234    fstd    d2, [r9]                    @ vAA<- d2
6235    GOTO_OPCODE(ip)                     @ jump to next instruction
6236
6237
6238/* ------------------------------ */
6239    .balign 64
6240.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
6241/* File: arm-vfp/OP_SUB_DOUBLE_2ADDR.S */
6242/* File: arm-vfp/fbinopWide2addr.S */
6243    /*
6244     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6245     * an "instr" line that specifies an instruction that performs
6246     * "d2 = d0 op d1".
6247     *
6248     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6249     *      div-double/2addr
6250     */
6251    /* binop/2addr vA, vB */
6252    mov     r3, rINST, lsr #12          @ r3<- B
6253    mov     r9, rINST, lsr #8           @ r9<- A+
6254    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6255    and     r9, r9, #15                 @ r9<- A
6256    fldd    d1, [r3]                    @ d1<- vB
6257    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6258    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6259    fldd    d0, [r9]                    @ d0<- vA
6260
6261    fsubd   d2, d0, d1                              @ d2<- op
6262    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6263    fstd    d2, [r9]                    @ vAA<- d2
6264    GOTO_OPCODE(ip)                     @ jump to next instruction
6265
6266
6267/* ------------------------------ */
6268    .balign 64
6269.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
6270/* File: arm-vfp/OP_MUL_DOUBLE_2ADDR.S */
6271/* File: arm-vfp/fbinopWide2addr.S */
6272    /*
6273     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6274     * an "instr" line that specifies an instruction that performs
6275     * "d2 = d0 op d1".
6276     *
6277     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6278     *      div-double/2addr
6279     */
6280    /* binop/2addr vA, vB */
6281    mov     r3, rINST, lsr #12          @ r3<- B
6282    mov     r9, rINST, lsr #8           @ r9<- A+
6283    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6284    and     r9, r9, #15                 @ r9<- A
6285    fldd    d1, [r3]                    @ d1<- vB
6286    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6287    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6288    fldd    d0, [r9]                    @ d0<- vA
6289
6290    fmuld   d2, d0, d1                              @ d2<- op
6291    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6292    fstd    d2, [r9]                    @ vAA<- d2
6293    GOTO_OPCODE(ip)                     @ jump to next instruction
6294
6295
6296/* ------------------------------ */
6297    .balign 64
6298.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */
6299/* File: arm-vfp/OP_DIV_DOUBLE_2ADDR.S */
6300/* File: arm-vfp/fbinopWide2addr.S */
6301    /*
6302     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6303     * an "instr" line that specifies an instruction that performs
6304     * "d2 = d0 op d1".
6305     *
6306     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6307     *      div-double/2addr
6308     */
6309    /* binop/2addr vA, vB */
6310    mov     r3, rINST, lsr #12          @ r3<- B
6311    mov     r9, rINST, lsr #8           @ r9<- A+
6312    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6313    and     r9, r9, #15                 @ r9<- A
6314    fldd    d1, [r3]                    @ d1<- vB
6315    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6316    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6317    fldd    d0, [r9]                    @ d0<- vA
6318
6319    fdivd   d2, d0, d1                              @ d2<- op
6320    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6321    fstd    d2, [r9]                    @ vAA<- d2
6322    GOTO_OPCODE(ip)                     @ jump to next instruction
6323
6324
6325/* ------------------------------ */
6326    .balign 64
6327.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */
6328/* File: armv5te/OP_REM_DOUBLE_2ADDR.S */
6329/* EABI doesn't define a double remainder function, but libm does */
6330/* File: armv5te/binopWide2addr.S */
6331    /*
6332     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6333     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6334     * This could be an ARM instruction or a function call.  (If the result
6335     * comes back in a register other than r0, you can override "result".)
6336     *
6337     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6338     * vCC (r1).  Useful for integer division and modulus.
6339     *
6340     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6341     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6342     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6343     *      rem-double/2addr
6344     */
6345    /* binop/2addr vA, vB */
6346    mov     r9, rINST, lsr #8           @ r9<- A+
6347    mov     r1, rINST, lsr #12          @ r1<- B
6348    and     r9, r9, #15
6349    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6350    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6351    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6352    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6353    .if 0
6354    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6355    beq     common_errDivideByZero
6356    .endif
6357    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6358
6359                               @ optional op; may set condition codes
6360    bl      fmod                              @ result<- op, r0-r3 changed
6361    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6362    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6363    GOTO_OPCODE(ip)                     @ jump to next instruction
6364    /* 12-15 instructions */
6365
6366
6367/* ------------------------------ */
6368    .balign 64
6369.L_OP_ADD_INT_LIT16: /* 0xd0 */
6370/* File: armv5te/OP_ADD_INT_LIT16.S */
6371/* File: armv5te/binopLit16.S */
6372    /*
6373     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6374     * that specifies an instruction that performs "result = r0 op r1".
6375     * This could be an ARM instruction or a function call.  (If the result
6376     * comes back in a register other than r0, you can override "result".)
6377     *
6378     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6379     * vCC (r1).  Useful for integer division and modulus.
6380     *
6381     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6382     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6383     */
6384    /* binop/lit16 vA, vB, #+CCCC */
6385    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6386    mov     r2, rINST, lsr #12          @ r2<- B
6387    mov     r9, rINST, lsr #8           @ r9<- A+
6388    GET_VREG(r0, r2)                    @ r0<- vB
6389    and     r9, r9, #15
6390    .if 0
6391    cmp     r1, #0                      @ is second operand zero?
6392    beq     common_errDivideByZero
6393    .endif
6394    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6395
6396    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
6397    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6398    SET_VREG(r0, r9)               @ vAA<- r0
6399    GOTO_OPCODE(ip)                     @ jump to next instruction
6400    /* 10-13 instructions */
6401
6402
6403/* ------------------------------ */
6404    .balign 64
6405.L_OP_RSUB_INT: /* 0xd1 */
6406/* File: armv5te/OP_RSUB_INT.S */
6407/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
6408/* File: armv5te/binopLit16.S */
6409    /*
6410     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6411     * that specifies an instruction that performs "result = r0 op r1".
6412     * This could be an ARM instruction or a function call.  (If the result
6413     * comes back in a register other than r0, you can override "result".)
6414     *
6415     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6416     * vCC (r1).  Useful for integer division and modulus.
6417     *
6418     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6419     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6420     */
6421    /* binop/lit16 vA, vB, #+CCCC */
6422    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6423    mov     r2, rINST, lsr #12          @ r2<- B
6424    mov     r9, rINST, lsr #8           @ r9<- A+
6425    GET_VREG(r0, r2)                    @ r0<- vB
6426    and     r9, r9, #15
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    rsb     r0, r0, r1                              @ 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_MUL_INT_LIT16: /* 0xd2 */
6443/* File: armv5te/OP_MUL_INT_LIT16.S */
6444/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
6445/* File: armv5te/binopLit16.S */
6446    /*
6447     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6448     * that specifies an instruction that performs "result = r0 op r1".
6449     * This could be an ARM instruction or a function call.  (If the result
6450     * comes back in a register other than r0, you can override "result".)
6451     *
6452     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6453     * vCC (r1).  Useful for integer division and modulus.
6454     *
6455     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6456     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6457     */
6458    /* binop/lit16 vA, vB, #+CCCC */
6459    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6460    mov     r2, rINST, lsr #12          @ r2<- B
6461    mov     r9, rINST, lsr #8           @ r9<- A+
6462    GET_VREG(r0, r2)                    @ r0<- vB
6463    and     r9, r9, #15
6464    .if 0
6465    cmp     r1, #0                      @ is second operand zero?
6466    beq     common_errDivideByZero
6467    .endif
6468    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6469
6470    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
6471    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6472    SET_VREG(r0, r9)               @ vAA<- r0
6473    GOTO_OPCODE(ip)                     @ jump to next instruction
6474    /* 10-13 instructions */
6475
6476
6477/* ------------------------------ */
6478    .balign 64
6479.L_OP_DIV_INT_LIT16: /* 0xd3 */
6480/* File: armv5te/OP_DIV_INT_LIT16.S */
6481/* File: armv5te/binopLit16.S */
6482    /*
6483     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6484     * that specifies an instruction that performs "result = r0 op r1".
6485     * This could be an ARM instruction or a function call.  (If the result
6486     * comes back in a register other than r0, you can override "result".)
6487     *
6488     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6489     * vCC (r1).  Useful for integer division and modulus.
6490     *
6491     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6492     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6493     */
6494    /* binop/lit16 vA, vB, #+CCCC */
6495    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6496    mov     r2, rINST, lsr #12          @ r2<- B
6497    mov     r9, rINST, lsr #8           @ r9<- A+
6498    GET_VREG(r0, r2)                    @ r0<- vB
6499    and     r9, r9, #15
6500    .if 1
6501    cmp     r1, #0                      @ is second operand zero?
6502    beq     common_errDivideByZero
6503    .endif
6504    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6505
6506    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
6507    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6508    SET_VREG(r0, r9)               @ vAA<- r0
6509    GOTO_OPCODE(ip)                     @ jump to next instruction
6510    /* 10-13 instructions */
6511
6512
6513/* ------------------------------ */
6514    .balign 64
6515.L_OP_REM_INT_LIT16: /* 0xd4 */
6516/* File: armv5te/OP_REM_INT_LIT16.S */
6517/* idivmod returns quotient in r0 and remainder in r1 */
6518/* File: armv5te/binopLit16.S */
6519    /*
6520     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6521     * that specifies an instruction that performs "result = r0 op r1".
6522     * This could be an ARM instruction or a function call.  (If the result
6523     * comes back in a register other than r0, you can override "result".)
6524     *
6525     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6526     * vCC (r1).  Useful for integer division and modulus.
6527     *
6528     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6529     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6530     */
6531    /* binop/lit16 vA, vB, #+CCCC */
6532    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6533    mov     r2, rINST, lsr #12          @ r2<- B
6534    mov     r9, rINST, lsr #8           @ r9<- A+
6535    GET_VREG(r0, r2)                    @ r0<- vB
6536    and     r9, r9, #15
6537    .if 1
6538    cmp     r1, #0                      @ is second operand zero?
6539    beq     common_errDivideByZero
6540    .endif
6541    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6542
6543    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
6544    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6545    SET_VREG(r1, r9)               @ vAA<- r1
6546    GOTO_OPCODE(ip)                     @ jump to next instruction
6547    /* 10-13 instructions */
6548
6549
6550/* ------------------------------ */
6551    .balign 64
6552.L_OP_AND_INT_LIT16: /* 0xd5 */
6553/* File: armv5te/OP_AND_INT_LIT16.S */
6554/* File: armv5te/binopLit16.S */
6555    /*
6556     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6557     * that specifies an instruction that performs "result = r0 op r1".
6558     * This could be an ARM instruction or a function call.  (If the result
6559     * comes back in a register other than r0, you can override "result".)
6560     *
6561     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6562     * vCC (r1).  Useful for integer division and modulus.
6563     *
6564     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6565     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6566     */
6567    /* binop/lit16 vA, vB, #+CCCC */
6568    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6569    mov     r2, rINST, lsr #12          @ r2<- B
6570    mov     r9, rINST, lsr #8           @ r9<- A+
6571    GET_VREG(r0, r2)                    @ r0<- vB
6572    and     r9, r9, #15
6573    .if 0
6574    cmp     r1, #0                      @ is second operand zero?
6575    beq     common_errDivideByZero
6576    .endif
6577    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6578
6579    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
6580    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6581    SET_VREG(r0, r9)               @ vAA<- r0
6582    GOTO_OPCODE(ip)                     @ jump to next instruction
6583    /* 10-13 instructions */
6584
6585
6586/* ------------------------------ */
6587    .balign 64
6588.L_OP_OR_INT_LIT16: /* 0xd6 */
6589/* File: armv5te/OP_OR_INT_LIT16.S */
6590/* File: armv5te/binopLit16.S */
6591    /*
6592     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6593     * that specifies an instruction that performs "result = r0 op r1".
6594     * This could be an ARM instruction or a function call.  (If the result
6595     * comes back in a register other than r0, you can override "result".)
6596     *
6597     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6598     * vCC (r1).  Useful for integer division and modulus.
6599     *
6600     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6601     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6602     */
6603    /* binop/lit16 vA, vB, #+CCCC */
6604    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6605    mov     r2, rINST, lsr #12          @ r2<- B
6606    mov     r9, rINST, lsr #8           @ r9<- A+
6607    GET_VREG(r0, r2)                    @ r0<- vB
6608    and     r9, r9, #15
6609    .if 0
6610    cmp     r1, #0                      @ is second operand zero?
6611    beq     common_errDivideByZero
6612    .endif
6613    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6614
6615    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
6616    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6617    SET_VREG(r0, r9)               @ vAA<- r0
6618    GOTO_OPCODE(ip)                     @ jump to next instruction
6619    /* 10-13 instructions */
6620
6621
6622/* ------------------------------ */
6623    .balign 64
6624.L_OP_XOR_INT_LIT16: /* 0xd7 */
6625/* File: armv5te/OP_XOR_INT_LIT16.S */
6626/* File: armv5te/binopLit16.S */
6627    /*
6628     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6629     * that specifies an instruction that performs "result = r0 op r1".
6630     * This could be an ARM instruction or a function call.  (If the result
6631     * comes back in a register other than r0, you can override "result".)
6632     *
6633     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6634     * vCC (r1).  Useful for integer division and modulus.
6635     *
6636     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6637     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6638     */
6639    /* binop/lit16 vA, vB, #+CCCC */
6640    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6641    mov     r2, rINST, lsr #12          @ r2<- B
6642    mov     r9, rINST, lsr #8           @ r9<- A+
6643    GET_VREG(r0, r2)                    @ r0<- vB
6644    and     r9, r9, #15
6645    .if 0
6646    cmp     r1, #0                      @ is second operand zero?
6647    beq     common_errDivideByZero
6648    .endif
6649    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6650
6651    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
6652    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6653    SET_VREG(r0, r9)               @ vAA<- r0
6654    GOTO_OPCODE(ip)                     @ jump to next instruction
6655    /* 10-13 instructions */
6656
6657
6658/* ------------------------------ */
6659    .balign 64
6660.L_OP_ADD_INT_LIT8: /* 0xd8 */
6661/* File: armv5te/OP_ADD_INT_LIT8.S */
6662/* File: armv5te/binopLit8.S */
6663    /*
6664     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6665     * that specifies an instruction that performs "result = r0 op r1".
6666     * This could be an ARM instruction or a function call.  (If the result
6667     * comes back in a register other than r0, you can override "result".)
6668     *
6669     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6670     * vCC (r1).  Useful for integer division and modulus.
6671     *
6672     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6673     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6674     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6675     */
6676    /* binop/lit8 vAA, vBB, #+CC */
6677    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6678    mov     r9, rINST, lsr #8           @ r9<- AA
6679    and     r2, r3, #255                @ r2<- BB
6680    GET_VREG(r0, r2)                    @ r0<- vBB
6681    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6682    .if 0
6683    @cmp     r1, #0                      @ is second operand zero?
6684    beq     common_errDivideByZero
6685    .endif
6686    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6687
6688                               @ optional op; may set condition codes
6689    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
6690    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6691    SET_VREG(r0, r9)               @ vAA<- r0
6692    GOTO_OPCODE(ip)                     @ jump to next instruction
6693    /* 10-12 instructions */
6694
6695
6696/* ------------------------------ */
6697    .balign 64
6698.L_OP_RSUB_INT_LIT8: /* 0xd9 */
6699/* File: armv5te/OP_RSUB_INT_LIT8.S */
6700/* File: armv5te/binopLit8.S */
6701    /*
6702     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6703     * that specifies an instruction that performs "result = r0 op r1".
6704     * This could be an ARM instruction or a function call.  (If the result
6705     * comes back in a register other than r0, you can override "result".)
6706     *
6707     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6708     * vCC (r1).  Useful for integer division and modulus.
6709     *
6710     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6711     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6712     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6713     */
6714    /* binop/lit8 vAA, vBB, #+CC */
6715    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6716    mov     r9, rINST, lsr #8           @ r9<- AA
6717    and     r2, r3, #255                @ r2<- BB
6718    GET_VREG(r0, r2)                    @ r0<- vBB
6719    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6720    .if 0
6721    @cmp     r1, #0                      @ is second operand zero?
6722    beq     common_errDivideByZero
6723    .endif
6724    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6725
6726                               @ optional op; may set condition codes
6727    rsb     r0, r0, r1                              @ r0<- op, r0-r3 changed
6728    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6729    SET_VREG(r0, r9)               @ vAA<- r0
6730    GOTO_OPCODE(ip)                     @ jump to next instruction
6731    /* 10-12 instructions */
6732
6733
6734/* ------------------------------ */
6735    .balign 64
6736.L_OP_MUL_INT_LIT8: /* 0xda */
6737/* File: armv5te/OP_MUL_INT_LIT8.S */
6738/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
6739/* File: armv5te/binopLit8.S */
6740    /*
6741     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6742     * that specifies an instruction that performs "result = r0 op r1".
6743     * This could be an ARM instruction or a function call.  (If the result
6744     * comes back in a register other than r0, you can override "result".)
6745     *
6746     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6747     * vCC (r1).  Useful for integer division and modulus.
6748     *
6749     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6750     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6751     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6752     */
6753    /* binop/lit8 vAA, vBB, #+CC */
6754    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6755    mov     r9, rINST, lsr #8           @ r9<- AA
6756    and     r2, r3, #255                @ r2<- BB
6757    GET_VREG(r0, r2)                    @ r0<- vBB
6758    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6759    .if 0
6760    @cmp     r1, #0                      @ is second operand zero?
6761    beq     common_errDivideByZero
6762    .endif
6763    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6764
6765                               @ optional op; may set condition codes
6766    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
6767    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6768    SET_VREG(r0, r9)               @ vAA<- r0
6769    GOTO_OPCODE(ip)                     @ jump to next instruction
6770    /* 10-12 instructions */
6771
6772
6773/* ------------------------------ */
6774    .balign 64
6775.L_OP_DIV_INT_LIT8: /* 0xdb */
6776/* File: armv5te/OP_DIV_INT_LIT8.S */
6777/* File: armv5te/binopLit8.S */
6778    /*
6779     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6780     * that specifies an instruction that performs "result = r0 op r1".
6781     * This could be an ARM instruction or a function call.  (If the result
6782     * comes back in a register other than r0, you can override "result".)
6783     *
6784     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6785     * vCC (r1).  Useful for integer division and modulus.
6786     *
6787     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6788     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6789     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6790     */
6791    /* binop/lit8 vAA, vBB, #+CC */
6792    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6793    mov     r9, rINST, lsr #8           @ r9<- AA
6794    and     r2, r3, #255                @ r2<- BB
6795    GET_VREG(r0, r2)                    @ r0<- vBB
6796    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6797    .if 1
6798    @cmp     r1, #0                      @ is second operand zero?
6799    beq     common_errDivideByZero
6800    .endif
6801    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6802
6803                               @ optional op; may set condition codes
6804    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
6805    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6806    SET_VREG(r0, r9)               @ vAA<- r0
6807    GOTO_OPCODE(ip)                     @ jump to next instruction
6808    /* 10-12 instructions */
6809
6810
6811/* ------------------------------ */
6812    .balign 64
6813.L_OP_REM_INT_LIT8: /* 0xdc */
6814/* File: armv5te/OP_REM_INT_LIT8.S */
6815/* idivmod returns quotient in r0 and remainder in r1 */
6816/* File: armv5te/binopLit8.S */
6817    /*
6818     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6819     * that specifies an instruction that performs "result = r0 op r1".
6820     * This could be an ARM instruction or a function call.  (If the result
6821     * comes back in a register other than r0, you can override "result".)
6822     *
6823     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6824     * vCC (r1).  Useful for integer division and modulus.
6825     *
6826     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6827     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6828     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6829     */
6830    /* binop/lit8 vAA, vBB, #+CC */
6831    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6832    mov     r9, rINST, lsr #8           @ r9<- AA
6833    and     r2, r3, #255                @ r2<- BB
6834    GET_VREG(r0, r2)                    @ r0<- vBB
6835    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6836    .if 1
6837    @cmp     r1, #0                      @ is second operand zero?
6838    beq     common_errDivideByZero
6839    .endif
6840    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6841
6842                               @ optional op; may set condition codes
6843    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
6844    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6845    SET_VREG(r1, r9)               @ vAA<- r1
6846    GOTO_OPCODE(ip)                     @ jump to next instruction
6847    /* 10-12 instructions */
6848
6849
6850/* ------------------------------ */
6851    .balign 64
6852.L_OP_AND_INT_LIT8: /* 0xdd */
6853/* File: armv5te/OP_AND_INT_LIT8.S */
6854/* File: armv5te/binopLit8.S */
6855    /*
6856     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6857     * that specifies an instruction that performs "result = r0 op r1".
6858     * This could be an ARM instruction or a function call.  (If the result
6859     * comes back in a register other than r0, you can override "result".)
6860     *
6861     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6862     * vCC (r1).  Useful for integer division and modulus.
6863     *
6864     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6865     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6866     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6867     */
6868    /* binop/lit8 vAA, vBB, #+CC */
6869    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6870    mov     r9, rINST, lsr #8           @ r9<- AA
6871    and     r2, r3, #255                @ r2<- BB
6872    GET_VREG(r0, r2)                    @ r0<- vBB
6873    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6874    .if 0
6875    @cmp     r1, #0                      @ is second operand zero?
6876    beq     common_errDivideByZero
6877    .endif
6878    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6879
6880                               @ optional op; may set condition codes
6881    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
6882    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6883    SET_VREG(r0, r9)               @ vAA<- r0
6884    GOTO_OPCODE(ip)                     @ jump to next instruction
6885    /* 10-12 instructions */
6886
6887
6888/* ------------------------------ */
6889    .balign 64
6890.L_OP_OR_INT_LIT8: /* 0xde */
6891/* File: armv5te/OP_OR_INT_LIT8.S */
6892/* File: armv5te/binopLit8.S */
6893    /*
6894     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6895     * that specifies an instruction that performs "result = r0 op r1".
6896     * This could be an ARM instruction or a function call.  (If the result
6897     * comes back in a register other than r0, you can override "result".)
6898     *
6899     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6900     * vCC (r1).  Useful for integer division and modulus.
6901     *
6902     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6903     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6904     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6905     */
6906    /* binop/lit8 vAA, vBB, #+CC */
6907    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6908    mov     r9, rINST, lsr #8           @ r9<- AA
6909    and     r2, r3, #255                @ r2<- BB
6910    GET_VREG(r0, r2)                    @ r0<- vBB
6911    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6912    .if 0
6913    @cmp     r1, #0                      @ is second operand zero?
6914    beq     common_errDivideByZero
6915    .endif
6916    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6917
6918                               @ optional op; may set condition codes
6919    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
6920    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6921    SET_VREG(r0, r9)               @ vAA<- r0
6922    GOTO_OPCODE(ip)                     @ jump to next instruction
6923    /* 10-12 instructions */
6924
6925
6926/* ------------------------------ */
6927    .balign 64
6928.L_OP_XOR_INT_LIT8: /* 0xdf */
6929/* File: armv5te/OP_XOR_INT_LIT8.S */
6930/* File: armv5te/binopLit8.S */
6931    /*
6932     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6933     * that specifies an instruction that performs "result = r0 op r1".
6934     * This could be an ARM instruction or a function call.  (If the result
6935     * comes back in a register other than r0, you can override "result".)
6936     *
6937     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6938     * vCC (r1).  Useful for integer division and modulus.
6939     *
6940     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6941     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6942     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6943     */
6944    /* binop/lit8 vAA, vBB, #+CC */
6945    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6946    mov     r9, rINST, lsr #8           @ r9<- AA
6947    and     r2, r3, #255                @ r2<- BB
6948    GET_VREG(r0, r2)                    @ r0<- vBB
6949    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6950    .if 0
6951    @cmp     r1, #0                      @ is second operand zero?
6952    beq     common_errDivideByZero
6953    .endif
6954    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6955
6956                               @ optional op; may set condition codes
6957    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
6958    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6959    SET_VREG(r0, r9)               @ vAA<- r0
6960    GOTO_OPCODE(ip)                     @ jump to next instruction
6961    /* 10-12 instructions */
6962
6963
6964/* ------------------------------ */
6965    .balign 64
6966.L_OP_SHL_INT_LIT8: /* 0xe0 */
6967/* File: armv5te/OP_SHL_INT_LIT8.S */
6968/* File: armv5te/binopLit8.S */
6969    /*
6970     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6971     * that specifies an instruction that performs "result = r0 op r1".
6972     * This could be an ARM instruction or a function call.  (If the result
6973     * comes back in a register other than r0, you can override "result".)
6974     *
6975     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6976     * vCC (r1).  Useful for integer division and modulus.
6977     *
6978     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6979     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6980     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6981     */
6982    /* binop/lit8 vAA, vBB, #+CC */
6983    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6984    mov     r9, rINST, lsr #8           @ r9<- AA
6985    and     r2, r3, #255                @ r2<- BB
6986    GET_VREG(r0, r2)                    @ r0<- vBB
6987    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6988    .if 0
6989    @cmp     r1, #0                      @ is second operand zero?
6990    beq     common_errDivideByZero
6991    .endif
6992    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6993
6994    and     r1, r1, #31                           @ optional op; may set condition codes
6995    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
6996    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6997    SET_VREG(r0, r9)               @ vAA<- r0
6998    GOTO_OPCODE(ip)                     @ jump to next instruction
6999    /* 10-12 instructions */
7000
7001
7002/* ------------------------------ */
7003    .balign 64
7004.L_OP_SHR_INT_LIT8: /* 0xe1 */
7005/* File: armv5te/OP_SHR_INT_LIT8.S */
7006/* File: armv5te/binopLit8.S */
7007    /*
7008     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7009     * that specifies an instruction that performs "result = r0 op r1".
7010     * This could be an ARM instruction or a function call.  (If the result
7011     * comes back in a register other than r0, you can override "result".)
7012     *
7013     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7014     * vCC (r1).  Useful for integer division and modulus.
7015     *
7016     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7017     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7018     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7019     */
7020    /* binop/lit8 vAA, vBB, #+CC */
7021    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7022    mov     r9, rINST, lsr #8           @ r9<- AA
7023    and     r2, r3, #255                @ r2<- BB
7024    GET_VREG(r0, r2)                    @ r0<- vBB
7025    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7026    .if 0
7027    @cmp     r1, #0                      @ is second operand zero?
7028    beq     common_errDivideByZero
7029    .endif
7030    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7031
7032    and     r1, r1, #31                           @ optional op; may set condition codes
7033    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
7034    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7035    SET_VREG(r0, r9)               @ vAA<- r0
7036    GOTO_OPCODE(ip)                     @ jump to next instruction
7037    /* 10-12 instructions */
7038
7039
7040/* ------------------------------ */
7041    .balign 64
7042.L_OP_USHR_INT_LIT8: /* 0xe2 */
7043/* File: armv5te/OP_USHR_INT_LIT8.S */
7044/* File: armv5te/binopLit8.S */
7045    /*
7046     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7047     * that specifies an instruction that performs "result = r0 op r1".
7048     * This could be an ARM instruction or a function call.  (If the result
7049     * comes back in a register other than r0, you can override "result".)
7050     *
7051     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7052     * vCC (r1).  Useful for integer division and modulus.
7053     *
7054     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7055     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7056     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7057     */
7058    /* binop/lit8 vAA, vBB, #+CC */
7059    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7060    mov     r9, rINST, lsr #8           @ r9<- AA
7061    and     r2, r3, #255                @ r2<- BB
7062    GET_VREG(r0, r2)                    @ r0<- vBB
7063    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7064    .if 0
7065    @cmp     r1, #0                      @ is second operand zero?
7066    beq     common_errDivideByZero
7067    .endif
7068    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7069
7070    and     r1, r1, #31                           @ optional op; may set condition codes
7071    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
7072    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7073    SET_VREG(r0, r9)               @ vAA<- r0
7074    GOTO_OPCODE(ip)                     @ jump to next instruction
7075    /* 10-12 instructions */
7076
7077
7078/* ------------------------------ */
7079    .balign 64
7080.L_OP_IGET_VOLATILE: /* 0xe3 */
7081/* File: armv5te/OP_IGET_VOLATILE.S */
7082/* File: armv5te/OP_IGET.S */
7083    /*
7084     * General 32-bit instance field get.
7085     *
7086     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7087     */
7088    /* op vA, vB, field@CCCC */
7089    mov     r0, rINST, lsr #12          @ r0<- B
7090    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7091    FETCH(r1, 1)                        @ r1<- field ref CCCC
7092    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7093    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7094    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7095    cmp     r0, #0                      @ is resolved entry null?
7096    bne     .LOP_IGET_VOLATILE_finish          @ no, already resolved
70978:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7098    EXPORT_PC()                         @ resolve() could throw
7099    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7100    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7101    cmp     r0, #0
7102    bne     .LOP_IGET_VOLATILE_finish
7103    b       common_exceptionThrown
7104
7105
7106/* ------------------------------ */
7107    .balign 64
7108.L_OP_IPUT_VOLATILE: /* 0xe4 */
7109/* File: armv5te/OP_IPUT_VOLATILE.S */
7110/* File: armv5te/OP_IPUT.S */
7111    /*
7112     * General 32-bit instance field put.
7113     *
7114     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
7115     */
7116    /* op vA, vB, field@CCCC */
7117    mov     r0, rINST, lsr #12          @ r0<- B
7118    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7119    FETCH(r1, 1)                        @ r1<- field ref CCCC
7120    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7121    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7122    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7123    cmp     r0, #0                      @ is resolved entry null?
7124    bne     .LOP_IPUT_VOLATILE_finish          @ no, already resolved
71258:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7126    EXPORT_PC()                         @ resolve() could throw
7127    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7128    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7129    cmp     r0, #0                      @ success?
7130    bne     .LOP_IPUT_VOLATILE_finish          @ yes, finish up
7131    b       common_exceptionThrown
7132
7133
7134/* ------------------------------ */
7135    .balign 64
7136.L_OP_SGET_VOLATILE: /* 0xe5 */
7137/* File: armv5te/OP_SGET_VOLATILE.S */
7138/* File: armv5te/OP_SGET.S */
7139    /*
7140     * General 32-bit SGET handler.
7141     *
7142     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7143     */
7144    /* op vAA, field@BBBB */
7145    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7146    FETCH(r1, 1)                        @ r1<- field ref BBBB
7147    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7148    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7149    cmp     r0, #0                      @ is resolved entry null?
7150    beq     .LOP_SGET_VOLATILE_resolve         @ yes, do resolve
7151.LOP_SGET_VOLATILE_finish: @ field ptr in r0
7152    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7153    SMP_DMB                            @ acquiring load
7154    mov     r2, rINST, lsr #8           @ r2<- AA
7155    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7156    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7157    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7158    GOTO_OPCODE(ip)                     @ jump to next instruction
7159
7160
7161/* ------------------------------ */
7162    .balign 64
7163.L_OP_SPUT_VOLATILE: /* 0xe6 */
7164/* File: armv5te/OP_SPUT_VOLATILE.S */
7165/* File: armv5te/OP_SPUT.S */
7166    /*
7167     * General 32-bit SPUT handler.
7168     *
7169     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
7170     */
7171    /* op vAA, field@BBBB */
7172    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7173    FETCH(r1, 1)                        @ r1<- field ref BBBB
7174    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7175    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7176    cmp     r0, #0                      @ is resolved entry null?
7177    beq     .LOP_SPUT_VOLATILE_resolve         @ yes, do resolve
7178.LOP_SPUT_VOLATILE_finish:   @ field ptr in r0
7179    mov     r2, rINST, lsr #8           @ r2<- AA
7180    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7181    GET_VREG(r1, r2)                    @ r1<- fp[AA]
7182    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7183    SMP_DMB                            @ releasing store
7184    str     r1, [r0, #offStaticField_value] @ field<- vAA
7185    GOTO_OPCODE(ip)                     @ jump to next instruction
7186
7187
7188/* ------------------------------ */
7189    .balign 64
7190.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
7191/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */
7192/* File: armv5te/OP_IGET.S */
7193    /*
7194     * General 32-bit instance field get.
7195     *
7196     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7197     */
7198    /* op vA, vB, field@CCCC */
7199    mov     r0, rINST, lsr #12          @ r0<- B
7200    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7201    FETCH(r1, 1)                        @ r1<- field ref CCCC
7202    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7203    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7204    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7205    cmp     r0, #0                      @ is resolved entry null?
7206    bne     .LOP_IGET_OBJECT_VOLATILE_finish          @ no, already resolved
72078:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7208    EXPORT_PC()                         @ resolve() could throw
7209    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7210    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7211    cmp     r0, #0
7212    bne     .LOP_IGET_OBJECT_VOLATILE_finish
7213    b       common_exceptionThrown
7214
7215
7216/* ------------------------------ */
7217    .balign 64
7218.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
7219/* File: armv5te/OP_IGET_WIDE_VOLATILE.S */
7220/* File: armv5te/OP_IGET_WIDE.S */
7221    /*
7222     * Wide 32-bit instance field get.
7223     */
7224    /* iget-wide vA, vB, field@CCCC */
7225    mov     r0, rINST, lsr #12          @ r0<- B
7226    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7227    FETCH(r1, 1)                        @ r1<- field ref CCCC
7228    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7229    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7230    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7231    cmp     r0, #0                      @ is resolved entry null?
7232    bne     .LOP_IGET_WIDE_VOLATILE_finish          @ no, already resolved
72338:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
7234    EXPORT_PC()                         @ resolve() could throw
7235    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7236    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7237    cmp     r0, #0
7238    bne     .LOP_IGET_WIDE_VOLATILE_finish
7239    b       common_exceptionThrown
7240
7241
7242/* ------------------------------ */
7243    .balign 64
7244.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
7245/* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */
7246/* File: armv5te/OP_IPUT_WIDE.S */
7247    /* iput-wide vA, vB, field@CCCC */
7248    mov     r0, rINST, lsr #12          @ r0<- B
7249    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7250    FETCH(r1, 1)                        @ r1<- field ref CCCC
7251    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7252    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7253    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7254    cmp     r0, #0                      @ is resolved entry null?
7255    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ no, already resolved
72568:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
7257    EXPORT_PC()                         @ resolve() could throw
7258    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7259    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7260    cmp     r0, #0                      @ success?
7261    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ yes, finish up
7262    b       common_exceptionThrown
7263
7264
7265/* ------------------------------ */
7266    .balign 64
7267.L_OP_SGET_WIDE_VOLATILE: /* 0xea */
7268/* File: armv5te/OP_SGET_WIDE_VOLATILE.S */
7269/* File: armv5te/OP_SGET_WIDE.S */
7270    /*
7271     * 64-bit SGET handler.
7272     */
7273    /* sget-wide vAA, field@BBBB */
7274    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7275    FETCH(r1, 1)                        @ r1<- field ref BBBB
7276    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7277    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7278    cmp     r0, #0                      @ is resolved entry null?
7279    beq     .LOP_SGET_WIDE_VOLATILE_resolve         @ yes, do resolve
7280.LOP_SGET_WIDE_VOLATILE_finish:
7281    mov     r9, rINST, lsr #8           @ r9<- AA
7282    .if 1
7283    add     r0, r0, #offStaticField_value @ r0<- pointer to data
7284    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
7285    .else
7286    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
7287    .endif
7288    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7289    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7290    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
7291    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7292    GOTO_OPCODE(ip)                     @ jump to next instruction
7293
7294
7295/* ------------------------------ */
7296    .balign 64
7297.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
7298/* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */
7299/* File: armv5te/OP_SPUT_WIDE.S */
7300    /*
7301     * 64-bit SPUT handler.
7302     */
7303    /* sput-wide vAA, field@BBBB */
7304    ldr     r0, [rGLUE, #offGlue_methodClassDex]  @ r0<- DvmDex
7305    FETCH(r1, 1)                        @ r1<- field ref BBBB
7306    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
7307    mov     r9, rINST, lsr #8           @ r9<- AA
7308    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
7309    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7310    cmp     r2, #0                      @ is resolved entry null?
7311    beq     .LOP_SPUT_WIDE_VOLATILE_resolve         @ yes, do resolve
7312.LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9
7313    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7314    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
7315    GET_INST_OPCODE(r10)                @ extract opcode from rINST
7316    .if 1
7317    add     r2, r2, #offStaticField_value @ r2<- pointer to data
7318    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
7319    .else
7320    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
7321    .endif
7322    GOTO_OPCODE(r10)                    @ jump to next instruction
7323
7324
7325/* ------------------------------ */
7326    .balign 64
7327.L_OP_BREAKPOINT: /* 0xec */
7328/* File: armv5te/OP_BREAKPOINT.S */
7329/* File: armv5te/unused.S */
7330    bl      common_abort
7331
7332
7333/* ------------------------------ */
7334    .balign 64
7335.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
7336/* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */
7337    /*
7338     * Handle a throw-verification-error instruction.  This throws an
7339     * exception for an error discovered during verification.  The
7340     * exception is indicated by AA, with some detail provided by BBBB.
7341     */
7342    /* op AA, ref@BBBB */
7343    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
7344    FETCH(r2, 1)                        @ r2<- BBBB
7345    EXPORT_PC()                         @ export the PC
7346    mov     r1, rINST, lsr #8           @ r1<- AA
7347    bl      dvmThrowVerificationError   @ always throws
7348    b       common_exceptionThrown      @ handle exception
7349
7350/* ------------------------------ */
7351    .balign 64
7352.L_OP_EXECUTE_INLINE: /* 0xee */
7353/* File: armv5te/OP_EXECUTE_INLINE.S */
7354    /*
7355     * Execute a "native inline" instruction.
7356     *
7357     * We need to call an InlineOp4Func:
7358     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7359     *
7360     * The first four args are in r0-r3, pointer to return value storage
7361     * is on the stack.  The function's return value is a flag that tells
7362     * us if an exception was thrown.
7363     */
7364    /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
7365    FETCH(r10, 1)                       @ r10<- BBBB
7366    add     r1, rGLUE, #offGlue_retval  @ r1<- &glue->retval
7367    EXPORT_PC()                         @ can throw
7368    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7369    mov     r0, rINST, lsr #12          @ r0<- B
7370    str     r1, [sp]                    @ push &glue->retval
7371    bl      .LOP_EXECUTE_INLINE_continue        @ make call; will return after
7372    add     sp, sp, #8                  @ pop stack
7373    cmp     r0, #0                      @ test boolean result of inline
7374    beq     common_exceptionThrown      @ returned false, handle exception
7375    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7376    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7377    GOTO_OPCODE(ip)                     @ jump to next instruction
7378
7379/* ------------------------------ */
7380    .balign 64
7381.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
7382/* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */
7383    /*
7384     * Execute a "native inline" instruction, using "/range" semantics.
7385     * Same idea as execute-inline, but we get the args differently.
7386     *
7387     * We need to call an InlineOp4Func:
7388     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7389     *
7390     * The first four args are in r0-r3, pointer to return value storage
7391     * is on the stack.  The function's return value is a flag that tells
7392     * us if an exception was thrown.
7393     */
7394    /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */
7395    FETCH(r10, 1)                       @ r10<- BBBB
7396    add     r1, rGLUE, #offGlue_retval  @ r1<- &glue->retval
7397    EXPORT_PC()                         @ can throw
7398    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7399    mov     r0, rINST, lsr #8           @ r0<- AA
7400    str     r1, [sp]                    @ push &glue->retval
7401    bl      .LOP_EXECUTE_INLINE_RANGE_continue        @ make call; will return after
7402    add     sp, sp, #8                  @ pop stack
7403    cmp     r0, #0                      @ test boolean result of inline
7404    beq     common_exceptionThrown      @ returned false, handle exception
7405    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7406    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7407    GOTO_OPCODE(ip)                     @ jump to next instruction
7408
7409/* ------------------------------ */
7410    .balign 64
7411.L_OP_INVOKE_OBJECT_INIT: /* 0xf0 */
7412/* File: armv5te/OP_INVOKE_OBJECT_INIT.S */
7413    /*
7414     * invoke-object-init is a no-op in a "standard" interpreter.
7415     */
7416    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
7417    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
7418    GOTO_OPCODE(ip)                     @ execute it
7419
7420/* ------------------------------ */
7421    .balign 64
7422.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */
7423/* File: armv5te/OP_RETURN_VOID_BARRIER.S */
7424    SMP_DMB_ST
7425    b       common_returnFromMethod
7426
7427/* ------------------------------ */
7428    .balign 64
7429.L_OP_IGET_QUICK: /* 0xf2 */
7430/* File: armv5te/OP_IGET_QUICK.S */
7431    /* For: iget-quick, iget-object-quick */
7432    /* op vA, vB, offset@CCCC */
7433    mov     r2, rINST, lsr #12          @ r2<- B
7434    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7435    FETCH(r1, 1)                        @ r1<- field byte offset
7436    cmp     r3, #0                      @ check object for null
7437    mov     r2, rINST, lsr #8           @ r2<- A(+)
7438    beq     common_errNullObject        @ object was null
7439    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7440    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7441    and     r2, r2, #15
7442    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7443    SET_VREG(r0, r2)                    @ fp[A]<- r0
7444    GOTO_OPCODE(ip)                     @ jump to next instruction
7445
7446/* ------------------------------ */
7447    .balign 64
7448.L_OP_IGET_WIDE_QUICK: /* 0xf3 */
7449/* File: armv5te/OP_IGET_WIDE_QUICK.S */
7450    /* iget-wide-quick vA, vB, offset@CCCC */
7451    mov     r2, rINST, lsr #12          @ r2<- B
7452    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7453    FETCH(ip, 1)                        @ ip<- field byte offset
7454    cmp     r3, #0                      @ check object for null
7455    mov     r2, rINST, lsr #8           @ r2<- A(+)
7456    beq     common_errNullObject        @ object was null
7457    ldrd    r0, [r3, ip]                @ r0<- obj.field (64 bits, aligned)
7458    and     r2, r2, #15
7459    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7460    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
7461    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7462    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
7463    GOTO_OPCODE(ip)                     @ jump to next instruction
7464
7465/* ------------------------------ */
7466    .balign 64
7467.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */
7468/* File: armv5te/OP_IGET_OBJECT_QUICK.S */
7469/* File: armv5te/OP_IGET_QUICK.S */
7470    /* For: iget-quick, iget-object-quick */
7471    /* op vA, vB, offset@CCCC */
7472    mov     r2, rINST, lsr #12          @ r2<- B
7473    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7474    FETCH(r1, 1)                        @ r1<- field byte offset
7475    cmp     r3, #0                      @ check object for null
7476    mov     r2, rINST, lsr #8           @ r2<- A(+)
7477    beq     common_errNullObject        @ object was null
7478    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7479    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7480    and     r2, r2, #15
7481    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7482    SET_VREG(r0, r2)                    @ fp[A]<- r0
7483    GOTO_OPCODE(ip)                     @ jump to next instruction
7484
7485
7486/* ------------------------------ */
7487    .balign 64
7488.L_OP_IPUT_QUICK: /* 0xf5 */
7489/* File: armv5te/OP_IPUT_QUICK.S */
7490    /* For: iput-quick */
7491    /* op vA, vB, offset@CCCC */
7492    mov     r2, rINST, lsr #12          @ r2<- B
7493    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7494    FETCH(r1, 1)                        @ r1<- field byte offset
7495    cmp     r3, #0                      @ check object for null
7496    mov     r2, rINST, lsr #8           @ r2<- A(+)
7497    beq     common_errNullObject        @ object was null
7498    and     r2, r2, #15
7499    GET_VREG(r0, r2)                    @ r0<- fp[A]
7500    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7501    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7502    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7503    GOTO_OPCODE(ip)                     @ jump to next instruction
7504
7505/* ------------------------------ */
7506    .balign 64
7507.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */
7508/* File: armv5te/OP_IPUT_WIDE_QUICK.S */
7509    /* iput-wide-quick vA, vB, offset@CCCC */
7510    mov     r0, rINST, lsr #8           @ r0<- A(+)
7511    mov     r1, rINST, lsr #12          @ r1<- B
7512    and     r0, r0, #15
7513    GET_VREG(r2, r1)                    @ r2<- fp[B], the object pointer
7514    add     r3, rFP, r0, lsl #2         @ r3<- &fp[A]
7515    cmp     r2, #0                      @ check object for null
7516    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[A]
7517    beq     common_errNullObject        @ object was null
7518    FETCH(r3, 1)                        @ r3<- field byte offset
7519    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7520    strd    r0, [r2, r3]                @ obj.field (64 bits, aligned)<- r0/r1
7521    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7522    GOTO_OPCODE(ip)                     @ jump to next instruction
7523
7524/* ------------------------------ */
7525    .balign 64
7526.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
7527/* File: armv5te/OP_IPUT_OBJECT_QUICK.S */
7528    /* For: iput-object-quick */
7529    /* op vA, vB, offset@CCCC */
7530    mov     r2, rINST, lsr #12          @ r2<- B
7531    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7532    FETCH(r1, 1)                        @ r1<- field byte offset
7533    cmp     r3, #0                      @ check object for null
7534    mov     r2, rINST, lsr #8           @ r2<- A(+)
7535    beq     common_errNullObject        @ object was null
7536    and     r2, r2, #15
7537    GET_VREG(r0, r2)                    @ r0<- fp[A]
7538    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
7539    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7540    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7541    cmp     r0, #0
7542    strneb  r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head
7543    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7544    GOTO_OPCODE(ip)                     @ jump to next instruction
7545
7546/* ------------------------------ */
7547    .balign 64
7548.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
7549/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7550    /*
7551     * Handle an optimized virtual method call.
7552     *
7553     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7554     */
7555    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7556    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7557    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7558    FETCH(r1, 1)                        @ r1<- BBBB
7559    .if     (!0)
7560    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7561    .endif
7562    GET_VREG(r2, r3)                    @ r2<- vC ("this" ptr)
7563    cmp     r2, #0                      @ is "this" null?
7564    beq     common_errNullObject        @ null "this", throw exception
7565    ldr     r2, [r2, #offObject_clazz]  @ r2<- thisPtr->clazz
7566    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7567    EXPORT_PC()                         @ invoke must export
7568    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7569    bl      common_invokeMethodNoRange @ continue on
7570
7571/* ------------------------------ */
7572    .balign 64
7573.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
7574/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */
7575/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7576    /*
7577     * Handle an optimized virtual method call.
7578     *
7579     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7580     */
7581    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7582    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7583    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7584    FETCH(r1, 1)                        @ r1<- BBBB
7585    .if     (!1)
7586    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7587    .endif
7588    GET_VREG(r2, r3)                    @ r2<- vC ("this" ptr)
7589    cmp     r2, #0                      @ is "this" null?
7590    beq     common_errNullObject        @ null "this", throw exception
7591    ldr     r2, [r2, #offObject_clazz]  @ r2<- thisPtr->clazz
7592    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7593    EXPORT_PC()                         @ invoke must export
7594    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7595    bl      common_invokeMethodRange @ continue on
7596
7597
7598/* ------------------------------ */
7599    .balign 64
7600.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */
7601/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7602    /*
7603     * Handle an optimized "super" method call.
7604     *
7605     * for: [opt] invoke-super-quick, invoke-super-quick/range
7606     */
7607    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7608    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7609    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7610    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7611    .if     (!0)
7612    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7613    .endif
7614    FETCH(r1, 1)                        @ r1<- BBBB
7615    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7616    EXPORT_PC()                         @ must export for invoke
7617    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7618    GET_VREG(r3, r10)                   @ r3<- "this"
7619    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7620    cmp     r3, #0                      @ null "this" ref?
7621    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7622    beq     common_errNullObject        @ "this" is null, throw exception
7623    bl      common_invokeMethodNoRange @ continue on
7624
7625/* ------------------------------ */
7626    .balign 64
7627.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
7628/* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */
7629/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7630    /*
7631     * Handle an optimized "super" method call.
7632     *
7633     * for: [opt] invoke-super-quick, invoke-super-quick/range
7634     */
7635    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7636    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7637    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7638    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7639    .if     (!1)
7640    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7641    .endif
7642    FETCH(r1, 1)                        @ r1<- BBBB
7643    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7644    EXPORT_PC()                         @ must export for invoke
7645    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7646    GET_VREG(r3, r10)                   @ r3<- "this"
7647    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7648    cmp     r3, #0                      @ null "this" ref?
7649    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7650    beq     common_errNullObject        @ "this" is null, throw exception
7651    bl      common_invokeMethodRange @ continue on
7652
7653
7654/* ------------------------------ */
7655    .balign 64
7656.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
7657/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */
7658/* File: armv5te/OP_IPUT_OBJECT.S */
7659    /*
7660     * 32-bit instance field put.
7661     *
7662     * for: iput-object, iput-object-volatile
7663     */
7664    /* op vA, vB, field@CCCC */
7665    mov     r0, rINST, lsr #12          @ r0<- B
7666    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7667    FETCH(r1, 1)                        @ r1<- field ref CCCC
7668    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7669    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7670    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7671    cmp     r0, #0                      @ is resolved entry null?
7672    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ no, already resolved
76738:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7674    EXPORT_PC()                         @ resolve() could throw
7675    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7676    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7677    cmp     r0, #0                      @ success?
7678    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ yes, finish up
7679    b       common_exceptionThrown
7680
7681
7682/* ------------------------------ */
7683    .balign 64
7684.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
7685/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */
7686/* File: armv5te/OP_SGET.S */
7687    /*
7688     * General 32-bit SGET handler.
7689     *
7690     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7691     */
7692    /* op vAA, field@BBBB */
7693    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7694    FETCH(r1, 1)                        @ r1<- field ref BBBB
7695    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7696    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7697    cmp     r0, #0                      @ is resolved entry null?
7698    beq     .LOP_SGET_OBJECT_VOLATILE_resolve         @ yes, do resolve
7699.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0
7700    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7701    SMP_DMB                            @ acquiring load
7702    mov     r2, rINST, lsr #8           @ r2<- AA
7703    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7704    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7705    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7706    GOTO_OPCODE(ip)                     @ jump to next instruction
7707
7708
7709/* ------------------------------ */
7710    .balign 64
7711.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
7712/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */
7713/* File: armv5te/OP_SPUT_OBJECT.S */
7714    /*
7715     * 32-bit SPUT handler for objects
7716     *
7717     * for: sput-object, sput-object-volatile
7718     */
7719    /* op vAA, field@BBBB */
7720    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7721    FETCH(r1, 1)                        @ r1<- field ref BBBB
7722    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7723    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7724    cmp     r0, #0                      @ is resolved entry null?
7725    bne     .LOP_SPUT_OBJECT_VOLATILE_finish          @ no, continue
7726    ldr     r9, [rGLUE, #offGlue_method]    @ r9<- current method
7727    EXPORT_PC()                         @ resolve() could throw, so export now
7728    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
7729    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
7730    cmp     r0, #0                      @ success?
7731    bne     .LOP_SPUT_OBJECT_VOLATILE_finish          @ yes, finish
7732    b       common_exceptionThrown      @ no, handle exception
7733
7734
7735
7736/* ------------------------------ */
7737    .balign 64
7738.L_OP_DISPATCH_FF: /* 0xff */
7739/* File: armv5te/OP_DISPATCH_FF.S */
7740    mov     ip, rINST, lsr #8           @ r9<- extended opcode
7741    add     ip, ip, #256                @ add offset for extended opcodes
7742    GOTO_OPCODE(ip)                     @ go to proper extended handler
7743
7744
7745/* ------------------------------ */
7746    .balign 64
7747.L_OP_CONST_CLASS_JUMBO: /* 0x100 */
7748/* File: armv5te/OP_CONST_CLASS_JUMBO.S */
7749    /* const-class/jumbo vBBBB, Class@AAAAAAAA */
7750    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7751    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- glue->methodClassDex
7752    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7753    ldr     r2, [r2, #offDvmDex_pResClasses]   @ r2<- dvmDex->pResClasses
7754    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7755    FETCH(r9, 3)                        @ r9<- BBBB
7756    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResClasses[AAAAaaaa]
7757    cmp     r0, #0                      @ not yet resolved?
7758    beq     .LOP_CONST_CLASS_JUMBO_resolve
7759    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
7760    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7761    SET_VREG(r0, r9)                    @ vBBBB<- r0
7762    GOTO_OPCODE(ip)                     @ jump to next instruction
7763
7764/* ------------------------------ */
7765    .balign 64
7766.L_OP_CHECK_CAST_JUMBO: /* 0x101 */
7767/* File: armv5te/OP_CHECK_CAST_JUMBO.S */
7768    /*
7769     * Check to see if a cast from one class to another is allowed.
7770     */
7771    /* check-cast/jumbo vBBBB, class@AAAAAAAA */
7772    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7773    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7774    FETCH(r3, 3)                        @ r3<- BBBB
7775    orr     r2, r0, r2, lsl #16         @ r2<- AAAAaaaa
7776    GET_VREG(r9, r3)                    @ r9<- object
7777    ldr     r0, [rGLUE, #offGlue_methodClassDex]    @ r0<- pDvmDex
7778    cmp     r9, #0                      @ is object null?
7779    ldr     r0, [r0, #offDvmDex_pResClasses]    @ r0<- pDvmDex->pResClasses
7780    beq     .LOP_CHECK_CAST_JUMBO_okay            @ null obj, cast always succeeds
7781    ldr     r1, [r0, r2, lsl #2]        @ r1<- resolved class
7782    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
7783    cmp     r1, #0                      @ have we resolved this before?
7784    beq     .LOP_CHECK_CAST_JUMBO_resolve         @ not resolved, do it now
7785.LOP_CHECK_CAST_JUMBO_resolved:
7786    cmp     r0, r1                      @ same class (trivial success)?
7787    bne     .LOP_CHECK_CAST_JUMBO_fullcheck       @ no, do full check
7788    b       .LOP_CHECK_CAST_JUMBO_okay            @ yes, finish up
7789
7790/* ------------------------------ */
7791    .balign 64
7792.L_OP_INSTANCE_OF_JUMBO: /* 0x102 */
7793/* File: armv5te/OP_INSTANCE_OF_JUMBO.S */
7794    /*
7795     * Check to see if an object reference is an instance of a class.
7796     *
7797     * Most common situation is a non-null object, being compared against
7798     * an already-resolved class.
7799     *
7800     * TODO: convert most of this into a common subroutine, shared with
7801     *       OP_INSTANCE_OF.S.
7802     */
7803    /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */
7804    FETCH(r3, 4)                        @ r3<- vCCCC
7805    FETCH(r9, 3)                        @ r9<- vBBBB
7806    GET_VREG(r0, r3)                    @ r0<- vCCCC (object)
7807    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- pDvmDex
7808    cmp     r0, #0                      @ is object null?
7809    beq     .LOP_INSTANCE_OF_JUMBO_store           @ null obj, not an instance, store r0
7810    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7811    FETCH(r3, 2)                        @ r3<- AAAA (hi)
7812    ldr     r2, [r2, #offDvmDex_pResClasses]    @ r2<- pDvmDex->pResClasses
7813    orr     r3, r1, r3, lsl #16         @ r3<- AAAAaaaa
7814    ldr     r1, [r2, r3, lsl #2]        @ r1<- resolved class
7815    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
7816    cmp     r1, #0                      @ have we resolved this before?
7817    beq     .LOP_INSTANCE_OF_JUMBO_resolve         @ not resolved, do it now
7818    b       .LOP_INSTANCE_OF_JUMBO_resolved        @ resolved, continue
7819
7820/* ------------------------------ */
7821    .balign 64
7822.L_OP_NEW_INSTANCE_JUMBO: /* 0x103 */
7823/* File: armv5te/OP_NEW_INSTANCE_JUMBO.S */
7824    /*
7825     * Create a new instance of a class.
7826     */
7827    /* new-instance/jumbo vBBBB, class@AAAAAAAA */
7828    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7829    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7830    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
7831    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7832    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7833    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
7834    EXPORT_PC()                         @ req'd for init, resolve, alloc
7835    cmp     r0, #0                      @ already resolved?
7836    beq     .LOP_NEW_INSTANCE_JUMBO_resolve         @ no, resolve it now
7837.LOP_NEW_INSTANCE_JUMBO_resolved:   @ r0=class
7838    ldrb    r1, [r0, #offClassObject_status]    @ r1<- ClassStatus enum
7839    cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
7840    bne     .LOP_NEW_INSTANCE_JUMBO_needinit        @ no, init class now
7841.LOP_NEW_INSTANCE_JUMBO_initialized: @ r0=class
7842    mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
7843    bl      dvmAllocObject              @ r0<- new object
7844    b       .LOP_NEW_INSTANCE_JUMBO_finish          @ continue
7845
7846/* ------------------------------ */
7847    .balign 64
7848.L_OP_NEW_ARRAY_JUMBO: /* 0x104 */
7849/* File: armv5te/OP_NEW_ARRAY_JUMBO.S */
7850    /*
7851     * Allocate an array of objects, specified with the array class
7852     * and a count.
7853     *
7854     * The verifier guarantees that this is an array class, so we don't
7855     * check for it here.
7856     */
7857    /* new-array/jumbo vBBBB, vCCCC, class@AAAAAAAA */
7858    FETCH(r2, 1)                        @ r2<- aaaa (lo)
7859    FETCH(r3, 2)                        @ r3<- AAAA (hi)
7860    FETCH(r0, 4)                        @ r0<- vCCCC
7861    orr     r2, r2, r3, lsl #16         @ r2<- AAAAaaaa
7862    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
7863    GET_VREG(r1, r0)                    @ r1<- vCCCC (array length)
7864    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7865    cmp     r1, #0                      @ check length
7866    ldr     r0, [r3, r2, lsl #2]        @ r0<- resolved class
7867    bmi     common_errNegativeArraySize @ negative length, bail
7868    cmp     r0, #0                      @ already resolved?
7869    EXPORT_PC()                         @ req'd for resolve, alloc
7870    bne     .LOP_NEW_ARRAY_JUMBO_finish          @ resolved, continue
7871    b       .LOP_NEW_ARRAY_JUMBO_resolve         @ do resolve now
7872
7873/* ------------------------------ */
7874    .balign 64
7875.L_OP_FILLED_NEW_ARRAY_JUMBO: /* 0x105 */
7876/* File: armv5te/OP_FILLED_NEW_ARRAY_JUMBO.S */
7877    /*
7878     * Create a new array with elements filled from registers.
7879     *
7880     * TODO: convert most of this into a common subroutine, shared with
7881     *       OP_FILLED_NEW_ARRAY.S.
7882     */
7883    /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */
7884    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
7885    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7886    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7887    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7888    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7889    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
7890    EXPORT_PC()                         @ need for resolve and alloc
7891    cmp     r0, #0                      @ already resolved?
7892    bne     .LOP_FILLED_NEW_ARRAY_JUMBO_continue        @ yes, continue on
78938:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
7894    mov     r2, #0                      @ r2<- false
7895    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
7896    bl      dvmResolveClass             @ r0<- call(clazz, ref)
7897    cmp     r0, #0                      @ got null?
7898    beq     common_exceptionThrown      @ yes, handle exception
7899    b       .LOP_FILLED_NEW_ARRAY_JUMBO_continue
7900
7901/* ------------------------------ */
7902    .balign 64
7903.L_OP_IGET_JUMBO: /* 0x106 */
7904/* File: armv5te/OP_IGET_JUMBO.S */
7905    /*
7906     * Jumbo 32-bit instance field get.
7907     *
7908     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7909     *      iget-char/jumbo, iget-short/jumbo
7910     */
7911    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7912    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7913    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7914    FETCH(r0, 4)                        @ r0<- CCCC
7915    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7916    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7917    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7918    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7919    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7920    cmp     r0, #0                      @ is resolved entry null?
7921    bne     .LOP_IGET_JUMBO_finish          @ no, already resolved
79228:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7923    EXPORT_PC()                         @ resolve() could throw
7924    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7925    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7926    b       .LOP_IGET_JUMBO_resolved        @ resolved, continue
7927
7928/* ------------------------------ */
7929    .balign 64
7930.L_OP_IGET_WIDE_JUMBO: /* 0x107 */
7931/* File: armv5te/OP_IGET_WIDE_JUMBO.S */
7932    /*
7933     * Jumbo 64-bit instance field get.
7934     */
7935    /* iget-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
7936    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7937    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7938    FETCH(r0, 4)                        @ r0<- CCCC
7939    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7940    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7941    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7942    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7943    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7944    cmp     r0, #0                      @ is resolved entry null?
7945    bne     .LOP_IGET_WIDE_JUMBO_finish          @ no, already resolved
79468:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
7947    EXPORT_PC()                         @ resolve() could throw
7948    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7949    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7950    b       .LOP_IGET_WIDE_JUMBO_resolved        @ resolved, continue
7951
7952/* ------------------------------ */
7953    .balign 64
7954.L_OP_IGET_OBJECT_JUMBO: /* 0x108 */
7955/* File: armv5te/OP_IGET_OBJECT_JUMBO.S */
7956/* File: armv5te/OP_IGET_JUMBO.S */
7957    /*
7958     * Jumbo 32-bit instance field get.
7959     *
7960     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7961     *      iget-char/jumbo, iget-short/jumbo
7962     */
7963    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7964    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7965    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7966    FETCH(r0, 4)                        @ r0<- CCCC
7967    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7968    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7969    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7970    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7971    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7972    cmp     r0, #0                      @ is resolved entry null?
7973    bne     .LOP_IGET_OBJECT_JUMBO_finish          @ no, already resolved
79748:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7975    EXPORT_PC()                         @ resolve() could throw
7976    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7977    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7978    b       .LOP_IGET_OBJECT_JUMBO_resolved        @ resolved, continue
7979
7980
7981/* ------------------------------ */
7982    .balign 64
7983.L_OP_IGET_BOOLEAN_JUMBO: /* 0x109 */
7984/* File: armv5te/OP_IGET_BOOLEAN_JUMBO.S */
7985@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrb", "sqnum":"1" }
7986/* File: armv5te/OP_IGET_JUMBO.S */
7987    /*
7988     * Jumbo 32-bit instance field get.
7989     *
7990     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7991     *      iget-char/jumbo, iget-short/jumbo
7992     */
7993    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7994    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7995    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7996    FETCH(r0, 4)                        @ r0<- CCCC
7997    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7998    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7999    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8000    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8001    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8002    cmp     r0, #0                      @ is resolved entry null?
8003    bne     .LOP_IGET_BOOLEAN_JUMBO_finish          @ no, already resolved
80048:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8005    EXPORT_PC()                         @ resolve() could throw
8006    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8007    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8008    b       .LOP_IGET_BOOLEAN_JUMBO_resolved        @ resolved, continue
8009
8010
8011/* ------------------------------ */
8012    .balign 64
8013.L_OP_IGET_BYTE_JUMBO: /* 0x10a */
8014/* File: armv5te/OP_IGET_BYTE_JUMBO.S */
8015@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsb", "sqnum":"2" }
8016/* File: armv5te/OP_IGET_JUMBO.S */
8017    /*
8018     * Jumbo 32-bit instance field get.
8019     *
8020     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8021     *      iget-char/jumbo, iget-short/jumbo
8022     */
8023    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8024    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8025    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8026    FETCH(r0, 4)                        @ r0<- CCCC
8027    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8028    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8029    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8030    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8031    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8032    cmp     r0, #0                      @ is resolved entry null?
8033    bne     .LOP_IGET_BYTE_JUMBO_finish          @ no, already resolved
80348:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8035    EXPORT_PC()                         @ resolve() could throw
8036    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8037    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8038    b       .LOP_IGET_BYTE_JUMBO_resolved        @ resolved, continue
8039
8040
8041/* ------------------------------ */
8042    .balign 64
8043.L_OP_IGET_CHAR_JUMBO: /* 0x10b */
8044/* File: armv5te/OP_IGET_CHAR_JUMBO.S */
8045@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrh", "sqnum":"3" }
8046/* File: armv5te/OP_IGET_JUMBO.S */
8047    /*
8048     * Jumbo 32-bit instance field get.
8049     *
8050     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8051     *      iget-char/jumbo, iget-short/jumbo
8052     */
8053    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8054    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8055    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8056    FETCH(r0, 4)                        @ r0<- CCCC
8057    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8058    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8059    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8060    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8061    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8062    cmp     r0, #0                      @ is resolved entry null?
8063    bne     .LOP_IGET_CHAR_JUMBO_finish          @ no, already resolved
80648:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8065    EXPORT_PC()                         @ resolve() could throw
8066    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8067    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8068    b       .LOP_IGET_CHAR_JUMBO_resolved        @ resolved, continue
8069
8070
8071/* ------------------------------ */
8072    .balign 64
8073.L_OP_IGET_SHORT_JUMBO: /* 0x10c */
8074/* File: armv5te/OP_IGET_SHORT_JUMBO.S */
8075@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsh", "sqnum":"4" }
8076/* File: armv5te/OP_IGET_JUMBO.S */
8077    /*
8078     * Jumbo 32-bit instance field get.
8079     *
8080     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8081     *      iget-char/jumbo, iget-short/jumbo
8082     */
8083    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8084    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8085    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8086    FETCH(r0, 4)                        @ r0<- CCCC
8087    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8088    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8089    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8090    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8091    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8092    cmp     r0, #0                      @ is resolved entry null?
8093    bne     .LOP_IGET_SHORT_JUMBO_finish          @ no, already resolved
80948:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8095    EXPORT_PC()                         @ resolve() could throw
8096    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8097    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8098    b       .LOP_IGET_SHORT_JUMBO_resolved        @ resolved, continue
8099
8100
8101/* ------------------------------ */
8102    .balign 64
8103.L_OP_IPUT_JUMBO: /* 0x10d */
8104/* File: armv5te/OP_IPUT_JUMBO.S */
8105    /*
8106     * Jumbo 32-bit instance field put.
8107     *
8108     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8109     *      iput-short/jumbo
8110     */
8111    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8112    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8113    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8114    FETCH(r0, 4)                        @ r0<- CCCC
8115    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8116    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8117    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8118    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8119    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8120    cmp     r0, #0                      @ is resolved entry null?
8121    bne     .LOP_IPUT_JUMBO_finish          @ no, already resolved
81228:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8123    EXPORT_PC()                         @ resolve() could throw
8124    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8125    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8126    b       .LOP_IPUT_JUMBO_resolved        @ resolved, continue
8127
8128/* ------------------------------ */
8129    .balign 64
8130.L_OP_IPUT_WIDE_JUMBO: /* 0x10e */
8131/* File: armv5te/OP_IPUT_WIDE_JUMBO.S */
8132    /* iput-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
8133    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8134    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8135    FETCH(r0, 4)                        @ r0<- CCCC
8136    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8137    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8138    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
8139    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
8140    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8141    cmp     r0, #0                      @ is resolved entry null?
8142    bne     .LOP_IPUT_WIDE_JUMBO_finish          @ no, already resolved
81438:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
8144    EXPORT_PC()                         @ resolve() could throw
8145    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8146    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8147    b       .LOP_IPUT_WIDE_JUMBO_resolved        @ resolved, continue
8148
8149/* ------------------------------ */
8150    .balign 64
8151.L_OP_IPUT_OBJECT_JUMBO: /* 0x10f */
8152/* File: armv5te/OP_IPUT_OBJECT_JUMBO.S */
8153    /*
8154     * Jumbo 32-bit instance field put.
8155     */
8156    /* iput-object/jumbo vBBBB, vCCCC, field@AAAAAAAA */
8157    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8158    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8159    FETCH(r0, 4)                        @ r0<- CCCC
8160    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8161    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8162    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8163    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8164    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8165    cmp     r0, #0                      @ is resolved entry null?
8166    bne     .LOP_IPUT_OBJECT_JUMBO_finish          @ no, already resolved
81678:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8168    EXPORT_PC()                         @ resolve() could throw
8169    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8170    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8171    b       .LOP_IPUT_OBJECT_JUMBO_resolved        @ resolved, continue
8172
8173/* ------------------------------ */
8174    .balign 64
8175.L_OP_IPUT_BOOLEAN_JUMBO: /* 0x110 */
8176/* File: armv5te/OP_IPUT_BOOLEAN_JUMBO.S */
8177@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"1" }
8178/* File: armv5te/OP_IPUT_JUMBO.S */
8179    /*
8180     * Jumbo 32-bit instance field put.
8181     *
8182     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8183     *      iput-short/jumbo
8184     */
8185    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8186    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8187    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8188    FETCH(r0, 4)                        @ r0<- CCCC
8189    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8190    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8191    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8192    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8193    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8194    cmp     r0, #0                      @ is resolved entry null?
8195    bne     .LOP_IPUT_BOOLEAN_JUMBO_finish          @ no, already resolved
81968:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8197    EXPORT_PC()                         @ resolve() could throw
8198    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8199    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8200    b       .LOP_IPUT_BOOLEAN_JUMBO_resolved        @ resolved, continue
8201
8202
8203/* ------------------------------ */
8204    .balign 64
8205.L_OP_IPUT_BYTE_JUMBO: /* 0x111 */
8206/* File: armv5te/OP_IPUT_BYTE_JUMBO.S */
8207@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"2" }
8208/* File: armv5te/OP_IPUT_JUMBO.S */
8209    /*
8210     * Jumbo 32-bit instance field put.
8211     *
8212     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8213     *      iput-short/jumbo
8214     */
8215    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8216    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8217    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8218    FETCH(r0, 4)                        @ r0<- CCCC
8219    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8220    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8221    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8222    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8223    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8224    cmp     r0, #0                      @ is resolved entry null?
8225    bne     .LOP_IPUT_BYTE_JUMBO_finish          @ no, already resolved
82268:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8227    EXPORT_PC()                         @ resolve() could throw
8228    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8229    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8230    b       .LOP_IPUT_BYTE_JUMBO_resolved        @ resolved, continue
8231
8232
8233/* ------------------------------ */
8234    .balign 64
8235.L_OP_IPUT_CHAR_JUMBO: /* 0x112 */
8236/* File: armv5te/OP_IPUT_CHAR_JUMBO.S */
8237@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"3" }
8238/* File: armv5te/OP_IPUT_JUMBO.S */
8239    /*
8240     * Jumbo 32-bit instance field put.
8241     *
8242     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8243     *      iput-short/jumbo
8244     */
8245    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8246    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8247    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8248    FETCH(r0, 4)                        @ r0<- CCCC
8249    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8250    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8251    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8252    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8253    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8254    cmp     r0, #0                      @ is resolved entry null?
8255    bne     .LOP_IPUT_CHAR_JUMBO_finish          @ no, already resolved
82568:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8257    EXPORT_PC()                         @ resolve() could throw
8258    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8259    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8260    b       .LOP_IPUT_CHAR_JUMBO_resolved        @ resolved, continue
8261
8262
8263/* ------------------------------ */
8264    .balign 64
8265.L_OP_IPUT_SHORT_JUMBO: /* 0x113 */
8266/* File: armv5te/OP_IPUT_SHORT_JUMBO.S */
8267@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"4" }
8268/* File: armv5te/OP_IPUT_JUMBO.S */
8269    /*
8270     * Jumbo 32-bit instance field put.
8271     *
8272     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8273     *      iput-short/jumbo
8274     */
8275    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8276    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8277    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8278    FETCH(r0, 4)                        @ r0<- CCCC
8279    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8280    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8281    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8282    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8283    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8284    cmp     r0, #0                      @ is resolved entry null?
8285    bne     .LOP_IPUT_SHORT_JUMBO_finish          @ no, already resolved
82868:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8287    EXPORT_PC()                         @ resolve() could throw
8288    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8289    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8290    b       .LOP_IPUT_SHORT_JUMBO_resolved        @ resolved, continue
8291
8292
8293/* ------------------------------ */
8294    .balign 64
8295.L_OP_SGET_JUMBO: /* 0x114 */
8296/* File: armv5te/OP_SGET_JUMBO.S */
8297    /*
8298     * Jumbo 32-bit SGET handler.
8299     *
8300     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8301     *      sget-char/jumbo, sget-short/jumbo
8302     */
8303    /* exop vBBBB, field@AAAAAAAA */
8304    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8305    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8306    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8307    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8308    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8309    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8310    cmp     r0, #0                      @ is resolved entry null?
8311    beq     .LOP_SGET_JUMBO_resolve         @ yes, do resolve
8312.LOP_SGET_JUMBO_finish: @ field ptr in r0
8313    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8314    @ no-op                             @ acquiring load
8315    FETCH(r2, 3)                        @ r2<- BBBB
8316    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8317    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8318    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8319    GOTO_OPCODE(ip)                     @ jump to next instruction
8320
8321/* ------------------------------ */
8322    .balign 64
8323.L_OP_SGET_WIDE_JUMBO: /* 0x115 */
8324/* File: armv5te/OP_SGET_WIDE_JUMBO.S */
8325    /*
8326     * Jumbo 64-bit SGET handler.
8327     */
8328    /* sget-wide/jumbo vBBBB, field@AAAAAAAA */
8329    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8330    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8331    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8332    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8333    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8334    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8335    cmp     r0, #0                      @ is resolved entry null?
8336    beq     .LOP_SGET_WIDE_JUMBO_resolve         @ yes, do resolve
8337.LOP_SGET_WIDE_JUMBO_finish:
8338    FETCH(r9, 3)                        @ r9<- BBBB
8339    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
8340    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BBBB]
8341    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8342    stmia   r9, {r0-r1}                 @ vBBBB/vBBBB+1<- r0/r1
8343    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8344    GOTO_OPCODE(ip)                     @ jump to next instruction
8345
8346/* ------------------------------ */
8347    .balign 64
8348.L_OP_SGET_OBJECT_JUMBO: /* 0x116 */
8349/* File: armv5te/OP_SGET_OBJECT_JUMBO.S */
8350/* File: armv5te/OP_SGET_JUMBO.S */
8351    /*
8352     * Jumbo 32-bit SGET handler.
8353     *
8354     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8355     *      sget-char/jumbo, sget-short/jumbo
8356     */
8357    /* exop vBBBB, field@AAAAAAAA */
8358    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8359    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8360    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8361    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8362    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8363    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8364    cmp     r0, #0                      @ is resolved entry null?
8365    beq     .LOP_SGET_OBJECT_JUMBO_resolve         @ yes, do resolve
8366.LOP_SGET_OBJECT_JUMBO_finish: @ field ptr in r0
8367    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8368    @ no-op                             @ acquiring load
8369    FETCH(r2, 3)                        @ r2<- BBBB
8370    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8371    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8372    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8373    GOTO_OPCODE(ip)                     @ jump to next instruction
8374
8375
8376/* ------------------------------ */
8377    .balign 64
8378.L_OP_SGET_BOOLEAN_JUMBO: /* 0x117 */
8379/* File: armv5te/OP_SGET_BOOLEAN_JUMBO.S */
8380/* File: armv5te/OP_SGET_JUMBO.S */
8381    /*
8382     * Jumbo 32-bit SGET handler.
8383     *
8384     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8385     *      sget-char/jumbo, sget-short/jumbo
8386     */
8387    /* exop vBBBB, field@AAAAAAAA */
8388    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8389    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8390    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8391    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8392    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8393    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8394    cmp     r0, #0                      @ is resolved entry null?
8395    beq     .LOP_SGET_BOOLEAN_JUMBO_resolve         @ yes, do resolve
8396.LOP_SGET_BOOLEAN_JUMBO_finish: @ field ptr in r0
8397    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8398    @ no-op                             @ acquiring load
8399    FETCH(r2, 3)                        @ r2<- BBBB
8400    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8401    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8402    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8403    GOTO_OPCODE(ip)                     @ jump to next instruction
8404
8405
8406/* ------------------------------ */
8407    .balign 64
8408.L_OP_SGET_BYTE_JUMBO: /* 0x118 */
8409/* File: armv5te/OP_SGET_BYTE_JUMBO.S */
8410/* File: armv5te/OP_SGET_JUMBO.S */
8411    /*
8412     * Jumbo 32-bit SGET handler.
8413     *
8414     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8415     *      sget-char/jumbo, sget-short/jumbo
8416     */
8417    /* exop vBBBB, field@AAAAAAAA */
8418    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8419    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8420    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8421    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8422    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8423    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8424    cmp     r0, #0                      @ is resolved entry null?
8425    beq     .LOP_SGET_BYTE_JUMBO_resolve         @ yes, do resolve
8426.LOP_SGET_BYTE_JUMBO_finish: @ field ptr in r0
8427    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8428    @ no-op                             @ acquiring load
8429    FETCH(r2, 3)                        @ r2<- BBBB
8430    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8431    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8432    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8433    GOTO_OPCODE(ip)                     @ jump to next instruction
8434
8435
8436/* ------------------------------ */
8437    .balign 64
8438.L_OP_SGET_CHAR_JUMBO: /* 0x119 */
8439/* File: armv5te/OP_SGET_CHAR_JUMBO.S */
8440/* File: armv5te/OP_SGET_JUMBO.S */
8441    /*
8442     * Jumbo 32-bit SGET handler.
8443     *
8444     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8445     *      sget-char/jumbo, sget-short/jumbo
8446     */
8447    /* exop vBBBB, field@AAAAAAAA */
8448    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8449    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8450    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8451    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8452    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8453    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8454    cmp     r0, #0                      @ is resolved entry null?
8455    beq     .LOP_SGET_CHAR_JUMBO_resolve         @ yes, do resolve
8456.LOP_SGET_CHAR_JUMBO_finish: @ field ptr in r0
8457    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8458    @ no-op                             @ acquiring load
8459    FETCH(r2, 3)                        @ r2<- BBBB
8460    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8461    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8462    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8463    GOTO_OPCODE(ip)                     @ jump to next instruction
8464
8465
8466/* ------------------------------ */
8467    .balign 64
8468.L_OP_SGET_SHORT_JUMBO: /* 0x11a */
8469/* File: armv5te/OP_SGET_SHORT_JUMBO.S */
8470/* File: armv5te/OP_SGET_JUMBO.S */
8471    /*
8472     * Jumbo 32-bit SGET handler.
8473     *
8474     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8475     *      sget-char/jumbo, sget-short/jumbo
8476     */
8477    /* exop vBBBB, field@AAAAAAAA */
8478    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8479    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8480    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8481    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8482    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8483    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8484    cmp     r0, #0                      @ is resolved entry null?
8485    beq     .LOP_SGET_SHORT_JUMBO_resolve         @ yes, do resolve
8486.LOP_SGET_SHORT_JUMBO_finish: @ field ptr in r0
8487    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8488    @ no-op                             @ acquiring load
8489    FETCH(r2, 3)                        @ r2<- BBBB
8490    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8491    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8492    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8493    GOTO_OPCODE(ip)                     @ jump to next instruction
8494
8495
8496/* ------------------------------ */
8497    .balign 64
8498.L_OP_SPUT_JUMBO: /* 0x11b */
8499/* File: armv5te/OP_SPUT_JUMBO.S */
8500    /*
8501     * Jumbo 32-bit SPUT handler.
8502     *
8503     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8504     *      sput-short/jumbo
8505     */
8506    /* exop vBBBB, field@AAAAAAAA */
8507    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8508    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8509    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8510    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8511    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8512    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8513    cmp     r0, #0                      @ is resolved entry null?
8514    beq     .LOP_SPUT_JUMBO_resolve         @ yes, do resolve
8515.LOP_SPUT_JUMBO_finish:   @ field ptr in r0
8516    FETCH(r2, 3)                        @ r2<- BBBB
8517    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8518    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8519    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8520    @ no-op                             @ releasing store
8521    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8522    GOTO_OPCODE(ip)                     @ jump to next instruction
8523
8524/* ------------------------------ */
8525    .balign 64
8526.L_OP_SPUT_WIDE_JUMBO: /* 0x11c */
8527/* File: armv5te/OP_SPUT_WIDE_JUMBO.S */
8528    /*
8529     * Jumbo 64-bit SPUT handler.
8530     */
8531    /* sput-wide/jumbo vBBBB, field@AAAAAAAA */
8532    ldr     r0, [rGLUE, #offGlue_methodClassDex]  @ r0<- DvmDex
8533    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8534    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8535    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
8536    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8537    FETCH(r9, 3)                        @ r9<- BBBB
8538    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
8539    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BBBB]
8540    cmp     r2, #0                      @ is resolved entry null?
8541    beq     .LOP_SPUT_WIDE_JUMBO_resolve         @ yes, do resolve
8542.LOP_SPUT_WIDE_JUMBO_finish: @ field ptr in r2, BBBB in r9
8543    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8544    ldmia   r9, {r0-r1}                 @ r0/r1<- vBBBB/vBBBB+1
8545    GET_INST_OPCODE(r10)                @ extract opcode from rINST
8546    strd    r0, [r2, #offStaticField_value] @ field<- vBBBB/vBBBB+1
8547    GOTO_OPCODE(r10)                    @ jump to next instruction
8548
8549/* ------------------------------ */
8550    .balign 64
8551.L_OP_SPUT_OBJECT_JUMBO: /* 0x11d */
8552/* File: armv5te/OP_SPUT_OBJECT_JUMBO.S */
8553    /*
8554     * Jumbo 32-bit SPUT handler for objects
8555     */
8556    /* sput-object/jumbo vBBBB, field@AAAAAAAA */
8557    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8558    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8559    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8560    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8561    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8562    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8563    cmp     r0, #0                      @ is resolved entry null?
8564    bne     .LOP_SPUT_OBJECT_JUMBO_finish          @ no, continue
8565    ldr     r9, [rGLUE, #offGlue_method]    @ r9<- current method
8566    EXPORT_PC()                         @ resolve() could throw, so export now
8567    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
8568    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8569    cmp     r0, #0                      @ success?
8570    bne     .LOP_SPUT_OBJECT_JUMBO_finish          @ yes, finish
8571    b       common_exceptionThrown      @ no, handle exception
8572
8573/* ------------------------------ */
8574    .balign 64
8575.L_OP_SPUT_BOOLEAN_JUMBO: /* 0x11e */
8576/* File: armv5te/OP_SPUT_BOOLEAN_JUMBO.S */
8577/* File: armv5te/OP_SPUT_JUMBO.S */
8578    /*
8579     * Jumbo 32-bit SPUT handler.
8580     *
8581     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8582     *      sput-short/jumbo
8583     */
8584    /* exop vBBBB, field@AAAAAAAA */
8585    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8586    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8587    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8588    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8589    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8590    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8591    cmp     r0, #0                      @ is resolved entry null?
8592    beq     .LOP_SPUT_BOOLEAN_JUMBO_resolve         @ yes, do resolve
8593.LOP_SPUT_BOOLEAN_JUMBO_finish:   @ field ptr in r0
8594    FETCH(r2, 3)                        @ r2<- BBBB
8595    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8596    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8597    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8598    @ no-op                             @ releasing store
8599    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8600    GOTO_OPCODE(ip)                     @ jump to next instruction
8601
8602
8603/* ------------------------------ */
8604    .balign 64
8605.L_OP_SPUT_BYTE_JUMBO: /* 0x11f */
8606/* File: armv5te/OP_SPUT_BYTE_JUMBO.S */
8607/* File: armv5te/OP_SPUT_JUMBO.S */
8608    /*
8609     * Jumbo 32-bit SPUT handler.
8610     *
8611     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8612     *      sput-short/jumbo
8613     */
8614    /* exop vBBBB, field@AAAAAAAA */
8615    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8616    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8617    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8618    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8619    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8620    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8621    cmp     r0, #0                      @ is resolved entry null?
8622    beq     .LOP_SPUT_BYTE_JUMBO_resolve         @ yes, do resolve
8623.LOP_SPUT_BYTE_JUMBO_finish:   @ field ptr in r0
8624    FETCH(r2, 3)                        @ r2<- BBBB
8625    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8626    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8627    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8628    @ no-op                             @ releasing store
8629    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8630    GOTO_OPCODE(ip)                     @ jump to next instruction
8631
8632
8633/* ------------------------------ */
8634    .balign 64
8635.L_OP_SPUT_CHAR_JUMBO: /* 0x120 */
8636/* File: armv5te/OP_SPUT_CHAR_JUMBO.S */
8637/* File: armv5te/OP_SPUT_JUMBO.S */
8638    /*
8639     * Jumbo 32-bit SPUT handler.
8640     *
8641     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8642     *      sput-short/jumbo
8643     */
8644    /* exop vBBBB, field@AAAAAAAA */
8645    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8646    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8647    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8648    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8649    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8650    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8651    cmp     r0, #0                      @ is resolved entry null?
8652    beq     .LOP_SPUT_CHAR_JUMBO_resolve         @ yes, do resolve
8653.LOP_SPUT_CHAR_JUMBO_finish:   @ field ptr in r0
8654    FETCH(r2, 3)                        @ r2<- BBBB
8655    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8656    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8657    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8658    @ no-op                             @ releasing store
8659    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8660    GOTO_OPCODE(ip)                     @ jump to next instruction
8661
8662
8663/* ------------------------------ */
8664    .balign 64
8665.L_OP_SPUT_SHORT_JUMBO: /* 0x121 */
8666/* File: armv5te/OP_SPUT_SHORT_JUMBO.S */
8667/* File: armv5te/OP_SPUT_JUMBO.S */
8668    /*
8669     * Jumbo 32-bit SPUT handler.
8670     *
8671     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8672     *      sput-short/jumbo
8673     */
8674    /* exop vBBBB, field@AAAAAAAA */
8675    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8676    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8677    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8678    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8679    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8680    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8681    cmp     r0, #0                      @ is resolved entry null?
8682    beq     .LOP_SPUT_SHORT_JUMBO_resolve         @ yes, do resolve
8683.LOP_SPUT_SHORT_JUMBO_finish:   @ field ptr in r0
8684    FETCH(r2, 3)                        @ r2<- BBBB
8685    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8686    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8687    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8688    @ no-op                             @ releasing store
8689    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8690    GOTO_OPCODE(ip)                     @ jump to next instruction
8691
8692
8693/* ------------------------------ */
8694    .balign 64
8695.L_OP_INVOKE_VIRTUAL_JUMBO: /* 0x122 */
8696/* File: armv5te/OP_INVOKE_VIRTUAL_JUMBO.S */
8697    /*
8698     * Handle a virtual method call.
8699     */
8700    /* invoke-virtual/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8701    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8702    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8703    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8704    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8705    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8706    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
8707    cmp     r0, #0                      @ already resolved?
8708    EXPORT_PC()                         @ must export for invoke
8709    bne     .LOP_INVOKE_VIRTUAL_JUMBO_continue        @ yes, continue on
8710    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
8711    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8712    mov     r2, #METHOD_VIRTUAL         @ resolver method type
8713    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8714    cmp     r0, #0                      @ got null?
8715    bne     .LOP_INVOKE_VIRTUAL_JUMBO_continue        @ no, continue
8716    b       common_exceptionThrown      @ yes, handle exception
8717
8718/* ------------------------------ */
8719    .balign 64
8720.L_OP_INVOKE_SUPER_JUMBO: /* 0x123 */
8721/* File: armv5te/OP_INVOKE_SUPER_JUMBO.S */
8722    /*
8723     * Handle a "super" method call.
8724     */
8725    /* invoke-super/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8726    FETCH(r10, 4)                       @ r10<- CCCC
8727    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8728    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8729    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8730    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8731    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8732    GET_VREG(r2, r10)                   @ r2<- "this" ptr
8733    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
8734    cmp     r2, #0                      @ null "this"?
8735    ldr     r9, [rGLUE, #offGlue_method] @ r9<- current method
8736    beq     common_errNullObject        @ null "this", throw exception
8737    cmp     r0, #0                      @ already resolved?
8738    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
8739    EXPORT_PC()                         @ must export for invoke
8740    bne     .LOP_INVOKE_SUPER_JUMBO_continue        @ resolved, continue on
8741    b       .LOP_INVOKE_SUPER_JUMBO_resolve         @ do resolve now
8742
8743/* ------------------------------ */
8744    .balign 64
8745.L_OP_INVOKE_DIRECT_JUMBO: /* 0x124 */
8746/* File: armv5te/OP_INVOKE_DIRECT_JUMBO.S */
8747    /*
8748     * Handle a direct method call.
8749     *
8750     * (We could defer the "is 'this' pointer null" test to the common
8751     * method invocation code, and use a flag to indicate that static
8752     * calls don't count.  If we do this as part of copying the arguments
8753     * out we could avoiding loading the first arg twice.)
8754     *
8755     */
8756    /* invoke-direct/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8757    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8758    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8759    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8760    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8761    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8762    FETCH(r10, 4)                       @ r10<- CCCC
8763    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
8764    cmp     r0, #0                      @ already resolved?
8765    EXPORT_PC()                         @ must export for invoke
8766    GET_VREG(r2, r10)                   @ r2<- "this" ptr
8767    beq     .LOP_INVOKE_DIRECT_JUMBO_resolve         @ not resolved, do it now
8768.LOP_INVOKE_DIRECT_JUMBO_finish:
8769    cmp     r2, #0                      @ null "this" ref?
8770    bne     common_invokeMethodJumbo    @ no, continue on
8771    b       common_errNullObject        @ yes, throw exception
8772
8773/* ------------------------------ */
8774    .balign 64
8775.L_OP_INVOKE_STATIC_JUMBO: /* 0x125 */
8776/* File: armv5te/OP_INVOKE_STATIC_JUMBO.S */
8777    /*
8778     * Handle a static method call.
8779     */
8780    /* invoke-static/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8781    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8782    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8783    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8784    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8785    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8786    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
8787    cmp     r0, #0                      @ already resolved?
8788    EXPORT_PC()                         @ must export for invoke
8789    bne     common_invokeMethodJumbo    @ yes, continue on
87900:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
8791    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8792    mov     r2, #METHOD_STATIC          @ resolver method type
8793    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8794    cmp     r0, #0                      @ got null?
8795    bne     common_invokeMethodJumbo    @ no, continue
8796    b       common_exceptionThrown      @ yes, handle exception
8797
8798/* ------------------------------ */
8799    .balign 64
8800.L_OP_INVOKE_INTERFACE_JUMBO: /* 0x126 */
8801/* File: armv5te/OP_INVOKE_INTERFACE_JUMBO.S */
8802    /*
8803     * Handle an interface method call.
8804     */
8805    /* invoke-interface/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8806    FETCH(r2, 4)                        @ r2<- CCCC
8807    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8808    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8809    EXPORT_PC()                         @ must export for invoke
8810    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8811    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
8812    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- methodClassDex
8813    cmp     r0, #0                      @ null obj?
8814    ldr     r2, [rGLUE, #offGlue_method]  @ r2<- method
8815    beq     common_errNullObject        @ yes, fail
8816    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
8817    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
8818    cmp     r0, #0                      @ failed?
8819    beq     common_exceptionThrown      @ yes, handle exception
8820    b       common_invokeMethodJumbo    @ jump to common handler
8821
8822/* ------------------------------ */
8823    .balign 64
8824.L_OP_UNUSED_27FF: /* 0x127 */
8825/* File: armv5te/OP_UNUSED_27FF.S */
8826/* File: armv5te/unused.S */
8827    bl      common_abort
8828
8829
8830/* ------------------------------ */
8831    .balign 64
8832.L_OP_UNUSED_28FF: /* 0x128 */
8833/* File: armv5te/OP_UNUSED_28FF.S */
8834/* File: armv5te/unused.S */
8835    bl      common_abort
8836
8837
8838/* ------------------------------ */
8839    .balign 64
8840.L_OP_UNUSED_29FF: /* 0x129 */
8841/* File: armv5te/OP_UNUSED_29FF.S */
8842/* File: armv5te/unused.S */
8843    bl      common_abort
8844
8845
8846/* ------------------------------ */
8847    .balign 64
8848.L_OP_UNUSED_2AFF: /* 0x12a */
8849/* File: armv5te/OP_UNUSED_2AFF.S */
8850/* File: armv5te/unused.S */
8851    bl      common_abort
8852
8853
8854/* ------------------------------ */
8855    .balign 64
8856.L_OP_UNUSED_2BFF: /* 0x12b */
8857/* File: armv5te/OP_UNUSED_2BFF.S */
8858/* File: armv5te/unused.S */
8859    bl      common_abort
8860
8861
8862/* ------------------------------ */
8863    .balign 64
8864.L_OP_UNUSED_2CFF: /* 0x12c */
8865/* File: armv5te/OP_UNUSED_2CFF.S */
8866/* File: armv5te/unused.S */
8867    bl      common_abort
8868
8869
8870/* ------------------------------ */
8871    .balign 64
8872.L_OP_UNUSED_2DFF: /* 0x12d */
8873/* File: armv5te/OP_UNUSED_2DFF.S */
8874/* File: armv5te/unused.S */
8875    bl      common_abort
8876
8877
8878/* ------------------------------ */
8879    .balign 64
8880.L_OP_UNUSED_2EFF: /* 0x12e */
8881/* File: armv5te/OP_UNUSED_2EFF.S */
8882/* File: armv5te/unused.S */
8883    bl      common_abort
8884
8885
8886/* ------------------------------ */
8887    .balign 64
8888.L_OP_UNUSED_2FFF: /* 0x12f */
8889/* File: armv5te/OP_UNUSED_2FFF.S */
8890/* File: armv5te/unused.S */
8891    bl      common_abort
8892
8893
8894/* ------------------------------ */
8895    .balign 64
8896.L_OP_UNUSED_30FF: /* 0x130 */
8897/* File: armv5te/OP_UNUSED_30FF.S */
8898/* File: armv5te/unused.S */
8899    bl      common_abort
8900
8901
8902/* ------------------------------ */
8903    .balign 64
8904.L_OP_UNUSED_31FF: /* 0x131 */
8905/* File: armv5te/OP_UNUSED_31FF.S */
8906/* File: armv5te/unused.S */
8907    bl      common_abort
8908
8909
8910/* ------------------------------ */
8911    .balign 64
8912.L_OP_UNUSED_32FF: /* 0x132 */
8913/* File: armv5te/OP_UNUSED_32FF.S */
8914/* File: armv5te/unused.S */
8915    bl      common_abort
8916
8917
8918/* ------------------------------ */
8919    .balign 64
8920.L_OP_UNUSED_33FF: /* 0x133 */
8921/* File: armv5te/OP_UNUSED_33FF.S */
8922/* File: armv5te/unused.S */
8923    bl      common_abort
8924
8925
8926/* ------------------------------ */
8927    .balign 64
8928.L_OP_UNUSED_34FF: /* 0x134 */
8929/* File: armv5te/OP_UNUSED_34FF.S */
8930/* File: armv5te/unused.S */
8931    bl      common_abort
8932
8933
8934/* ------------------------------ */
8935    .balign 64
8936.L_OP_UNUSED_35FF: /* 0x135 */
8937/* File: armv5te/OP_UNUSED_35FF.S */
8938/* File: armv5te/unused.S */
8939    bl      common_abort
8940
8941
8942/* ------------------------------ */
8943    .balign 64
8944.L_OP_UNUSED_36FF: /* 0x136 */
8945/* File: armv5te/OP_UNUSED_36FF.S */
8946/* File: armv5te/unused.S */
8947    bl      common_abort
8948
8949
8950/* ------------------------------ */
8951    .balign 64
8952.L_OP_UNUSED_37FF: /* 0x137 */
8953/* File: armv5te/OP_UNUSED_37FF.S */
8954/* File: armv5te/unused.S */
8955    bl      common_abort
8956
8957
8958/* ------------------------------ */
8959    .balign 64
8960.L_OP_UNUSED_38FF: /* 0x138 */
8961/* File: armv5te/OP_UNUSED_38FF.S */
8962/* File: armv5te/unused.S */
8963    bl      common_abort
8964
8965
8966/* ------------------------------ */
8967    .balign 64
8968.L_OP_UNUSED_39FF: /* 0x139 */
8969/* File: armv5te/OP_UNUSED_39FF.S */
8970/* File: armv5te/unused.S */
8971    bl      common_abort
8972
8973
8974/* ------------------------------ */
8975    .balign 64
8976.L_OP_UNUSED_3AFF: /* 0x13a */
8977/* File: armv5te/OP_UNUSED_3AFF.S */
8978/* File: armv5te/unused.S */
8979    bl      common_abort
8980
8981
8982/* ------------------------------ */
8983    .balign 64
8984.L_OP_UNUSED_3BFF: /* 0x13b */
8985/* File: armv5te/OP_UNUSED_3BFF.S */
8986/* File: armv5te/unused.S */
8987    bl      common_abort
8988
8989
8990/* ------------------------------ */
8991    .balign 64
8992.L_OP_UNUSED_3CFF: /* 0x13c */
8993/* File: armv5te/OP_UNUSED_3CFF.S */
8994/* File: armv5te/unused.S */
8995    bl      common_abort
8996
8997
8998/* ------------------------------ */
8999    .balign 64
9000.L_OP_UNUSED_3DFF: /* 0x13d */
9001/* File: armv5te/OP_UNUSED_3DFF.S */
9002/* File: armv5te/unused.S */
9003    bl      common_abort
9004
9005
9006/* ------------------------------ */
9007    .balign 64
9008.L_OP_UNUSED_3EFF: /* 0x13e */
9009/* File: armv5te/OP_UNUSED_3EFF.S */
9010/* File: armv5te/unused.S */
9011    bl      common_abort
9012
9013
9014/* ------------------------------ */
9015    .balign 64
9016.L_OP_UNUSED_3FFF: /* 0x13f */
9017/* File: armv5te/OP_UNUSED_3FFF.S */
9018/* File: armv5te/unused.S */
9019    bl      common_abort
9020
9021
9022/* ------------------------------ */
9023    .balign 64
9024.L_OP_UNUSED_40FF: /* 0x140 */
9025/* File: armv5te/OP_UNUSED_40FF.S */
9026/* File: armv5te/unused.S */
9027    bl      common_abort
9028
9029
9030/* ------------------------------ */
9031    .balign 64
9032.L_OP_UNUSED_41FF: /* 0x141 */
9033/* File: armv5te/OP_UNUSED_41FF.S */
9034/* File: armv5te/unused.S */
9035    bl      common_abort
9036
9037
9038/* ------------------------------ */
9039    .balign 64
9040.L_OP_UNUSED_42FF: /* 0x142 */
9041/* File: armv5te/OP_UNUSED_42FF.S */
9042/* File: armv5te/unused.S */
9043    bl      common_abort
9044
9045
9046/* ------------------------------ */
9047    .balign 64
9048.L_OP_UNUSED_43FF: /* 0x143 */
9049/* File: armv5te/OP_UNUSED_43FF.S */
9050/* File: armv5te/unused.S */
9051    bl      common_abort
9052
9053
9054/* ------------------------------ */
9055    .balign 64
9056.L_OP_UNUSED_44FF: /* 0x144 */
9057/* File: armv5te/OP_UNUSED_44FF.S */
9058/* File: armv5te/unused.S */
9059    bl      common_abort
9060
9061
9062/* ------------------------------ */
9063    .balign 64
9064.L_OP_UNUSED_45FF: /* 0x145 */
9065/* File: armv5te/OP_UNUSED_45FF.S */
9066/* File: armv5te/unused.S */
9067    bl      common_abort
9068
9069
9070/* ------------------------------ */
9071    .balign 64
9072.L_OP_UNUSED_46FF: /* 0x146 */
9073/* File: armv5te/OP_UNUSED_46FF.S */
9074/* File: armv5te/unused.S */
9075    bl      common_abort
9076
9077
9078/* ------------------------------ */
9079    .balign 64
9080.L_OP_UNUSED_47FF: /* 0x147 */
9081/* File: armv5te/OP_UNUSED_47FF.S */
9082/* File: armv5te/unused.S */
9083    bl      common_abort
9084
9085
9086/* ------------------------------ */
9087    .balign 64
9088.L_OP_UNUSED_48FF: /* 0x148 */
9089/* File: armv5te/OP_UNUSED_48FF.S */
9090/* File: armv5te/unused.S */
9091    bl      common_abort
9092
9093
9094/* ------------------------------ */
9095    .balign 64
9096.L_OP_UNUSED_49FF: /* 0x149 */
9097/* File: armv5te/OP_UNUSED_49FF.S */
9098/* File: armv5te/unused.S */
9099    bl      common_abort
9100
9101
9102/* ------------------------------ */
9103    .balign 64
9104.L_OP_UNUSED_4AFF: /* 0x14a */
9105/* File: armv5te/OP_UNUSED_4AFF.S */
9106/* File: armv5te/unused.S */
9107    bl      common_abort
9108
9109
9110/* ------------------------------ */
9111    .balign 64
9112.L_OP_UNUSED_4BFF: /* 0x14b */
9113/* File: armv5te/OP_UNUSED_4BFF.S */
9114/* File: armv5te/unused.S */
9115    bl      common_abort
9116
9117
9118/* ------------------------------ */
9119    .balign 64
9120.L_OP_UNUSED_4CFF: /* 0x14c */
9121/* File: armv5te/OP_UNUSED_4CFF.S */
9122/* File: armv5te/unused.S */
9123    bl      common_abort
9124
9125
9126/* ------------------------------ */
9127    .balign 64
9128.L_OP_UNUSED_4DFF: /* 0x14d */
9129/* File: armv5te/OP_UNUSED_4DFF.S */
9130/* File: armv5te/unused.S */
9131    bl      common_abort
9132
9133
9134/* ------------------------------ */
9135    .balign 64
9136.L_OP_UNUSED_4EFF: /* 0x14e */
9137/* File: armv5te/OP_UNUSED_4EFF.S */
9138/* File: armv5te/unused.S */
9139    bl      common_abort
9140
9141
9142/* ------------------------------ */
9143    .balign 64
9144.L_OP_UNUSED_4FFF: /* 0x14f */
9145/* File: armv5te/OP_UNUSED_4FFF.S */
9146/* File: armv5te/unused.S */
9147    bl      common_abort
9148
9149
9150/* ------------------------------ */
9151    .balign 64
9152.L_OP_UNUSED_50FF: /* 0x150 */
9153/* File: armv5te/OP_UNUSED_50FF.S */
9154/* File: armv5te/unused.S */
9155    bl      common_abort
9156
9157
9158/* ------------------------------ */
9159    .balign 64
9160.L_OP_UNUSED_51FF: /* 0x151 */
9161/* File: armv5te/OP_UNUSED_51FF.S */
9162/* File: armv5te/unused.S */
9163    bl      common_abort
9164
9165
9166/* ------------------------------ */
9167    .balign 64
9168.L_OP_UNUSED_52FF: /* 0x152 */
9169/* File: armv5te/OP_UNUSED_52FF.S */
9170/* File: armv5te/unused.S */
9171    bl      common_abort
9172
9173
9174/* ------------------------------ */
9175    .balign 64
9176.L_OP_UNUSED_53FF: /* 0x153 */
9177/* File: armv5te/OP_UNUSED_53FF.S */
9178/* File: armv5te/unused.S */
9179    bl      common_abort
9180
9181
9182/* ------------------------------ */
9183    .balign 64
9184.L_OP_UNUSED_54FF: /* 0x154 */
9185/* File: armv5te/OP_UNUSED_54FF.S */
9186/* File: armv5te/unused.S */
9187    bl      common_abort
9188
9189
9190/* ------------------------------ */
9191    .balign 64
9192.L_OP_UNUSED_55FF: /* 0x155 */
9193/* File: armv5te/OP_UNUSED_55FF.S */
9194/* File: armv5te/unused.S */
9195    bl      common_abort
9196
9197
9198/* ------------------------------ */
9199    .balign 64
9200.L_OP_UNUSED_56FF: /* 0x156 */
9201/* File: armv5te/OP_UNUSED_56FF.S */
9202/* File: armv5te/unused.S */
9203    bl      common_abort
9204
9205
9206/* ------------------------------ */
9207    .balign 64
9208.L_OP_UNUSED_57FF: /* 0x157 */
9209/* File: armv5te/OP_UNUSED_57FF.S */
9210/* File: armv5te/unused.S */
9211    bl      common_abort
9212
9213
9214/* ------------------------------ */
9215    .balign 64
9216.L_OP_UNUSED_58FF: /* 0x158 */
9217/* File: armv5te/OP_UNUSED_58FF.S */
9218/* File: armv5te/unused.S */
9219    bl      common_abort
9220
9221
9222/* ------------------------------ */
9223    .balign 64
9224.L_OP_UNUSED_59FF: /* 0x159 */
9225/* File: armv5te/OP_UNUSED_59FF.S */
9226/* File: armv5te/unused.S */
9227    bl      common_abort
9228
9229
9230/* ------------------------------ */
9231    .balign 64
9232.L_OP_UNUSED_5AFF: /* 0x15a */
9233/* File: armv5te/OP_UNUSED_5AFF.S */
9234/* File: armv5te/unused.S */
9235    bl      common_abort
9236
9237
9238/* ------------------------------ */
9239    .balign 64
9240.L_OP_UNUSED_5BFF: /* 0x15b */
9241/* File: armv5te/OP_UNUSED_5BFF.S */
9242/* File: armv5te/unused.S */
9243    bl      common_abort
9244
9245
9246/* ------------------------------ */
9247    .balign 64
9248.L_OP_UNUSED_5CFF: /* 0x15c */
9249/* File: armv5te/OP_UNUSED_5CFF.S */
9250/* File: armv5te/unused.S */
9251    bl      common_abort
9252
9253
9254/* ------------------------------ */
9255    .balign 64
9256.L_OP_UNUSED_5DFF: /* 0x15d */
9257/* File: armv5te/OP_UNUSED_5DFF.S */
9258/* File: armv5te/unused.S */
9259    bl      common_abort
9260
9261
9262/* ------------------------------ */
9263    .balign 64
9264.L_OP_UNUSED_5EFF: /* 0x15e */
9265/* File: armv5te/OP_UNUSED_5EFF.S */
9266/* File: armv5te/unused.S */
9267    bl      common_abort
9268
9269
9270/* ------------------------------ */
9271    .balign 64
9272.L_OP_UNUSED_5FFF: /* 0x15f */
9273/* File: armv5te/OP_UNUSED_5FFF.S */
9274/* File: armv5te/unused.S */
9275    bl      common_abort
9276
9277
9278/* ------------------------------ */
9279    .balign 64
9280.L_OP_UNUSED_60FF: /* 0x160 */
9281/* File: armv5te/OP_UNUSED_60FF.S */
9282/* File: armv5te/unused.S */
9283    bl      common_abort
9284
9285
9286/* ------------------------------ */
9287    .balign 64
9288.L_OP_UNUSED_61FF: /* 0x161 */
9289/* File: armv5te/OP_UNUSED_61FF.S */
9290/* File: armv5te/unused.S */
9291    bl      common_abort
9292
9293
9294/* ------------------------------ */
9295    .balign 64
9296.L_OP_UNUSED_62FF: /* 0x162 */
9297/* File: armv5te/OP_UNUSED_62FF.S */
9298/* File: armv5te/unused.S */
9299    bl      common_abort
9300
9301
9302/* ------------------------------ */
9303    .balign 64
9304.L_OP_UNUSED_63FF: /* 0x163 */
9305/* File: armv5te/OP_UNUSED_63FF.S */
9306/* File: armv5te/unused.S */
9307    bl      common_abort
9308
9309
9310/* ------------------------------ */
9311    .balign 64
9312.L_OP_UNUSED_64FF: /* 0x164 */
9313/* File: armv5te/OP_UNUSED_64FF.S */
9314/* File: armv5te/unused.S */
9315    bl      common_abort
9316
9317
9318/* ------------------------------ */
9319    .balign 64
9320.L_OP_UNUSED_65FF: /* 0x165 */
9321/* File: armv5te/OP_UNUSED_65FF.S */
9322/* File: armv5te/unused.S */
9323    bl      common_abort
9324
9325
9326/* ------------------------------ */
9327    .balign 64
9328.L_OP_UNUSED_66FF: /* 0x166 */
9329/* File: armv5te/OP_UNUSED_66FF.S */
9330/* File: armv5te/unused.S */
9331    bl      common_abort
9332
9333
9334/* ------------------------------ */
9335    .balign 64
9336.L_OP_UNUSED_67FF: /* 0x167 */
9337/* File: armv5te/OP_UNUSED_67FF.S */
9338/* File: armv5te/unused.S */
9339    bl      common_abort
9340
9341
9342/* ------------------------------ */
9343    .balign 64
9344.L_OP_UNUSED_68FF: /* 0x168 */
9345/* File: armv5te/OP_UNUSED_68FF.S */
9346/* File: armv5te/unused.S */
9347    bl      common_abort
9348
9349
9350/* ------------------------------ */
9351    .balign 64
9352.L_OP_UNUSED_69FF: /* 0x169 */
9353/* File: armv5te/OP_UNUSED_69FF.S */
9354/* File: armv5te/unused.S */
9355    bl      common_abort
9356
9357
9358/* ------------------------------ */
9359    .balign 64
9360.L_OP_UNUSED_6AFF: /* 0x16a */
9361/* File: armv5te/OP_UNUSED_6AFF.S */
9362/* File: armv5te/unused.S */
9363    bl      common_abort
9364
9365
9366/* ------------------------------ */
9367    .balign 64
9368.L_OP_UNUSED_6BFF: /* 0x16b */
9369/* File: armv5te/OP_UNUSED_6BFF.S */
9370/* File: armv5te/unused.S */
9371    bl      common_abort
9372
9373
9374/* ------------------------------ */
9375    .balign 64
9376.L_OP_UNUSED_6CFF: /* 0x16c */
9377/* File: armv5te/OP_UNUSED_6CFF.S */
9378/* File: armv5te/unused.S */
9379    bl      common_abort
9380
9381
9382/* ------------------------------ */
9383    .balign 64
9384.L_OP_UNUSED_6DFF: /* 0x16d */
9385/* File: armv5te/OP_UNUSED_6DFF.S */
9386/* File: armv5te/unused.S */
9387    bl      common_abort
9388
9389
9390/* ------------------------------ */
9391    .balign 64
9392.L_OP_UNUSED_6EFF: /* 0x16e */
9393/* File: armv5te/OP_UNUSED_6EFF.S */
9394/* File: armv5te/unused.S */
9395    bl      common_abort
9396
9397
9398/* ------------------------------ */
9399    .balign 64
9400.L_OP_UNUSED_6FFF: /* 0x16f */
9401/* File: armv5te/OP_UNUSED_6FFF.S */
9402/* File: armv5te/unused.S */
9403    bl      common_abort
9404
9405
9406/* ------------------------------ */
9407    .balign 64
9408.L_OP_UNUSED_70FF: /* 0x170 */
9409/* File: armv5te/OP_UNUSED_70FF.S */
9410/* File: armv5te/unused.S */
9411    bl      common_abort
9412
9413
9414/* ------------------------------ */
9415    .balign 64
9416.L_OP_UNUSED_71FF: /* 0x171 */
9417/* File: armv5te/OP_UNUSED_71FF.S */
9418/* File: armv5te/unused.S */
9419    bl      common_abort
9420
9421
9422/* ------------------------------ */
9423    .balign 64
9424.L_OP_UNUSED_72FF: /* 0x172 */
9425/* File: armv5te/OP_UNUSED_72FF.S */
9426/* File: armv5te/unused.S */
9427    bl      common_abort
9428
9429
9430/* ------------------------------ */
9431    .balign 64
9432.L_OP_UNUSED_73FF: /* 0x173 */
9433/* File: armv5te/OP_UNUSED_73FF.S */
9434/* File: armv5te/unused.S */
9435    bl      common_abort
9436
9437
9438/* ------------------------------ */
9439    .balign 64
9440.L_OP_UNUSED_74FF: /* 0x174 */
9441/* File: armv5te/OP_UNUSED_74FF.S */
9442/* File: armv5te/unused.S */
9443    bl      common_abort
9444
9445
9446/* ------------------------------ */
9447    .balign 64
9448.L_OP_UNUSED_75FF: /* 0x175 */
9449/* File: armv5te/OP_UNUSED_75FF.S */
9450/* File: armv5te/unused.S */
9451    bl      common_abort
9452
9453
9454/* ------------------------------ */
9455    .balign 64
9456.L_OP_UNUSED_76FF: /* 0x176 */
9457/* File: armv5te/OP_UNUSED_76FF.S */
9458/* File: armv5te/unused.S */
9459    bl      common_abort
9460
9461
9462/* ------------------------------ */
9463    .balign 64
9464.L_OP_UNUSED_77FF: /* 0x177 */
9465/* File: armv5te/OP_UNUSED_77FF.S */
9466/* File: armv5te/unused.S */
9467    bl      common_abort
9468
9469
9470/* ------------------------------ */
9471    .balign 64
9472.L_OP_UNUSED_78FF: /* 0x178 */
9473/* File: armv5te/OP_UNUSED_78FF.S */
9474/* File: armv5te/unused.S */
9475    bl      common_abort
9476
9477
9478/* ------------------------------ */
9479    .balign 64
9480.L_OP_UNUSED_79FF: /* 0x179 */
9481/* File: armv5te/OP_UNUSED_79FF.S */
9482/* File: armv5te/unused.S */
9483    bl      common_abort
9484
9485
9486/* ------------------------------ */
9487    .balign 64
9488.L_OP_UNUSED_7AFF: /* 0x17a */
9489/* File: armv5te/OP_UNUSED_7AFF.S */
9490/* File: armv5te/unused.S */
9491    bl      common_abort
9492
9493
9494/* ------------------------------ */
9495    .balign 64
9496.L_OP_UNUSED_7BFF: /* 0x17b */
9497/* File: armv5te/OP_UNUSED_7BFF.S */
9498/* File: armv5te/unused.S */
9499    bl      common_abort
9500
9501
9502/* ------------------------------ */
9503    .balign 64
9504.L_OP_UNUSED_7CFF: /* 0x17c */
9505/* File: armv5te/OP_UNUSED_7CFF.S */
9506/* File: armv5te/unused.S */
9507    bl      common_abort
9508
9509
9510/* ------------------------------ */
9511    .balign 64
9512.L_OP_UNUSED_7DFF: /* 0x17d */
9513/* File: armv5te/OP_UNUSED_7DFF.S */
9514/* File: armv5te/unused.S */
9515    bl      common_abort
9516
9517
9518/* ------------------------------ */
9519    .balign 64
9520.L_OP_UNUSED_7EFF: /* 0x17e */
9521/* File: armv5te/OP_UNUSED_7EFF.S */
9522/* File: armv5te/unused.S */
9523    bl      common_abort
9524
9525
9526/* ------------------------------ */
9527    .balign 64
9528.L_OP_UNUSED_7FFF: /* 0x17f */
9529/* File: armv5te/OP_UNUSED_7FFF.S */
9530/* File: armv5te/unused.S */
9531    bl      common_abort
9532
9533
9534/* ------------------------------ */
9535    .balign 64
9536.L_OP_UNUSED_80FF: /* 0x180 */
9537/* File: armv5te/OP_UNUSED_80FF.S */
9538/* File: armv5te/unused.S */
9539    bl      common_abort
9540
9541
9542/* ------------------------------ */
9543    .balign 64
9544.L_OP_UNUSED_81FF: /* 0x181 */
9545/* File: armv5te/OP_UNUSED_81FF.S */
9546/* File: armv5te/unused.S */
9547    bl      common_abort
9548
9549
9550/* ------------------------------ */
9551    .balign 64
9552.L_OP_UNUSED_82FF: /* 0x182 */
9553/* File: armv5te/OP_UNUSED_82FF.S */
9554/* File: armv5te/unused.S */
9555    bl      common_abort
9556
9557
9558/* ------------------------------ */
9559    .balign 64
9560.L_OP_UNUSED_83FF: /* 0x183 */
9561/* File: armv5te/OP_UNUSED_83FF.S */
9562/* File: armv5te/unused.S */
9563    bl      common_abort
9564
9565
9566/* ------------------------------ */
9567    .balign 64
9568.L_OP_UNUSED_84FF: /* 0x184 */
9569/* File: armv5te/OP_UNUSED_84FF.S */
9570/* File: armv5te/unused.S */
9571    bl      common_abort
9572
9573
9574/* ------------------------------ */
9575    .balign 64
9576.L_OP_UNUSED_85FF: /* 0x185 */
9577/* File: armv5te/OP_UNUSED_85FF.S */
9578/* File: armv5te/unused.S */
9579    bl      common_abort
9580
9581
9582/* ------------------------------ */
9583    .balign 64
9584.L_OP_UNUSED_86FF: /* 0x186 */
9585/* File: armv5te/OP_UNUSED_86FF.S */
9586/* File: armv5te/unused.S */
9587    bl      common_abort
9588
9589
9590/* ------------------------------ */
9591    .balign 64
9592.L_OP_UNUSED_87FF: /* 0x187 */
9593/* File: armv5te/OP_UNUSED_87FF.S */
9594/* File: armv5te/unused.S */
9595    bl      common_abort
9596
9597
9598/* ------------------------------ */
9599    .balign 64
9600.L_OP_UNUSED_88FF: /* 0x188 */
9601/* File: armv5te/OP_UNUSED_88FF.S */
9602/* File: armv5te/unused.S */
9603    bl      common_abort
9604
9605
9606/* ------------------------------ */
9607    .balign 64
9608.L_OP_UNUSED_89FF: /* 0x189 */
9609/* File: armv5te/OP_UNUSED_89FF.S */
9610/* File: armv5te/unused.S */
9611    bl      common_abort
9612
9613
9614/* ------------------------------ */
9615    .balign 64
9616.L_OP_UNUSED_8AFF: /* 0x18a */
9617/* File: armv5te/OP_UNUSED_8AFF.S */
9618/* File: armv5te/unused.S */
9619    bl      common_abort
9620
9621
9622/* ------------------------------ */
9623    .balign 64
9624.L_OP_UNUSED_8BFF: /* 0x18b */
9625/* File: armv5te/OP_UNUSED_8BFF.S */
9626/* File: armv5te/unused.S */
9627    bl      common_abort
9628
9629
9630/* ------------------------------ */
9631    .balign 64
9632.L_OP_UNUSED_8CFF: /* 0x18c */
9633/* File: armv5te/OP_UNUSED_8CFF.S */
9634/* File: armv5te/unused.S */
9635    bl      common_abort
9636
9637
9638/* ------------------------------ */
9639    .balign 64
9640.L_OP_UNUSED_8DFF: /* 0x18d */
9641/* File: armv5te/OP_UNUSED_8DFF.S */
9642/* File: armv5te/unused.S */
9643    bl      common_abort
9644
9645
9646/* ------------------------------ */
9647    .balign 64
9648.L_OP_UNUSED_8EFF: /* 0x18e */
9649/* File: armv5te/OP_UNUSED_8EFF.S */
9650/* File: armv5te/unused.S */
9651    bl      common_abort
9652
9653
9654/* ------------------------------ */
9655    .balign 64
9656.L_OP_UNUSED_8FFF: /* 0x18f */
9657/* File: armv5te/OP_UNUSED_8FFF.S */
9658/* File: armv5te/unused.S */
9659    bl      common_abort
9660
9661
9662/* ------------------------------ */
9663    .balign 64
9664.L_OP_UNUSED_90FF: /* 0x190 */
9665/* File: armv5te/OP_UNUSED_90FF.S */
9666/* File: armv5te/unused.S */
9667    bl      common_abort
9668
9669
9670/* ------------------------------ */
9671    .balign 64
9672.L_OP_UNUSED_91FF: /* 0x191 */
9673/* File: armv5te/OP_UNUSED_91FF.S */
9674/* File: armv5te/unused.S */
9675    bl      common_abort
9676
9677
9678/* ------------------------------ */
9679    .balign 64
9680.L_OP_UNUSED_92FF: /* 0x192 */
9681/* File: armv5te/OP_UNUSED_92FF.S */
9682/* File: armv5te/unused.S */
9683    bl      common_abort
9684
9685
9686/* ------------------------------ */
9687    .balign 64
9688.L_OP_UNUSED_93FF: /* 0x193 */
9689/* File: armv5te/OP_UNUSED_93FF.S */
9690/* File: armv5te/unused.S */
9691    bl      common_abort
9692
9693
9694/* ------------------------------ */
9695    .balign 64
9696.L_OP_UNUSED_94FF: /* 0x194 */
9697/* File: armv5te/OP_UNUSED_94FF.S */
9698/* File: armv5te/unused.S */
9699    bl      common_abort
9700
9701
9702/* ------------------------------ */
9703    .balign 64
9704.L_OP_UNUSED_95FF: /* 0x195 */
9705/* File: armv5te/OP_UNUSED_95FF.S */
9706/* File: armv5te/unused.S */
9707    bl      common_abort
9708
9709
9710/* ------------------------------ */
9711    .balign 64
9712.L_OP_UNUSED_96FF: /* 0x196 */
9713/* File: armv5te/OP_UNUSED_96FF.S */
9714/* File: armv5te/unused.S */
9715    bl      common_abort
9716
9717
9718/* ------------------------------ */
9719    .balign 64
9720.L_OP_UNUSED_97FF: /* 0x197 */
9721/* File: armv5te/OP_UNUSED_97FF.S */
9722/* File: armv5te/unused.S */
9723    bl      common_abort
9724
9725
9726/* ------------------------------ */
9727    .balign 64
9728.L_OP_UNUSED_98FF: /* 0x198 */
9729/* File: armv5te/OP_UNUSED_98FF.S */
9730/* File: armv5te/unused.S */
9731    bl      common_abort
9732
9733
9734/* ------------------------------ */
9735    .balign 64
9736.L_OP_UNUSED_99FF: /* 0x199 */
9737/* File: armv5te/OP_UNUSED_99FF.S */
9738/* File: armv5te/unused.S */
9739    bl      common_abort
9740
9741
9742/* ------------------------------ */
9743    .balign 64
9744.L_OP_UNUSED_9AFF: /* 0x19a */
9745/* File: armv5te/OP_UNUSED_9AFF.S */
9746/* File: armv5te/unused.S */
9747    bl      common_abort
9748
9749
9750/* ------------------------------ */
9751    .balign 64
9752.L_OP_UNUSED_9BFF: /* 0x19b */
9753/* File: armv5te/OP_UNUSED_9BFF.S */
9754/* File: armv5te/unused.S */
9755    bl      common_abort
9756
9757
9758/* ------------------------------ */
9759    .balign 64
9760.L_OP_UNUSED_9CFF: /* 0x19c */
9761/* File: armv5te/OP_UNUSED_9CFF.S */
9762/* File: armv5te/unused.S */
9763    bl      common_abort
9764
9765
9766/* ------------------------------ */
9767    .balign 64
9768.L_OP_UNUSED_9DFF: /* 0x19d */
9769/* File: armv5te/OP_UNUSED_9DFF.S */
9770/* File: armv5te/unused.S */
9771    bl      common_abort
9772
9773
9774/* ------------------------------ */
9775    .balign 64
9776.L_OP_UNUSED_9EFF: /* 0x19e */
9777/* File: armv5te/OP_UNUSED_9EFF.S */
9778/* File: armv5te/unused.S */
9779    bl      common_abort
9780
9781
9782/* ------------------------------ */
9783    .balign 64
9784.L_OP_UNUSED_9FFF: /* 0x19f */
9785/* File: armv5te/OP_UNUSED_9FFF.S */
9786/* File: armv5te/unused.S */
9787    bl      common_abort
9788
9789
9790/* ------------------------------ */
9791    .balign 64
9792.L_OP_UNUSED_A0FF: /* 0x1a0 */
9793/* File: armv5te/OP_UNUSED_A0FF.S */
9794/* File: armv5te/unused.S */
9795    bl      common_abort
9796
9797
9798/* ------------------------------ */
9799    .balign 64
9800.L_OP_UNUSED_A1FF: /* 0x1a1 */
9801/* File: armv5te/OP_UNUSED_A1FF.S */
9802/* File: armv5te/unused.S */
9803    bl      common_abort
9804
9805
9806/* ------------------------------ */
9807    .balign 64
9808.L_OP_UNUSED_A2FF: /* 0x1a2 */
9809/* File: armv5te/OP_UNUSED_A2FF.S */
9810/* File: armv5te/unused.S */
9811    bl      common_abort
9812
9813
9814/* ------------------------------ */
9815    .balign 64
9816.L_OP_UNUSED_A3FF: /* 0x1a3 */
9817/* File: armv5te/OP_UNUSED_A3FF.S */
9818/* File: armv5te/unused.S */
9819    bl      common_abort
9820
9821
9822/* ------------------------------ */
9823    .balign 64
9824.L_OP_UNUSED_A4FF: /* 0x1a4 */
9825/* File: armv5te/OP_UNUSED_A4FF.S */
9826/* File: armv5te/unused.S */
9827    bl      common_abort
9828
9829
9830/* ------------------------------ */
9831    .balign 64
9832.L_OP_UNUSED_A5FF: /* 0x1a5 */
9833/* File: armv5te/OP_UNUSED_A5FF.S */
9834/* File: armv5te/unused.S */
9835    bl      common_abort
9836
9837
9838/* ------------------------------ */
9839    .balign 64
9840.L_OP_UNUSED_A6FF: /* 0x1a6 */
9841/* File: armv5te/OP_UNUSED_A6FF.S */
9842/* File: armv5te/unused.S */
9843    bl      common_abort
9844
9845
9846/* ------------------------------ */
9847    .balign 64
9848.L_OP_UNUSED_A7FF: /* 0x1a7 */
9849/* File: armv5te/OP_UNUSED_A7FF.S */
9850/* File: armv5te/unused.S */
9851    bl      common_abort
9852
9853
9854/* ------------------------------ */
9855    .balign 64
9856.L_OP_UNUSED_A8FF: /* 0x1a8 */
9857/* File: armv5te/OP_UNUSED_A8FF.S */
9858/* File: armv5te/unused.S */
9859    bl      common_abort
9860
9861
9862/* ------------------------------ */
9863    .balign 64
9864.L_OP_UNUSED_A9FF: /* 0x1a9 */
9865/* File: armv5te/OP_UNUSED_A9FF.S */
9866/* File: armv5te/unused.S */
9867    bl      common_abort
9868
9869
9870/* ------------------------------ */
9871    .balign 64
9872.L_OP_UNUSED_AAFF: /* 0x1aa */
9873/* File: armv5te/OP_UNUSED_AAFF.S */
9874/* File: armv5te/unused.S */
9875    bl      common_abort
9876
9877
9878/* ------------------------------ */
9879    .balign 64
9880.L_OP_UNUSED_ABFF: /* 0x1ab */
9881/* File: armv5te/OP_UNUSED_ABFF.S */
9882/* File: armv5te/unused.S */
9883    bl      common_abort
9884
9885
9886/* ------------------------------ */
9887    .balign 64
9888.L_OP_UNUSED_ACFF: /* 0x1ac */
9889/* File: armv5te/OP_UNUSED_ACFF.S */
9890/* File: armv5te/unused.S */
9891    bl      common_abort
9892
9893
9894/* ------------------------------ */
9895    .balign 64
9896.L_OP_UNUSED_ADFF: /* 0x1ad */
9897/* File: armv5te/OP_UNUSED_ADFF.S */
9898/* File: armv5te/unused.S */
9899    bl      common_abort
9900
9901
9902/* ------------------------------ */
9903    .balign 64
9904.L_OP_UNUSED_AEFF: /* 0x1ae */
9905/* File: armv5te/OP_UNUSED_AEFF.S */
9906/* File: armv5te/unused.S */
9907    bl      common_abort
9908
9909
9910/* ------------------------------ */
9911    .balign 64
9912.L_OP_UNUSED_AFFF: /* 0x1af */
9913/* File: armv5te/OP_UNUSED_AFFF.S */
9914/* File: armv5te/unused.S */
9915    bl      common_abort
9916
9917
9918/* ------------------------------ */
9919    .balign 64
9920.L_OP_UNUSED_B0FF: /* 0x1b0 */
9921/* File: armv5te/OP_UNUSED_B0FF.S */
9922/* File: armv5te/unused.S */
9923    bl      common_abort
9924
9925
9926/* ------------------------------ */
9927    .balign 64
9928.L_OP_UNUSED_B1FF: /* 0x1b1 */
9929/* File: armv5te/OP_UNUSED_B1FF.S */
9930/* File: armv5te/unused.S */
9931    bl      common_abort
9932
9933
9934/* ------------------------------ */
9935    .balign 64
9936.L_OP_UNUSED_B2FF: /* 0x1b2 */
9937/* File: armv5te/OP_UNUSED_B2FF.S */
9938/* File: armv5te/unused.S */
9939    bl      common_abort
9940
9941
9942/* ------------------------------ */
9943    .balign 64
9944.L_OP_UNUSED_B3FF: /* 0x1b3 */
9945/* File: armv5te/OP_UNUSED_B3FF.S */
9946/* File: armv5te/unused.S */
9947    bl      common_abort
9948
9949
9950/* ------------------------------ */
9951    .balign 64
9952.L_OP_UNUSED_B4FF: /* 0x1b4 */
9953/* File: armv5te/OP_UNUSED_B4FF.S */
9954/* File: armv5te/unused.S */
9955    bl      common_abort
9956
9957
9958/* ------------------------------ */
9959    .balign 64
9960.L_OP_UNUSED_B5FF: /* 0x1b5 */
9961/* File: armv5te/OP_UNUSED_B5FF.S */
9962/* File: armv5te/unused.S */
9963    bl      common_abort
9964
9965
9966/* ------------------------------ */
9967    .balign 64
9968.L_OP_UNUSED_B6FF: /* 0x1b6 */
9969/* File: armv5te/OP_UNUSED_B6FF.S */
9970/* File: armv5te/unused.S */
9971    bl      common_abort
9972
9973
9974/* ------------------------------ */
9975    .balign 64
9976.L_OP_UNUSED_B7FF: /* 0x1b7 */
9977/* File: armv5te/OP_UNUSED_B7FF.S */
9978/* File: armv5te/unused.S */
9979    bl      common_abort
9980
9981
9982/* ------------------------------ */
9983    .balign 64
9984.L_OP_UNUSED_B8FF: /* 0x1b8 */
9985/* File: armv5te/OP_UNUSED_B8FF.S */
9986/* File: armv5te/unused.S */
9987    bl      common_abort
9988
9989
9990/* ------------------------------ */
9991    .balign 64
9992.L_OP_UNUSED_B9FF: /* 0x1b9 */
9993/* File: armv5te/OP_UNUSED_B9FF.S */
9994/* File: armv5te/unused.S */
9995    bl      common_abort
9996
9997
9998/* ------------------------------ */
9999    .balign 64
10000.L_OP_UNUSED_BAFF: /* 0x1ba */
10001/* File: armv5te/OP_UNUSED_BAFF.S */
10002/* File: armv5te/unused.S */
10003    bl      common_abort
10004
10005
10006/* ------------------------------ */
10007    .balign 64
10008.L_OP_UNUSED_BBFF: /* 0x1bb */
10009/* File: armv5te/OP_UNUSED_BBFF.S */
10010/* File: armv5te/unused.S */
10011    bl      common_abort
10012
10013
10014/* ------------------------------ */
10015    .balign 64
10016.L_OP_UNUSED_BCFF: /* 0x1bc */
10017/* File: armv5te/OP_UNUSED_BCFF.S */
10018/* File: armv5te/unused.S */
10019    bl      common_abort
10020
10021
10022/* ------------------------------ */
10023    .balign 64
10024.L_OP_UNUSED_BDFF: /* 0x1bd */
10025/* File: armv5te/OP_UNUSED_BDFF.S */
10026/* File: armv5te/unused.S */
10027    bl      common_abort
10028
10029
10030/* ------------------------------ */
10031    .balign 64
10032.L_OP_UNUSED_BEFF: /* 0x1be */
10033/* File: armv5te/OP_UNUSED_BEFF.S */
10034/* File: armv5te/unused.S */
10035    bl      common_abort
10036
10037
10038/* ------------------------------ */
10039    .balign 64
10040.L_OP_UNUSED_BFFF: /* 0x1bf */
10041/* File: armv5te/OP_UNUSED_BFFF.S */
10042/* File: armv5te/unused.S */
10043    bl      common_abort
10044
10045
10046/* ------------------------------ */
10047    .balign 64
10048.L_OP_UNUSED_C0FF: /* 0x1c0 */
10049/* File: armv5te/OP_UNUSED_C0FF.S */
10050/* File: armv5te/unused.S */
10051    bl      common_abort
10052
10053
10054/* ------------------------------ */
10055    .balign 64
10056.L_OP_UNUSED_C1FF: /* 0x1c1 */
10057/* File: armv5te/OP_UNUSED_C1FF.S */
10058/* File: armv5te/unused.S */
10059    bl      common_abort
10060
10061
10062/* ------------------------------ */
10063    .balign 64
10064.L_OP_UNUSED_C2FF: /* 0x1c2 */
10065/* File: armv5te/OP_UNUSED_C2FF.S */
10066/* File: armv5te/unused.S */
10067    bl      common_abort
10068
10069
10070/* ------------------------------ */
10071    .balign 64
10072.L_OP_UNUSED_C3FF: /* 0x1c3 */
10073/* File: armv5te/OP_UNUSED_C3FF.S */
10074/* File: armv5te/unused.S */
10075    bl      common_abort
10076
10077
10078/* ------------------------------ */
10079    .balign 64
10080.L_OP_UNUSED_C4FF: /* 0x1c4 */
10081/* File: armv5te/OP_UNUSED_C4FF.S */
10082/* File: armv5te/unused.S */
10083    bl      common_abort
10084
10085
10086/* ------------------------------ */
10087    .balign 64
10088.L_OP_UNUSED_C5FF: /* 0x1c5 */
10089/* File: armv5te/OP_UNUSED_C5FF.S */
10090/* File: armv5te/unused.S */
10091    bl      common_abort
10092
10093
10094/* ------------------------------ */
10095    .balign 64
10096.L_OP_UNUSED_C6FF: /* 0x1c6 */
10097/* File: armv5te/OP_UNUSED_C6FF.S */
10098/* File: armv5te/unused.S */
10099    bl      common_abort
10100
10101
10102/* ------------------------------ */
10103    .balign 64
10104.L_OP_UNUSED_C7FF: /* 0x1c7 */
10105/* File: armv5te/OP_UNUSED_C7FF.S */
10106/* File: armv5te/unused.S */
10107    bl      common_abort
10108
10109
10110/* ------------------------------ */
10111    .balign 64
10112.L_OP_UNUSED_C8FF: /* 0x1c8 */
10113/* File: armv5te/OP_UNUSED_C8FF.S */
10114/* File: armv5te/unused.S */
10115    bl      common_abort
10116
10117
10118/* ------------------------------ */
10119    .balign 64
10120.L_OP_UNUSED_C9FF: /* 0x1c9 */
10121/* File: armv5te/OP_UNUSED_C9FF.S */
10122/* File: armv5te/unused.S */
10123    bl      common_abort
10124
10125
10126/* ------------------------------ */
10127    .balign 64
10128.L_OP_UNUSED_CAFF: /* 0x1ca */
10129/* File: armv5te/OP_UNUSED_CAFF.S */
10130/* File: armv5te/unused.S */
10131    bl      common_abort
10132
10133
10134/* ------------------------------ */
10135    .balign 64
10136.L_OP_UNUSED_CBFF: /* 0x1cb */
10137/* File: armv5te/OP_UNUSED_CBFF.S */
10138/* File: armv5te/unused.S */
10139    bl      common_abort
10140
10141
10142/* ------------------------------ */
10143    .balign 64
10144.L_OP_UNUSED_CCFF: /* 0x1cc */
10145/* File: armv5te/OP_UNUSED_CCFF.S */
10146/* File: armv5te/unused.S */
10147    bl      common_abort
10148
10149
10150/* ------------------------------ */
10151    .balign 64
10152.L_OP_UNUSED_CDFF: /* 0x1cd */
10153/* File: armv5te/OP_UNUSED_CDFF.S */
10154/* File: armv5te/unused.S */
10155    bl      common_abort
10156
10157
10158/* ------------------------------ */
10159    .balign 64
10160.L_OP_UNUSED_CEFF: /* 0x1ce */
10161/* File: armv5te/OP_UNUSED_CEFF.S */
10162/* File: armv5te/unused.S */
10163    bl      common_abort
10164
10165
10166/* ------------------------------ */
10167    .balign 64
10168.L_OP_UNUSED_CFFF: /* 0x1cf */
10169/* File: armv5te/OP_UNUSED_CFFF.S */
10170/* File: armv5te/unused.S */
10171    bl      common_abort
10172
10173
10174/* ------------------------------ */
10175    .balign 64
10176.L_OP_UNUSED_D0FF: /* 0x1d0 */
10177/* File: armv5te/OP_UNUSED_D0FF.S */
10178/* File: armv5te/unused.S */
10179    bl      common_abort
10180
10181
10182/* ------------------------------ */
10183    .balign 64
10184.L_OP_UNUSED_D1FF: /* 0x1d1 */
10185/* File: armv5te/OP_UNUSED_D1FF.S */
10186/* File: armv5te/unused.S */
10187    bl      common_abort
10188
10189
10190/* ------------------------------ */
10191    .balign 64
10192.L_OP_UNUSED_D2FF: /* 0x1d2 */
10193/* File: armv5te/OP_UNUSED_D2FF.S */
10194/* File: armv5te/unused.S */
10195    bl      common_abort
10196
10197
10198/* ------------------------------ */
10199    .balign 64
10200.L_OP_UNUSED_D3FF: /* 0x1d3 */
10201/* File: armv5te/OP_UNUSED_D3FF.S */
10202/* File: armv5te/unused.S */
10203    bl      common_abort
10204
10205
10206/* ------------------------------ */
10207    .balign 64
10208.L_OP_UNUSED_D4FF: /* 0x1d4 */
10209/* File: armv5te/OP_UNUSED_D4FF.S */
10210/* File: armv5te/unused.S */
10211    bl      common_abort
10212
10213
10214/* ------------------------------ */
10215    .balign 64
10216.L_OP_UNUSED_D5FF: /* 0x1d5 */
10217/* File: armv5te/OP_UNUSED_D5FF.S */
10218/* File: armv5te/unused.S */
10219    bl      common_abort
10220
10221
10222/* ------------------------------ */
10223    .balign 64
10224.L_OP_UNUSED_D6FF: /* 0x1d6 */
10225/* File: armv5te/OP_UNUSED_D6FF.S */
10226/* File: armv5te/unused.S */
10227    bl      common_abort
10228
10229
10230/* ------------------------------ */
10231    .balign 64
10232.L_OP_UNUSED_D7FF: /* 0x1d7 */
10233/* File: armv5te/OP_UNUSED_D7FF.S */
10234/* File: armv5te/unused.S */
10235    bl      common_abort
10236
10237
10238/* ------------------------------ */
10239    .balign 64
10240.L_OP_UNUSED_D8FF: /* 0x1d8 */
10241/* File: armv5te/OP_UNUSED_D8FF.S */
10242/* File: armv5te/unused.S */
10243    bl      common_abort
10244
10245
10246/* ------------------------------ */
10247    .balign 64
10248.L_OP_UNUSED_D9FF: /* 0x1d9 */
10249/* File: armv5te/OP_UNUSED_D9FF.S */
10250/* File: armv5te/unused.S */
10251    bl      common_abort
10252
10253
10254/* ------------------------------ */
10255    .balign 64
10256.L_OP_UNUSED_DAFF: /* 0x1da */
10257/* File: armv5te/OP_UNUSED_DAFF.S */
10258/* File: armv5te/unused.S */
10259    bl      common_abort
10260
10261
10262/* ------------------------------ */
10263    .balign 64
10264.L_OP_UNUSED_DBFF: /* 0x1db */
10265/* File: armv5te/OP_UNUSED_DBFF.S */
10266/* File: armv5te/unused.S */
10267    bl      common_abort
10268
10269
10270/* ------------------------------ */
10271    .balign 64
10272.L_OP_UNUSED_DCFF: /* 0x1dc */
10273/* File: armv5te/OP_UNUSED_DCFF.S */
10274/* File: armv5te/unused.S */
10275    bl      common_abort
10276
10277
10278/* ------------------------------ */
10279    .balign 64
10280.L_OP_UNUSED_DDFF: /* 0x1dd */
10281/* File: armv5te/OP_UNUSED_DDFF.S */
10282/* File: armv5te/unused.S */
10283    bl      common_abort
10284
10285
10286/* ------------------------------ */
10287    .balign 64
10288.L_OP_UNUSED_DEFF: /* 0x1de */
10289/* File: armv5te/OP_UNUSED_DEFF.S */
10290/* File: armv5te/unused.S */
10291    bl      common_abort
10292
10293
10294/* ------------------------------ */
10295    .balign 64
10296.L_OP_UNUSED_DFFF: /* 0x1df */
10297/* File: armv5te/OP_UNUSED_DFFF.S */
10298/* File: armv5te/unused.S */
10299    bl      common_abort
10300
10301
10302/* ------------------------------ */
10303    .balign 64
10304.L_OP_UNUSED_E0FF: /* 0x1e0 */
10305/* File: armv5te/OP_UNUSED_E0FF.S */
10306/* File: armv5te/unused.S */
10307    bl      common_abort
10308
10309
10310/* ------------------------------ */
10311    .balign 64
10312.L_OP_UNUSED_E1FF: /* 0x1e1 */
10313/* File: armv5te/OP_UNUSED_E1FF.S */
10314/* File: armv5te/unused.S */
10315    bl      common_abort
10316
10317
10318/* ------------------------------ */
10319    .balign 64
10320.L_OP_UNUSED_E2FF: /* 0x1e2 */
10321/* File: armv5te/OP_UNUSED_E2FF.S */
10322/* File: armv5te/unused.S */
10323    bl      common_abort
10324
10325
10326/* ------------------------------ */
10327    .balign 64
10328.L_OP_UNUSED_E3FF: /* 0x1e3 */
10329/* File: armv5te/OP_UNUSED_E3FF.S */
10330/* File: armv5te/unused.S */
10331    bl      common_abort
10332
10333
10334/* ------------------------------ */
10335    .balign 64
10336.L_OP_UNUSED_E4FF: /* 0x1e4 */
10337/* File: armv5te/OP_UNUSED_E4FF.S */
10338/* File: armv5te/unused.S */
10339    bl      common_abort
10340
10341
10342/* ------------------------------ */
10343    .balign 64
10344.L_OP_UNUSED_E5FF: /* 0x1e5 */
10345/* File: armv5te/OP_UNUSED_E5FF.S */
10346/* File: armv5te/unused.S */
10347    bl      common_abort
10348
10349
10350/* ------------------------------ */
10351    .balign 64
10352.L_OP_UNUSED_E6FF: /* 0x1e6 */
10353/* File: armv5te/OP_UNUSED_E6FF.S */
10354/* File: armv5te/unused.S */
10355    bl      common_abort
10356
10357
10358/* ------------------------------ */
10359    .balign 64
10360.L_OP_UNUSED_E7FF: /* 0x1e7 */
10361/* File: armv5te/OP_UNUSED_E7FF.S */
10362/* File: armv5te/unused.S */
10363    bl      common_abort
10364
10365
10366/* ------------------------------ */
10367    .balign 64
10368.L_OP_UNUSED_E8FF: /* 0x1e8 */
10369/* File: armv5te/OP_UNUSED_E8FF.S */
10370/* File: armv5te/unused.S */
10371    bl      common_abort
10372
10373
10374/* ------------------------------ */
10375    .balign 64
10376.L_OP_UNUSED_E9FF: /* 0x1e9 */
10377/* File: armv5te/OP_UNUSED_E9FF.S */
10378/* File: armv5te/unused.S */
10379    bl      common_abort
10380
10381
10382/* ------------------------------ */
10383    .balign 64
10384.L_OP_UNUSED_EAFF: /* 0x1ea */
10385/* File: armv5te/OP_UNUSED_EAFF.S */
10386/* File: armv5te/unused.S */
10387    bl      common_abort
10388
10389
10390/* ------------------------------ */
10391    .balign 64
10392.L_OP_UNUSED_EBFF: /* 0x1eb */
10393/* File: armv5te/OP_UNUSED_EBFF.S */
10394/* File: armv5te/unused.S */
10395    bl      common_abort
10396
10397
10398/* ------------------------------ */
10399    .balign 64
10400.L_OP_UNUSED_ECFF: /* 0x1ec */
10401/* File: armv5te/OP_UNUSED_ECFF.S */
10402/* File: armv5te/unused.S */
10403    bl      common_abort
10404
10405
10406/* ------------------------------ */
10407    .balign 64
10408.L_OP_UNUSED_EDFF: /* 0x1ed */
10409/* File: armv5te/OP_UNUSED_EDFF.S */
10410/* File: armv5te/unused.S */
10411    bl      common_abort
10412
10413
10414/* ------------------------------ */
10415    .balign 64
10416.L_OP_UNUSED_EEFF: /* 0x1ee */
10417/* File: armv5te/OP_UNUSED_EEFF.S */
10418/* File: armv5te/unused.S */
10419    bl      common_abort
10420
10421
10422/* ------------------------------ */
10423    .balign 64
10424.L_OP_UNUSED_EFFF: /* 0x1ef */
10425/* File: armv5te/OP_UNUSED_EFFF.S */
10426/* File: armv5te/unused.S */
10427    bl      common_abort
10428
10429
10430/* ------------------------------ */
10431    .balign 64
10432.L_OP_UNUSED_F0FF: /* 0x1f0 */
10433/* File: armv5te/OP_UNUSED_F0FF.S */
10434/* File: armv5te/unused.S */
10435    bl      common_abort
10436
10437
10438/* ------------------------------ */
10439    .balign 64
10440.L_OP_UNUSED_F1FF: /* 0x1f1 */
10441/* File: armv5te/OP_UNUSED_F1FF.S */
10442/* File: armv5te/unused.S */
10443    bl      common_abort
10444
10445
10446/* ------------------------------ */
10447    .balign 64
10448.L_OP_UNUSED_F2FF: /* 0x1f2 */
10449/* File: armv5te/OP_UNUSED_F2FF.S */
10450/* File: armv5te/unused.S */
10451    bl      common_abort
10452
10453
10454/* ------------------------------ */
10455    .balign 64
10456.L_OP_UNUSED_F3FF: /* 0x1f3 */
10457/* File: armv5te/OP_UNUSED_F3FF.S */
10458/* File: armv5te/unused.S */
10459    bl      common_abort
10460
10461
10462/* ------------------------------ */
10463    .balign 64
10464.L_OP_UNUSED_F4FF: /* 0x1f4 */
10465/* File: armv5te/OP_UNUSED_F4FF.S */
10466/* File: armv5te/unused.S */
10467    bl      common_abort
10468
10469
10470/* ------------------------------ */
10471    .balign 64
10472.L_OP_UNUSED_F5FF: /* 0x1f5 */
10473/* File: armv5te/OP_UNUSED_F5FF.S */
10474/* File: armv5te/unused.S */
10475    bl      common_abort
10476
10477
10478/* ------------------------------ */
10479    .balign 64
10480.L_OP_UNUSED_F6FF: /* 0x1f6 */
10481/* File: armv5te/OP_UNUSED_F6FF.S */
10482/* File: armv5te/unused.S */
10483    bl      common_abort
10484
10485
10486/* ------------------------------ */
10487    .balign 64
10488.L_OP_UNUSED_F7FF: /* 0x1f7 */
10489/* File: armv5te/OP_UNUSED_F7FF.S */
10490/* File: armv5te/unused.S */
10491    bl      common_abort
10492
10493
10494/* ------------------------------ */
10495    .balign 64
10496.L_OP_UNUSED_F8FF: /* 0x1f8 */
10497/* File: armv5te/OP_UNUSED_F8FF.S */
10498/* File: armv5te/unused.S */
10499    bl      common_abort
10500
10501
10502/* ------------------------------ */
10503    .balign 64
10504.L_OP_UNUSED_F9FF: /* 0x1f9 */
10505/* File: armv5te/OP_UNUSED_F9FF.S */
10506/* File: armv5te/unused.S */
10507    bl      common_abort
10508
10509
10510/* ------------------------------ */
10511    .balign 64
10512.L_OP_UNUSED_FAFF: /* 0x1fa */
10513/* File: armv5te/OP_UNUSED_FAFF.S */
10514/* File: armv5te/unused.S */
10515    bl      common_abort
10516
10517
10518/* ------------------------------ */
10519    .balign 64
10520.L_OP_UNUSED_FBFF: /* 0x1fb */
10521/* File: armv5te/OP_UNUSED_FBFF.S */
10522/* File: armv5te/unused.S */
10523    bl      common_abort
10524
10525
10526/* ------------------------------ */
10527    .balign 64
10528.L_OP_UNUSED_FCFF: /* 0x1fc */
10529/* File: armv5te/OP_UNUSED_FCFF.S */
10530/* File: armv5te/unused.S */
10531    bl      common_abort
10532
10533
10534/* ------------------------------ */
10535    .balign 64
10536.L_OP_UNUSED_FDFF: /* 0x1fd */
10537/* File: armv5te/OP_UNUSED_FDFF.S */
10538/* File: armv5te/unused.S */
10539    bl      common_abort
10540
10541
10542/* ------------------------------ */
10543    .balign 64
10544.L_OP_UNUSED_FEFF: /* 0x1fe */
10545/* File: armv5te/OP_UNUSED_FEFF.S */
10546/* File: armv5te/unused.S */
10547    bl      common_abort
10548
10549
10550/* ------------------------------ */
10551    .balign 64
10552.L_OP_THROW_VERIFICATION_ERROR_JUMBO: /* 0x1ff */
10553/* File: armv5te/OP_THROW_VERIFICATION_ERROR_JUMBO.S */
10554    /*
10555     * Handle a jumbo throw-verification-error instruction.  This throws an
10556     * exception for an error discovered during verification.  The
10557     * exception is indicated by BBBB, with some detail provided by AAAAAAAA.
10558     */
10559    /* exop BBBB, Class@AAAAAAAA */
10560    FETCH(r1, 1)                        @ r1<- aaaa (lo)
10561    FETCH(r2, 2)                        @ r2<- AAAA (hi)
10562    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
10563    orr     r2, r1, r2, lsl #16         @ r2<- AAAAaaaa
10564    EXPORT_PC()                         @ export the PC
10565    FETCH(r1, 3)                        @ r1<- BBBB
10566    bl      dvmThrowVerificationError   @ always throws
10567    b       common_exceptionThrown      @ handle exception
10568
10569
10570    .balign 64
10571    .size   dvmAsmInstructionStart, .-dvmAsmInstructionStart
10572    .global dvmAsmInstructionEnd
10573dvmAsmInstructionEnd:
10574
10575/*
10576 * ===========================================================================
10577 *  Sister implementations
10578 * ===========================================================================
10579 */
10580    .global dvmAsmSisterStart
10581    .type   dvmAsmSisterStart, %function
10582    .text
10583    .balign 4
10584dvmAsmSisterStart:
10585
10586/* continuation for OP_CONST_STRING */
10587
10588    /*
10589     * Continuation if the String has not yet been resolved.
10590     *  r1: BBBB (String ref)
10591     *  r9: target register
10592     */
10593.LOP_CONST_STRING_resolve:
10594    EXPORT_PC()
10595    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
10596    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10597    bl      dvmResolveString            @ r0<- String reference
10598    cmp     r0, #0                      @ failed?
10599    beq     common_exceptionThrown      @ yup, handle the exception
10600    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10601    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10602    SET_VREG(r0, r9)                    @ vAA<- r0
10603    GOTO_OPCODE(ip)                     @ jump to next instruction
10604
10605/* continuation for OP_CONST_STRING_JUMBO */
10606
10607    /*
10608     * Continuation if the String has not yet been resolved.
10609     *  r1: BBBBBBBB (String ref)
10610     *  r9: target register
10611     */
10612.LOP_CONST_STRING_JUMBO_resolve:
10613    EXPORT_PC()
10614    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
10615    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10616    bl      dvmResolveString            @ r0<- String reference
10617    cmp     r0, #0                      @ failed?
10618    beq     common_exceptionThrown      @ yup, handle the exception
10619    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
10620    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10621    SET_VREG(r0, r9)                    @ vAA<- r0
10622    GOTO_OPCODE(ip)                     @ jump to next instruction
10623
10624/* continuation for OP_CONST_CLASS */
10625
10626    /*
10627     * Continuation if the Class has not yet been resolved.
10628     *  r1: BBBB (Class ref)
10629     *  r9: target register
10630     */
10631.LOP_CONST_CLASS_resolve:
10632    EXPORT_PC()
10633    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
10634    mov     r2, #1                      @ r2<- true
10635    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10636    bl      dvmResolveClass             @ r0<- Class reference
10637    cmp     r0, #0                      @ failed?
10638    beq     common_exceptionThrown      @ yup, handle the exception
10639    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10640    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10641    SET_VREG(r0, r9)                    @ vAA<- r0
10642    GOTO_OPCODE(ip)                     @ jump to next instruction
10643
10644/* continuation for OP_CHECK_CAST */
10645
10646    /*
10647     * Trivial test failed, need to perform full check.  This is common.
10648     *  r0 holds obj->clazz
10649     *  r1 holds desired class resolved from BBBB
10650     *  r9 holds object
10651     */
10652.LOP_CHECK_CAST_fullcheck:
10653    mov     r10, r1                     @ avoid ClassObject getting clobbered
10654    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
10655    cmp     r0, #0                      @ failed?
10656    bne     .LOP_CHECK_CAST_okay            @ no, success
10657
10658    @ A cast has failed.  We need to throw a ClassCastException.
10659    EXPORT_PC()                         @ about to throw
10660    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
10661    mov     r1, r10                     @ r1<- desired class
10662    bl      dvmThrowClassCastException
10663    b       common_exceptionThrown
10664
10665    /*
10666     * Resolution required.  This is the least-likely path.
10667     *
10668     *  r2 holds BBBB
10669     *  r9 holds object
10670     */
10671.LOP_CHECK_CAST_resolve:
10672    EXPORT_PC()                         @ resolve() could throw
10673    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
10674    mov     r1, r2                      @ r1<- BBBB
10675    mov     r2, #0                      @ r2<- false
10676    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10677    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10678    cmp     r0, #0                      @ got null?
10679    beq     common_exceptionThrown      @ yes, handle exception
10680    mov     r1, r0                      @ r1<- class resolved from BBB
10681    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
10682    b       .LOP_CHECK_CAST_resolved        @ pick up where we left off
10683
10684/* continuation for OP_INSTANCE_OF */
10685
10686    /*
10687     * Trivial test failed, need to perform full check.  This is common.
10688     *  r0 holds obj->clazz
10689     *  r1 holds class resolved from BBBB
10690     *  r9 holds A
10691     */
10692.LOP_INSTANCE_OF_fullcheck:
10693    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
10694    @ fall through to OP_INSTANCE_OF_store
10695
10696    /*
10697     * r0 holds boolean result
10698     * r9 holds A
10699     */
10700.LOP_INSTANCE_OF_store:
10701    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10702    SET_VREG(r0, r9)                    @ vA<- r0
10703    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10704    GOTO_OPCODE(ip)                     @ jump to next instruction
10705
10706    /*
10707     * Trivial test succeeded, save and bail.
10708     *  r9 holds A
10709     */
10710.LOP_INSTANCE_OF_trivial:
10711    mov     r0, #1                      @ indicate success
10712    @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper
10713    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10714    SET_VREG(r0, r9)                    @ vA<- r0
10715    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10716    GOTO_OPCODE(ip)                     @ jump to next instruction
10717
10718    /*
10719     * Resolution required.  This is the least-likely path.
10720     *
10721     *  r3 holds BBBB
10722     *  r9 holds A
10723     */
10724.LOP_INSTANCE_OF_resolve:
10725    EXPORT_PC()                         @ resolve() could throw
10726    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
10727    mov     r1, r3                      @ r1<- BBBB
10728    mov     r2, #1                      @ r2<- true
10729    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10730    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10731    cmp     r0, #0                      @ got null?
10732    beq     common_exceptionThrown      @ yes, handle exception
10733    mov     r1, r0                      @ r1<- class resolved from BBB
10734    mov     r3, rINST, lsr #12          @ r3<- B
10735    GET_VREG(r0, r3)                    @ r0<- vB (object)
10736    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
10737    b       .LOP_INSTANCE_OF_resolved        @ pick up where we left off
10738
10739/* continuation for OP_NEW_INSTANCE */
10740
10741    .balign 32                          @ minimize cache lines
10742.LOP_NEW_INSTANCE_finish: @ r0=new object
10743    mov     r3, rINST, lsr #8           @ r3<- AA
10744    cmp     r0, #0                      @ failed?
10745    beq     common_exceptionThrown      @ yes, handle the exception
10746    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10747    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10748    SET_VREG(r0, r3)                    @ vAA<- r0
10749    GOTO_OPCODE(ip)                     @ jump to next instruction
10750
10751    /*
10752     * Class initialization required.
10753     *
10754     *  r0 holds class object
10755     */
10756.LOP_NEW_INSTANCE_needinit:
10757    mov     r9, r0                      @ save r0
10758    bl      dvmInitClass                @ initialize class
10759    cmp     r0, #0                      @ check boolean result
10760    mov     r0, r9                      @ restore r0
10761    bne     .LOP_NEW_INSTANCE_initialized     @ success, continue
10762    b       common_exceptionThrown      @ failed, deal with init exception
10763
10764    /*
10765     * Resolution required.  This is the least-likely path.
10766     *
10767     *  r1 holds BBBB
10768     */
10769.LOP_NEW_INSTANCE_resolve:
10770    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
10771    mov     r2, #0                      @ r2<- false
10772    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10773    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10774    cmp     r0, #0                      @ got null?
10775    bne     .LOP_NEW_INSTANCE_resolved        @ no, continue
10776    b       common_exceptionThrown      @ yes, handle exception
10777
10778.LstrInstantiationErrorPtr:
10779    .word   .LstrInstantiationError
10780
10781/* continuation for OP_NEW_ARRAY */
10782
10783
10784    /*
10785     * Resolve class.  (This is an uncommon case.)
10786     *
10787     *  r1 holds array length
10788     *  r2 holds class ref CCCC
10789     */
10790.LOP_NEW_ARRAY_resolve:
10791    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
10792    mov     r9, r1                      @ r9<- length (save)
10793    mov     r1, r2                      @ r1<- CCCC
10794    mov     r2, #0                      @ r2<- false
10795    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10796    bl      dvmResolveClass             @ r0<- call(clazz, ref)
10797    cmp     r0, #0                      @ got null?
10798    mov     r1, r9                      @ r1<- length (restore)
10799    beq     common_exceptionThrown      @ yes, handle exception
10800    @ fall through to OP_NEW_ARRAY_finish
10801
10802    /*
10803     * Finish allocation.
10804     *
10805     *  r0 holds class
10806     *  r1 holds array length
10807     */
10808.LOP_NEW_ARRAY_finish:
10809    mov     r2, #ALLOC_DONT_TRACK       @ don't track in local refs table
10810    bl      dvmAllocArrayByClass        @ r0<- call(clazz, length, flags)
10811    cmp     r0, #0                      @ failed?
10812    mov     r2, rINST, lsr #8           @ r2<- A+
10813    beq     common_exceptionThrown      @ yes, handle the exception
10814    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10815    and     r2, r2, #15                 @ r2<- A
10816    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10817    SET_VREG(r0, r2)                    @ vA<- r0
10818    GOTO_OPCODE(ip)                     @ jump to next instruction
10819
10820/* continuation for OP_FILLED_NEW_ARRAY */
10821
10822    /*
10823     * On entry:
10824     *  r0 holds array class
10825     *  r10 holds AA or BA
10826     */
10827.LOP_FILLED_NEW_ARRAY_continue:
10828    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
10829    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
10830    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
10831    .if     0
10832    mov     r1, r10                     @ r1<- AA (length)
10833    .else
10834    mov     r1, r10, lsr #4             @ r1<- B (length)
10835    .endif
10836    cmp     rINST, #'I'                 @ array of ints?
10837    cmpne   rINST, #'L'                 @ array of objects?
10838    cmpne   rINST, #'['                 @ array of arrays?
10839    mov     r9, r1                      @ save length in r9
10840    bne     .LOP_FILLED_NEW_ARRAY_notimpl         @ no, not handled yet
10841    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
10842    cmp     r0, #0                      @ null return?
10843    beq     common_exceptionThrown      @ alloc failed, handle exception
10844
10845    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
10846    str     r0, [rGLUE, #offGlue_retval]      @ retval.l <- new array
10847    str     rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type
10848    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
10849    subs    r9, r9, #1                  @ length--, check for neg
10850    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
10851    bmi     2f                          @ was zero, bail
10852
10853    @ copy values from registers into the array
10854    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
10855    .if     0
10856    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
108571:  ldr     r3, [r2], #4                @ r3<- *r2++
10858    subs    r9, r9, #1                  @ count--
10859    str     r3, [r0], #4                @ *contents++ = vX
10860    bpl     1b
10861    @ continue at 2
10862    .else
10863    cmp     r9, #4                      @ length was initially 5?
10864    and     r2, r10, #15                @ r2<- A
10865    bne     1f                          @ <= 4 args, branch
10866    GET_VREG(r3, r2)                    @ r3<- vA
10867    sub     r9, r9, #1                  @ count--
10868    str     r3, [r0, #16]               @ contents[4] = vA
108691:  and     r2, r1, #15                 @ r2<- F/E/D/C
10870    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
10871    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
10872    subs    r9, r9, #1                  @ count--
10873    str     r3, [r0], #4                @ *contents++ = vX
10874    bpl     1b
10875    @ continue at 2
10876    .endif
10877
108782:
10879    ldr     r0, [rGLUE, #offGlue_retval]     @ r0<- object
10880    ldr     r1, [rGLUE, #offGlue_retval+4]   @ r1<- type
10881    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
10882    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
10883    cmp     r1, #'I'                         @ Is int array?
10884    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
10885    GOTO_OPCODE(ip)                          @ execute it
10886
10887    /*
10888     * Throw an exception indicating that we have not implemented this
10889     * mode of filled-new-array.
10890     */
10891.LOP_FILLED_NEW_ARRAY_notimpl:
10892    ldr     r0, .L_strInternalError
10893    ldr     r1, .L_strFilledNewArrayNotImpl
10894    bl      dvmThrowException
10895    b       common_exceptionThrown
10896
10897    .if     (!0)                 @ define in one or the other, not both
10898.L_strFilledNewArrayNotImpl:
10899    .word   .LstrFilledNewArrayNotImpl
10900.L_strInternalError:
10901    .word   .LstrInternalError
10902    .endif
10903
10904/* continuation for OP_FILLED_NEW_ARRAY_RANGE */
10905
10906    /*
10907     * On entry:
10908     *  r0 holds array class
10909     *  r10 holds AA or BA
10910     */
10911.LOP_FILLED_NEW_ARRAY_RANGE_continue:
10912    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
10913    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
10914    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
10915    .if     1
10916    mov     r1, r10                     @ r1<- AA (length)
10917    .else
10918    mov     r1, r10, lsr #4             @ r1<- B (length)
10919    .endif
10920    cmp     rINST, #'I'                 @ array of ints?
10921    cmpne   rINST, #'L'                 @ array of objects?
10922    cmpne   rINST, #'['                 @ array of arrays?
10923    mov     r9, r1                      @ save length in r9
10924    bne     .LOP_FILLED_NEW_ARRAY_RANGE_notimpl         @ no, not handled yet
10925    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
10926    cmp     r0, #0                      @ null return?
10927    beq     common_exceptionThrown      @ alloc failed, handle exception
10928
10929    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
10930    str     r0, [rGLUE, #offGlue_retval]      @ retval.l <- new array
10931    str     rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type
10932    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
10933    subs    r9, r9, #1                  @ length--, check for neg
10934    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
10935    bmi     2f                          @ was zero, bail
10936
10937    @ copy values from registers into the array
10938    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
10939    .if     1
10940    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
109411:  ldr     r3, [r2], #4                @ r3<- *r2++
10942    subs    r9, r9, #1                  @ count--
10943    str     r3, [r0], #4                @ *contents++ = vX
10944    bpl     1b
10945    @ continue at 2
10946    .else
10947    cmp     r9, #4                      @ length was initially 5?
10948    and     r2, r10, #15                @ r2<- A
10949    bne     1f                          @ <= 4 args, branch
10950    GET_VREG(r3, r2)                    @ r3<- vA
10951    sub     r9, r9, #1                  @ count--
10952    str     r3, [r0, #16]               @ contents[4] = vA
109531:  and     r2, r1, #15                 @ r2<- F/E/D/C
10954    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
10955    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
10956    subs    r9, r9, #1                  @ count--
10957    str     r3, [r0], #4                @ *contents++ = vX
10958    bpl     1b
10959    @ continue at 2
10960    .endif
10961
109622:
10963    ldr     r0, [rGLUE, #offGlue_retval]     @ r0<- object
10964    ldr     r1, [rGLUE, #offGlue_retval+4]   @ r1<- type
10965    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
10966    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
10967    cmp     r1, #'I'                         @ Is int array?
10968    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
10969    GOTO_OPCODE(ip)                          @ execute it
10970
10971    /*
10972     * Throw an exception indicating that we have not implemented this
10973     * mode of filled-new-array.
10974     */
10975.LOP_FILLED_NEW_ARRAY_RANGE_notimpl:
10976    ldr     r0, .L_strInternalError
10977    ldr     r1, .L_strFilledNewArrayNotImpl
10978    bl      dvmThrowException
10979    b       common_exceptionThrown
10980
10981    .if     (!1)                 @ define in one or the other, not both
10982.L_strFilledNewArrayNotImpl:
10983    .word   .LstrFilledNewArrayNotImpl
10984.L_strInternalError:
10985    .word   .LstrInternalError
10986    .endif
10987
10988/* continuation for OP_CMPL_FLOAT */
10989.LOP_CMPL_FLOAT_finish:
10990    SET_VREG(r0, r9)                    @ vAA<- r0
10991    GOTO_OPCODE(ip)                     @ jump to next instruction
10992
10993/* continuation for OP_CMPG_FLOAT */
10994.LOP_CMPG_FLOAT_finish:
10995    SET_VREG(r0, r9)                    @ vAA<- r0
10996    GOTO_OPCODE(ip)                     @ jump to next instruction
10997
10998/* continuation for OP_CMPL_DOUBLE */
10999.LOP_CMPL_DOUBLE_finish:
11000    SET_VREG(r0, r9)                    @ vAA<- r0
11001    GOTO_OPCODE(ip)                     @ jump to next instruction
11002
11003/* continuation for OP_CMPG_DOUBLE */
11004.LOP_CMPG_DOUBLE_finish:
11005    SET_VREG(r0, r9)                    @ vAA<- r0
11006    GOTO_OPCODE(ip)                     @ jump to next instruction
11007
11008/* continuation for OP_CMP_LONG */
11009
11010.LOP_CMP_LONG_less:
11011    mvn     r1, #0                      @ r1<- -1
11012    @ Want to cond code the next mov so we can avoid branch, but don't see it;
11013    @ instead, we just replicate the tail end.
11014    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11015    SET_VREG(r1, r9)                    @ vAA<- r1
11016    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11017    GOTO_OPCODE(ip)                     @ jump to next instruction
11018
11019.LOP_CMP_LONG_greater:
11020    mov     r1, #1                      @ r1<- 1
11021    @ fall through to _finish
11022
11023.LOP_CMP_LONG_finish:
11024    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11025    SET_VREG(r1, r9)                    @ vAA<- r1
11026    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11027    GOTO_OPCODE(ip)                     @ jump to next instruction
11028
11029/* continuation for OP_AGET_WIDE */
11030
11031.LOP_AGET_WIDE_finish:
11032    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11033    ldrd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
11034    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
11035    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11036    stmia   r9, {r2-r3}                 @ vAA/vAA+1<- r2/r3
11037    GOTO_OPCODE(ip)                     @ jump to next instruction
11038
11039/* continuation for OP_APUT_WIDE */
11040
11041.LOP_APUT_WIDE_finish:
11042    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11043    ldmia   r9, {r2-r3}                 @ r2/r3<- vAA/vAA+1
11044    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11045    strd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
11046    GOTO_OPCODE(ip)                     @ jump to next instruction
11047
11048/* continuation for OP_APUT_OBJECT */
11049    /*
11050     * On entry:
11051     *  rINST = vBB (arrayObj)
11052     *  r9 = vAA (obj)
11053     *  r10 = offset into array (vBB + vCC * width)
11054     */
11055.LOP_APUT_OBJECT_finish:
11056    cmp     r9, #0                      @ storing null reference?
11057    beq     .LOP_APUT_OBJECT_skip_check      @ yes, skip type checks
11058    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
11059    ldr     r1, [rINST, #offObject_clazz]  @ r1<- arrayObj->clazz
11060    bl      dvmCanPutArrayElement       @ test object type vs. array type
11061    cmp     r0, #0                      @ okay?
11062    beq     .LOP_APUT_OBJECT_throw           @ no
11063    mov     r1, rINST                   @ r1<- arrayObj
11064    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11065    ldr     r2, [rGLUE, #offGlue_cardTable]     @ get biased CT base
11066    add     r10, #offArrayObject_contents   @ r0<- pointer to slot
11067    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11068    str     r9, [r10]                   @ vBB[vCC]<- vAA
11069    strb    r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head
11070    GOTO_OPCODE(ip)                     @ jump to next instruction
11071.LOP_APUT_OBJECT_skip_check:
11072    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11073    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11074    str     r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA
11075    GOTO_OPCODE(ip)                     @ jump to next instruction
11076.LOP_APUT_OBJECT_throw:
11077    @ The types don't match.  We need to throw an ArrayStoreException.
11078    ldr     r0, [r9, #offObject_clazz]
11079    ldr     r1, [rINST, #offObject_clazz]
11080    EXPORT_PC()
11081    bl      dvmThrowArrayStoreException
11082    b       common_exceptionThrown
11083
11084/* continuation for OP_IGET */
11085
11086    /*
11087     * Currently:
11088     *  r0 holds resolved field
11089     *  r9 holds object
11090     */
11091.LOP_IGET_finish:
11092    @bl      common_squeak0
11093    cmp     r9, #0                      @ check object for null
11094    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11095    beq     common_errNullObject        @ object was null
11096    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11097    @ no-op                             @ acquiring load
11098    mov     r2, rINST, lsr #8           @ r2<- A+
11099    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11100    and     r2, r2, #15                 @ r2<- A
11101    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11102    SET_VREG(r0, r2)                    @ fp[A]<- r0
11103    GOTO_OPCODE(ip)                     @ jump to next instruction
11104
11105/* continuation for OP_IGET_WIDE */
11106
11107    /*
11108     * Currently:
11109     *  r0 holds resolved field
11110     *  r9 holds object
11111     */
11112.LOP_IGET_WIDE_finish:
11113    cmp     r9, #0                      @ check object for null
11114    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11115    beq     common_errNullObject        @ object was null
11116    .if     0
11117    add     r0, r9, r3                  @ r0<- address of field
11118    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
11119    .else
11120    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
11121    .endif
11122    mov     r2, rINST, lsr #8           @ r2<- A+
11123    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11124    and     r2, r2, #15                 @ r2<- A
11125    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
11126    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11127    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
11128    GOTO_OPCODE(ip)                     @ jump to next instruction
11129
11130/* continuation for OP_IGET_OBJECT */
11131
11132    /*
11133     * Currently:
11134     *  r0 holds resolved field
11135     *  r9 holds object
11136     */
11137.LOP_IGET_OBJECT_finish:
11138    @bl      common_squeak0
11139    cmp     r9, #0                      @ check object for null
11140    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11141    beq     common_errNullObject        @ object was null
11142    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11143    @ no-op                             @ acquiring load
11144    mov     r2, rINST, lsr #8           @ r2<- A+
11145    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11146    and     r2, r2, #15                 @ r2<- A
11147    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11148    SET_VREG(r0, r2)                    @ fp[A]<- r0
11149    GOTO_OPCODE(ip)                     @ jump to next instruction
11150
11151/* continuation for OP_IGET_BOOLEAN */
11152
11153    /*
11154     * Currently:
11155     *  r0 holds resolved field
11156     *  r9 holds object
11157     */
11158.LOP_IGET_BOOLEAN_finish:
11159    @bl      common_squeak1
11160    cmp     r9, #0                      @ check object for null
11161    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11162    beq     common_errNullObject        @ object was null
11163    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11164    @ no-op                             @ acquiring load
11165    mov     r2, rINST, lsr #8           @ r2<- A+
11166    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11167    and     r2, r2, #15                 @ r2<- A
11168    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11169    SET_VREG(r0, r2)                    @ fp[A]<- r0
11170    GOTO_OPCODE(ip)                     @ jump to next instruction
11171
11172/* continuation for OP_IGET_BYTE */
11173
11174    /*
11175     * Currently:
11176     *  r0 holds resolved field
11177     *  r9 holds object
11178     */
11179.LOP_IGET_BYTE_finish:
11180    @bl      common_squeak2
11181    cmp     r9, #0                      @ check object for null
11182    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11183    beq     common_errNullObject        @ object was null
11184    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11185    @ no-op                             @ acquiring load
11186    mov     r2, rINST, lsr #8           @ r2<- A+
11187    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11188    and     r2, r2, #15                 @ r2<- A
11189    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11190    SET_VREG(r0, r2)                    @ fp[A]<- r0
11191    GOTO_OPCODE(ip)                     @ jump to next instruction
11192
11193/* continuation for OP_IGET_CHAR */
11194
11195    /*
11196     * Currently:
11197     *  r0 holds resolved field
11198     *  r9 holds object
11199     */
11200.LOP_IGET_CHAR_finish:
11201    @bl      common_squeak3
11202    cmp     r9, #0                      @ check object for null
11203    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11204    beq     common_errNullObject        @ object was null
11205    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11206    @ no-op                             @ acquiring load
11207    mov     r2, rINST, lsr #8           @ r2<- A+
11208    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11209    and     r2, r2, #15                 @ r2<- A
11210    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11211    SET_VREG(r0, r2)                    @ fp[A]<- r0
11212    GOTO_OPCODE(ip)                     @ jump to next instruction
11213
11214/* continuation for OP_IGET_SHORT */
11215
11216    /*
11217     * Currently:
11218     *  r0 holds resolved field
11219     *  r9 holds object
11220     */
11221.LOP_IGET_SHORT_finish:
11222    @bl      common_squeak4
11223    cmp     r9, #0                      @ check object for null
11224    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11225    beq     common_errNullObject        @ object was null
11226    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11227    @ no-op                             @ acquiring load
11228    mov     r2, rINST, lsr #8           @ r2<- A+
11229    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11230    and     r2, r2, #15                 @ r2<- A
11231    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11232    SET_VREG(r0, r2)                    @ fp[A]<- r0
11233    GOTO_OPCODE(ip)                     @ jump to next instruction
11234
11235/* continuation for OP_IPUT */
11236
11237    /*
11238     * Currently:
11239     *  r0 holds resolved field
11240     *  r9 holds object
11241     */
11242.LOP_IPUT_finish:
11243    @bl      common_squeak0
11244    mov     r1, rINST, lsr #8           @ r1<- A+
11245    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11246    and     r1, r1, #15                 @ r1<- A
11247    cmp     r9, #0                      @ check object for null
11248    GET_VREG(r0, r1)                    @ r0<- fp[A]
11249    beq     common_errNullObject        @ object was null
11250    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11251    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11252    @ no-op                             @ releasing store
11253    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11254    GOTO_OPCODE(ip)                     @ jump to next instruction
11255
11256/* continuation for OP_IPUT_WIDE */
11257
11258    /*
11259     * Currently:
11260     *  r0 holds resolved field
11261     *  r9 holds object
11262     */
11263.LOP_IPUT_WIDE_finish:
11264    mov     r2, rINST, lsr #8           @ r2<- A+
11265    cmp     r9, #0                      @ check object for null
11266    and     r2, r2, #15                 @ r2<- A
11267    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11268    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
11269    beq     common_errNullObject        @ object was null
11270    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11271    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
11272    GET_INST_OPCODE(r10)                @ extract opcode from rINST
11273    .if     0
11274    add     r2, r9, r3                  @ r2<- target address
11275    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
11276    .else
11277    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
11278    .endif
11279    GOTO_OPCODE(r10)                    @ jump to next instruction
11280
11281/* continuation for OP_IPUT_OBJECT */
11282
11283    /*
11284     * Currently:
11285     *  r0 holds resolved field
11286     *  r9 holds object
11287     */
11288.LOP_IPUT_OBJECT_finish:
11289    @bl      common_squeak0
11290    mov     r1, rINST, lsr #8           @ r1<- A+
11291    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11292    and     r1, r1, #15                 @ r1<- A
11293    cmp     r9, #0                      @ check object for null
11294    GET_VREG(r0, r1)                    @ r0<- fp[A]
11295    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
11296    beq     common_errNullObject        @ object was null
11297    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11298    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11299    @ no-op                             @ releasing store
11300    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
11301    cmp     r0, #0                      @ stored a null reference?
11302    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
11303    GOTO_OPCODE(ip)                     @ jump to next instruction
11304
11305/* continuation for OP_IPUT_BOOLEAN */
11306
11307    /*
11308     * Currently:
11309     *  r0 holds resolved field
11310     *  r9 holds object
11311     */
11312.LOP_IPUT_BOOLEAN_finish:
11313    @bl      common_squeak1
11314    mov     r1, rINST, lsr #8           @ r1<- A+
11315    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11316    and     r1, r1, #15                 @ r1<- A
11317    cmp     r9, #0                      @ check object for null
11318    GET_VREG(r0, r1)                    @ r0<- fp[A]
11319    beq     common_errNullObject        @ object was null
11320    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11321    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11322    @ no-op                             @ releasing store
11323    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11324    GOTO_OPCODE(ip)                     @ jump to next instruction
11325
11326/* continuation for OP_IPUT_BYTE */
11327
11328    /*
11329     * Currently:
11330     *  r0 holds resolved field
11331     *  r9 holds object
11332     */
11333.LOP_IPUT_BYTE_finish:
11334    @bl      common_squeak2
11335    mov     r1, rINST, lsr #8           @ r1<- A+
11336    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11337    and     r1, r1, #15                 @ r1<- A
11338    cmp     r9, #0                      @ check object for null
11339    GET_VREG(r0, r1)                    @ r0<- fp[A]
11340    beq     common_errNullObject        @ object was null
11341    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11342    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11343    @ no-op                             @ releasing store
11344    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11345    GOTO_OPCODE(ip)                     @ jump to next instruction
11346
11347/* continuation for OP_IPUT_CHAR */
11348
11349    /*
11350     * Currently:
11351     *  r0 holds resolved field
11352     *  r9 holds object
11353     */
11354.LOP_IPUT_CHAR_finish:
11355    @bl      common_squeak3
11356    mov     r1, rINST, lsr #8           @ r1<- A+
11357    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11358    and     r1, r1, #15                 @ r1<- A
11359    cmp     r9, #0                      @ check object for null
11360    GET_VREG(r0, r1)                    @ r0<- fp[A]
11361    beq     common_errNullObject        @ object was null
11362    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11363    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11364    @ no-op                             @ releasing store
11365    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11366    GOTO_OPCODE(ip)                     @ jump to next instruction
11367
11368/* continuation for OP_IPUT_SHORT */
11369
11370    /*
11371     * Currently:
11372     *  r0 holds resolved field
11373     *  r9 holds object
11374     */
11375.LOP_IPUT_SHORT_finish:
11376    @bl      common_squeak4
11377    mov     r1, rINST, lsr #8           @ r1<- A+
11378    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11379    and     r1, r1, #15                 @ r1<- A
11380    cmp     r9, #0                      @ check object for null
11381    GET_VREG(r0, r1)                    @ r0<- fp[A]
11382    beq     common_errNullObject        @ object was null
11383    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11384    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11385    @ no-op                             @ releasing store
11386    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11387    GOTO_OPCODE(ip)                     @ jump to next instruction
11388
11389/* continuation for OP_SGET */
11390
11391    /*
11392     * Continuation if the field has not yet been resolved.
11393     *  r1: BBBB field ref
11394     */
11395.LOP_SGET_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_finish          @ yes, finish
11402    b       common_exceptionThrown      @ no, handle exception
11403
11404/* continuation for OP_SGET_WIDE */
11405
11406    /*
11407     * Continuation if the field has not yet been resolved.
11408     *  r1: BBBB field ref
11409     *
11410     * Returns StaticField pointer in r0.
11411     */
11412.LOP_SGET_WIDE_resolve:
11413    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11414    EXPORT_PC()                         @ resolve() could throw, so export now
11415    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11416    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11417    cmp     r0, #0                      @ success?
11418    bne     .LOP_SGET_WIDE_finish          @ yes, finish
11419    b       common_exceptionThrown      @ no, handle exception
11420
11421/* continuation for OP_SGET_OBJECT */
11422
11423    /*
11424     * Continuation if the field has not yet been resolved.
11425     *  r1: BBBB field ref
11426     */
11427.LOP_SGET_OBJECT_resolve:
11428    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11429    EXPORT_PC()                         @ resolve() could throw, so export now
11430    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11431    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11432    cmp     r0, #0                      @ success?
11433    bne     .LOP_SGET_OBJECT_finish          @ yes, finish
11434    b       common_exceptionThrown      @ no, handle exception
11435
11436/* continuation for OP_SGET_BOOLEAN */
11437
11438    /*
11439     * Continuation if the field has not yet been resolved.
11440     *  r1: BBBB field ref
11441     */
11442.LOP_SGET_BOOLEAN_resolve:
11443    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11444    EXPORT_PC()                         @ resolve() could throw, so export now
11445    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11446    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11447    cmp     r0, #0                      @ success?
11448    bne     .LOP_SGET_BOOLEAN_finish          @ yes, finish
11449    b       common_exceptionThrown      @ no, handle exception
11450
11451/* continuation for OP_SGET_BYTE */
11452
11453    /*
11454     * Continuation if the field has not yet been resolved.
11455     *  r1: BBBB field ref
11456     */
11457.LOP_SGET_BYTE_resolve:
11458    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11459    EXPORT_PC()                         @ resolve() could throw, so export now
11460    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11461    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11462    cmp     r0, #0                      @ success?
11463    bne     .LOP_SGET_BYTE_finish          @ yes, finish
11464    b       common_exceptionThrown      @ no, handle exception
11465
11466/* continuation for OP_SGET_CHAR */
11467
11468    /*
11469     * Continuation if the field has not yet been resolved.
11470     *  r1: BBBB field ref
11471     */
11472.LOP_SGET_CHAR_resolve:
11473    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11474    EXPORT_PC()                         @ resolve() could throw, so export now
11475    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11476    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11477    cmp     r0, #0                      @ success?
11478    bne     .LOP_SGET_CHAR_finish          @ yes, finish
11479    b       common_exceptionThrown      @ no, handle exception
11480
11481/* continuation for OP_SGET_SHORT */
11482
11483    /*
11484     * Continuation if the field has not yet been resolved.
11485     *  r1: BBBB field ref
11486     */
11487.LOP_SGET_SHORT_resolve:
11488    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11489    EXPORT_PC()                         @ resolve() could throw, so export now
11490    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11491    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11492    cmp     r0, #0                      @ success?
11493    bne     .LOP_SGET_SHORT_finish          @ yes, finish
11494    b       common_exceptionThrown      @ no, handle exception
11495
11496/* continuation for OP_SPUT */
11497
11498    /*
11499     * Continuation if the field has not yet been resolved.
11500     *  r1: BBBB field ref
11501     */
11502.LOP_SPUT_resolve:
11503    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11504    EXPORT_PC()                         @ resolve() could throw, so export now
11505    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11506    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11507    cmp     r0, #0                      @ success?
11508    bne     .LOP_SPUT_finish          @ yes, finish
11509    b       common_exceptionThrown      @ no, handle exception
11510
11511/* continuation for OP_SPUT_WIDE */
11512
11513    /*
11514     * Continuation if the field has not yet been resolved.
11515     *  r1: BBBB field ref
11516     *  r9: &fp[AA]
11517     *
11518     * Returns StaticField pointer in r2.
11519     */
11520.LOP_SPUT_WIDE_resolve:
11521    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11522    EXPORT_PC()                         @ resolve() could throw, so export now
11523    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11524    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11525    cmp     r0, #0                      @ success?
11526    mov     r2, r0                      @ copy to r2
11527    bne     .LOP_SPUT_WIDE_finish          @ yes, finish
11528    b       common_exceptionThrown      @ no, handle exception
11529
11530/* continuation for OP_SPUT_OBJECT */
11531.LOP_SPUT_OBJECT_finish:   @ field ptr in r0
11532    mov     r2, rINST, lsr #8           @ r2<- AA
11533    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11534    GET_VREG(r1, r2)                    @ r1<- fp[AA]
11535    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
11536    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
11537    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11538    @ no-op                             @ releasing store
11539    str     r1, [r0, #offStaticField_value]  @ field<- vAA
11540    cmp     r1, #0                      @ stored a null object?
11541    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
11542    GOTO_OPCODE(ip)                     @ jump to next instruction
11543
11544/* continuation for OP_SPUT_BOOLEAN */
11545
11546    /*
11547     * Continuation if the field has not yet been resolved.
11548     *  r1: BBBB field ref
11549     */
11550.LOP_SPUT_BOOLEAN_resolve:
11551    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11552    EXPORT_PC()                         @ resolve() could throw, so export now
11553    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11554    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11555    cmp     r0, #0                      @ success?
11556    bne     .LOP_SPUT_BOOLEAN_finish          @ yes, finish
11557    b       common_exceptionThrown      @ no, handle exception
11558
11559/* continuation for OP_SPUT_BYTE */
11560
11561    /*
11562     * Continuation if the field has not yet been resolved.
11563     *  r1: BBBB field ref
11564     */
11565.LOP_SPUT_BYTE_resolve:
11566    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11567    EXPORT_PC()                         @ resolve() could throw, so export now
11568    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11569    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11570    cmp     r0, #0                      @ success?
11571    bne     .LOP_SPUT_BYTE_finish          @ yes, finish
11572    b       common_exceptionThrown      @ no, handle exception
11573
11574/* continuation for OP_SPUT_CHAR */
11575
11576    /*
11577     * Continuation if the field has not yet been resolved.
11578     *  r1: BBBB field ref
11579     */
11580.LOP_SPUT_CHAR_resolve:
11581    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11582    EXPORT_PC()                         @ resolve() could throw, so export now
11583    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11584    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11585    cmp     r0, #0                      @ success?
11586    bne     .LOP_SPUT_CHAR_finish          @ yes, finish
11587    b       common_exceptionThrown      @ no, handle exception
11588
11589/* continuation for OP_SPUT_SHORT */
11590
11591    /*
11592     * Continuation if the field has not yet been resolved.
11593     *  r1: BBBB field ref
11594     */
11595.LOP_SPUT_SHORT_resolve:
11596    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11597    EXPORT_PC()                         @ resolve() could throw, so export now
11598    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11599    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11600    cmp     r0, #0                      @ success?
11601    bne     .LOP_SPUT_SHORT_finish          @ yes, finish
11602    b       common_exceptionThrown      @ no, handle exception
11603
11604/* continuation for OP_INVOKE_VIRTUAL */
11605
11606    /*
11607     * At this point:
11608     *  r0 = resolved base method
11609     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
11610     */
11611.LOP_INVOKE_VIRTUAL_continue:
11612    GET_VREG(r1, r10)                   @ r1<- "this" ptr
11613    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11614    cmp     r1, #0                      @ is "this" null?
11615    beq     common_errNullObject        @ null "this", throw exception
11616    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
11617    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
11618    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
11619    bl      common_invokeMethodNoRange @ continue on
11620
11621/* continuation for OP_INVOKE_SUPER */
11622
11623    /*
11624     * At this point:
11625     *  r0 = resolved base method
11626     *  r9 = method->clazz
11627     */
11628.LOP_INVOKE_SUPER_continue:
11629    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
11630    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11631    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
11632    EXPORT_PC()                         @ must export for invoke
11633    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
11634    bcs     .LOP_INVOKE_SUPER_nsm             @ method not present in superclass
11635    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
11636    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
11637    bl      common_invokeMethodNoRange @ continue on
11638
11639.LOP_INVOKE_SUPER_resolve:
11640    mov     r0, r9                      @ r0<- method->clazz
11641    mov     r2, #METHOD_VIRTUAL         @ resolver method type
11642    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11643    cmp     r0, #0                      @ got null?
11644    bne     .LOP_INVOKE_SUPER_continue        @ no, continue
11645    b       common_exceptionThrown      @ yes, handle exception
11646
11647    /*
11648     * Throw a NoSuchMethodError with the method name as the message.
11649     *  r0 = resolved base method
11650     */
11651.LOP_INVOKE_SUPER_nsm:
11652    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
11653    b       common_errNoSuchMethod
11654
11655/* continuation for OP_INVOKE_DIRECT */
11656
11657    /*
11658     * On entry:
11659     *  r1 = reference (BBBB or CCCC)
11660     *  r10 = "this" register
11661     */
11662.LOP_INVOKE_DIRECT_resolve:
11663    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
11664    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
11665    mov     r2, #METHOD_DIRECT          @ resolver method type
11666    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11667    cmp     r0, #0                      @ got null?
11668    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
11669    bne     .LOP_INVOKE_DIRECT_finish          @ no, continue
11670    b       common_exceptionThrown      @ yes, handle exception
11671
11672/* continuation for OP_INVOKE_VIRTUAL_RANGE */
11673
11674    /*
11675     * At this point:
11676     *  r0 = resolved base method
11677     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
11678     */
11679.LOP_INVOKE_VIRTUAL_RANGE_continue:
11680    GET_VREG(r1, r10)                   @ r1<- "this" ptr
11681    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11682    cmp     r1, #0                      @ is "this" null?
11683    beq     common_errNullObject        @ null "this", throw exception
11684    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
11685    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
11686    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
11687    bl      common_invokeMethodRange @ continue on
11688
11689/* continuation for OP_INVOKE_SUPER_RANGE */
11690
11691    /*
11692     * At this point:
11693     *  r0 = resolved base method
11694     *  r9 = method->clazz
11695     */
11696.LOP_INVOKE_SUPER_RANGE_continue:
11697    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
11698    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11699    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
11700    EXPORT_PC()                         @ must export for invoke
11701    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
11702    bcs     .LOP_INVOKE_SUPER_RANGE_nsm             @ method not present in superclass
11703    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
11704    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
11705    bl      common_invokeMethodRange @ continue on
11706
11707.LOP_INVOKE_SUPER_RANGE_resolve:
11708    mov     r0, r9                      @ r0<- method->clazz
11709    mov     r2, #METHOD_VIRTUAL         @ resolver method type
11710    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11711    cmp     r0, #0                      @ got null?
11712    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ no, continue
11713    b       common_exceptionThrown      @ yes, handle exception
11714
11715    /*
11716     * Throw a NoSuchMethodError with the method name as the message.
11717     *  r0 = resolved base method
11718     */
11719.LOP_INVOKE_SUPER_RANGE_nsm:
11720    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
11721    b       common_errNoSuchMethod
11722
11723/* continuation for OP_INVOKE_DIRECT_RANGE */
11724
11725    /*
11726     * On entry:
11727     *  r1 = reference (BBBB or CCCC)
11728     *  r10 = "this" register
11729     */
11730.LOP_INVOKE_DIRECT_RANGE_resolve:
11731    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
11732    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
11733    mov     r2, #METHOD_DIRECT          @ resolver method type
11734    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11735    cmp     r0, #0                      @ got null?
11736    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
11737    bne     .LOP_INVOKE_DIRECT_RANGE_finish          @ no, continue
11738    b       common_exceptionThrown      @ yes, handle exception
11739
11740/* continuation for OP_FLOAT_TO_LONG */
11741/*
11742 * Convert the float in r0 to a long in r0/r1.
11743 *
11744 * We have to clip values to long min/max per the specification.  The
11745 * expected common case is a "reasonable" value that converts directly
11746 * to modest integer.  The EABI convert function isn't doing this for us.
11747 */
11748f2l_doconv:
11749    stmfd   sp!, {r4, lr}
11750    mov     r1, #0x5f000000             @ (float)maxlong
11751    mov     r4, r0
11752    bl      __aeabi_fcmpge              @ is arg >= maxlong?
11753    cmp     r0, #0                      @ nonzero == yes
11754    mvnne   r0, #0                      @ return maxlong (7fffffff)
11755    mvnne   r1, #0x80000000
11756    ldmnefd sp!, {r4, pc}
11757
11758    mov     r0, r4                      @ recover arg
11759    mov     r1, #0xdf000000             @ (float)minlong
11760    bl      __aeabi_fcmple              @ is arg <= minlong?
11761    cmp     r0, #0                      @ nonzero == yes
11762    movne   r0, #0                      @ return minlong (80000000)
11763    movne   r1, #0x80000000
11764    ldmnefd sp!, {r4, pc}
11765
11766    mov     r0, r4                      @ recover arg
11767    mov     r1, r4
11768    bl      __aeabi_fcmpeq              @ is arg == self?
11769    cmp     r0, #0                      @ zero == no
11770    moveq   r1, #0                      @ return zero for NaN
11771    ldmeqfd sp!, {r4, pc}
11772
11773    mov     r0, r4                      @ recover arg
11774    bl      __aeabi_f2lz                @ convert float to long
11775    ldmfd   sp!, {r4, pc}
11776
11777/* continuation for OP_DOUBLE_TO_LONG */
11778/*
11779 * Convert the double in r0/r1 to a long in r0/r1.
11780 *
11781 * We have to clip values to long min/max per the specification.  The
11782 * expected common case is a "reasonable" value that converts directly
11783 * to modest integer.  The EABI convert function isn't doing this for us.
11784 */
11785d2l_doconv:
11786    stmfd   sp!, {r4, r5, lr}           @ save regs
11787    mov     r3, #0x43000000             @ maxlong, as a double (high word)
11788    add     r3, #0x00e00000             @  0x43e00000
11789    mov     r2, #0                      @ maxlong, as a double (low word)
11790    sub     sp, sp, #4                  @ align for EABI
11791    mov     r4, r0                      @ save a copy of r0
11792    mov     r5, r1                      @  and r1
11793    bl      __aeabi_dcmpge              @ is arg >= maxlong?
11794    cmp     r0, #0                      @ nonzero == yes
11795    mvnne   r0, #0                      @ return maxlong (7fffffffffffffff)
11796    mvnne   r1, #0x80000000
11797    bne     1f
11798
11799    mov     r0, r4                      @ recover arg
11800    mov     r1, r5
11801    mov     r3, #0xc3000000             @ minlong, as a double (high word)
11802    add     r3, #0x00e00000             @  0xc3e00000
11803    mov     r2, #0                      @ minlong, as a double (low word)
11804    bl      __aeabi_dcmple              @ is arg <= minlong?
11805    cmp     r0, #0                      @ nonzero == yes
11806    movne   r0, #0                      @ return minlong (8000000000000000)
11807    movne   r1, #0x80000000
11808    bne     1f
11809
11810    mov     r0, r4                      @ recover arg
11811    mov     r1, r5
11812    mov     r2, r4                      @ compare against self
11813    mov     r3, r5
11814    bl      __aeabi_dcmpeq              @ is arg == self?
11815    cmp     r0, #0                      @ zero == no
11816    moveq   r1, #0                      @ return zero for NaN
11817    beq     1f
11818
11819    mov     r0, r4                      @ recover arg
11820    mov     r1, r5
11821    bl      __aeabi_d2lz                @ convert double to long
11822
118231:
11824    add     sp, sp, #4
11825    ldmfd   sp!, {r4, r5, pc}
11826
11827/* continuation for OP_MUL_LONG */
11828
11829.LOP_MUL_LONG_finish:
11830    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11831    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
11832    GOTO_OPCODE(ip)                     @ jump to next instruction
11833
11834/* continuation for OP_SHL_LONG */
11835
11836.LOP_SHL_LONG_finish:
11837    mov     r0, r0, asl r2              @  r0<- r0 << r2
11838    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11839    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11840    GOTO_OPCODE(ip)                     @ jump to next instruction
11841
11842/* continuation for OP_SHR_LONG */
11843
11844.LOP_SHR_LONG_finish:
11845    mov     r1, r1, asr r2              @  r1<- r1 >> r2
11846    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11847    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11848    GOTO_OPCODE(ip)                     @ jump to next instruction
11849
11850/* continuation for OP_USHR_LONG */
11851
11852.LOP_USHR_LONG_finish:
11853    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
11854    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11855    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11856    GOTO_OPCODE(ip)                     @ jump to next instruction
11857
11858/* continuation for OP_SHL_LONG_2ADDR */
11859
11860.LOP_SHL_LONG_2ADDR_finish:
11861    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11862    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11863    GOTO_OPCODE(ip)                     @ jump to next instruction
11864
11865/* continuation for OP_SHR_LONG_2ADDR */
11866
11867.LOP_SHR_LONG_2ADDR_finish:
11868    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11869    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11870    GOTO_OPCODE(ip)                     @ jump to next instruction
11871
11872/* continuation for OP_USHR_LONG_2ADDR */
11873
11874.LOP_USHR_LONG_2ADDR_finish:
11875    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11876    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11877    GOTO_OPCODE(ip)                     @ jump to next instruction
11878
11879/* continuation for OP_IGET_VOLATILE */
11880
11881    /*
11882     * Currently:
11883     *  r0 holds resolved field
11884     *  r9 holds object
11885     */
11886.LOP_IGET_VOLATILE_finish:
11887    @bl      common_squeak0
11888    cmp     r9, #0                      @ check object for null
11889    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11890    beq     common_errNullObject        @ object was null
11891    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11892    SMP_DMB                            @ acquiring load
11893    mov     r2, rINST, lsr #8           @ r2<- A+
11894    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11895    and     r2, r2, #15                 @ r2<- A
11896    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11897    SET_VREG(r0, r2)                    @ fp[A]<- r0
11898    GOTO_OPCODE(ip)                     @ jump to next instruction
11899
11900/* continuation for OP_IPUT_VOLATILE */
11901
11902    /*
11903     * Currently:
11904     *  r0 holds resolved field
11905     *  r9 holds object
11906     */
11907.LOP_IPUT_VOLATILE_finish:
11908    @bl      common_squeak0
11909    mov     r1, rINST, lsr #8           @ r1<- A+
11910    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11911    and     r1, r1, #15                 @ r1<- A
11912    cmp     r9, #0                      @ check object for null
11913    GET_VREG(r0, r1)                    @ r0<- fp[A]
11914    beq     common_errNullObject        @ object was null
11915    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11916    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11917    SMP_DMB                            @ releasing store
11918    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11919    GOTO_OPCODE(ip)                     @ jump to next instruction
11920
11921/* continuation for OP_SGET_VOLATILE */
11922
11923    /*
11924     * Continuation if the field has not yet been resolved.
11925     *  r1: BBBB field ref
11926     */
11927.LOP_SGET_VOLATILE_resolve:
11928    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11929    EXPORT_PC()                         @ resolve() could throw, so export now
11930    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11931    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11932    cmp     r0, #0                      @ success?
11933    bne     .LOP_SGET_VOLATILE_finish          @ yes, finish
11934    b       common_exceptionThrown      @ no, handle exception
11935
11936/* continuation for OP_SPUT_VOLATILE */
11937
11938    /*
11939     * Continuation if the field has not yet been resolved.
11940     *  r1: BBBB field ref
11941     */
11942.LOP_SPUT_VOLATILE_resolve:
11943    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11944    EXPORT_PC()                         @ resolve() could throw, so export now
11945    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11946    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11947    cmp     r0, #0                      @ success?
11948    bne     .LOP_SPUT_VOLATILE_finish          @ yes, finish
11949    b       common_exceptionThrown      @ no, handle exception
11950
11951/* continuation for OP_IGET_OBJECT_VOLATILE */
11952
11953    /*
11954     * Currently:
11955     *  r0 holds resolved field
11956     *  r9 holds object
11957     */
11958.LOP_IGET_OBJECT_VOLATILE_finish:
11959    @bl      common_squeak0
11960    cmp     r9, #0                      @ check object for null
11961    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11962    beq     common_errNullObject        @ object was null
11963    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11964    SMP_DMB                            @ acquiring load
11965    mov     r2, rINST, lsr #8           @ r2<- A+
11966    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11967    and     r2, r2, #15                 @ r2<- A
11968    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11969    SET_VREG(r0, r2)                    @ fp[A]<- r0
11970    GOTO_OPCODE(ip)                     @ jump to next instruction
11971
11972/* continuation for OP_IGET_WIDE_VOLATILE */
11973
11974    /*
11975     * Currently:
11976     *  r0 holds resolved field
11977     *  r9 holds object
11978     */
11979.LOP_IGET_WIDE_VOLATILE_finish:
11980    cmp     r9, #0                      @ check object for null
11981    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11982    beq     common_errNullObject        @ object was null
11983    .if     1
11984    add     r0, r9, r3                  @ r0<- address of field
11985    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
11986    .else
11987    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
11988    .endif
11989    mov     r2, rINST, lsr #8           @ r2<- A+
11990    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11991    and     r2, r2, #15                 @ r2<- A
11992    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
11993    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11994    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
11995    GOTO_OPCODE(ip)                     @ jump to next instruction
11996
11997/* continuation for OP_IPUT_WIDE_VOLATILE */
11998
11999    /*
12000     * Currently:
12001     *  r0 holds resolved field
12002     *  r9 holds object
12003     */
12004.LOP_IPUT_WIDE_VOLATILE_finish:
12005    mov     r2, rINST, lsr #8           @ r2<- A+
12006    cmp     r9, #0                      @ check object for null
12007    and     r2, r2, #15                 @ r2<- A
12008    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12009    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
12010    beq     common_errNullObject        @ object was null
12011    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12012    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
12013    GET_INST_OPCODE(r10)                @ extract opcode from rINST
12014    .if     1
12015    add     r2, r9, r3                  @ r2<- target address
12016    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
12017    .else
12018    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
12019    .endif
12020    GOTO_OPCODE(r10)                    @ jump to next instruction
12021
12022/* continuation for OP_SGET_WIDE_VOLATILE */
12023
12024    /*
12025     * Continuation if the field has not yet been resolved.
12026     *  r1: BBBB field ref
12027     *
12028     * Returns StaticField pointer in r0.
12029     */
12030.LOP_SGET_WIDE_VOLATILE_resolve:
12031    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12032    EXPORT_PC()                         @ resolve() could throw, so export now
12033    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12034    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12035    cmp     r0, #0                      @ success?
12036    bne     .LOP_SGET_WIDE_VOLATILE_finish          @ yes, finish
12037    b       common_exceptionThrown      @ no, handle exception
12038
12039/* continuation for OP_SPUT_WIDE_VOLATILE */
12040
12041    /*
12042     * Continuation if the field has not yet been resolved.
12043     *  r1: BBBB field ref
12044     *  r9: &fp[AA]
12045     *
12046     * Returns StaticField pointer in r2.
12047     */
12048.LOP_SPUT_WIDE_VOLATILE_resolve:
12049    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12050    EXPORT_PC()                         @ resolve() could throw, so export now
12051    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12052    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12053    cmp     r0, #0                      @ success?
12054    mov     r2, r0                      @ copy to r2
12055    bne     .LOP_SPUT_WIDE_VOLATILE_finish          @ yes, finish
12056    b       common_exceptionThrown      @ no, handle exception
12057
12058/* continuation for OP_EXECUTE_INLINE */
12059
12060    /*
12061     * Extract args, call function.
12062     *  r0 = #of args (0-4)
12063     *  r10 = call index
12064     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
12065     *
12066     * Other ideas:
12067     * - Use a jump table from the main piece to jump directly into the
12068     *   AND/LDR pairs.  Costs a data load, saves a branch.
12069     * - Have five separate pieces that do the loading, so we can work the
12070     *   interleave a little better.  Increases code size.
12071     */
12072.LOP_EXECUTE_INLINE_continue:
12073    rsb     r0, r0, #4                  @ r0<- 4-r0
12074    FETCH(r9, 2)                        @ r9<- FEDC
12075    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
12076    bl      common_abort                @ (skipped due to ARM prefetch)
120774:  and     ip, r9, #0xf000             @ isolate F
12078    ldr     r3, [rFP, ip, lsr #10]      @ r3<- vF (shift right 12, left 2)
120793:  and     ip, r9, #0x0f00             @ isolate E
12080    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vE
120812:  and     ip, r9, #0x00f0             @ isolate D
12082    ldr     r1, [rFP, ip, lsr #2]       @ r1<- vD
120831:  and     ip, r9, #0x000f             @ isolate C
12084    ldr     r0, [rFP, ip, lsl #2]       @ r0<- vC
120850:
12086    ldr     r9, .LOP_EXECUTE_INLINE_table       @ table of InlineOperation
12087    ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
12088    @ (not reached)
12089
12090.LOP_EXECUTE_INLINE_table:
12091    .word   gDvmInlineOpsTable
12092
12093/* continuation for OP_EXECUTE_INLINE_RANGE */
12094
12095    /*
12096     * Extract args, call function.
12097     *  r0 = #of args (0-4)
12098     *  r10 = call index
12099     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
12100     */
12101.LOP_EXECUTE_INLINE_RANGE_continue:
12102    rsb     r0, r0, #4                  @ r0<- 4-r0
12103    FETCH(r9, 2)                        @ r9<- CCCC
12104    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
12105    bl      common_abort                @ (skipped due to ARM prefetch)
121064:  add     ip, r9, #3                  @ base+3
12107    GET_VREG(r3, ip)                    @ r3<- vBase[3]
121083:  add     ip, r9, #2                  @ base+2
12109    GET_VREG(r2, ip)                    @ r2<- vBase[2]
121102:  add     ip, r9, #1                  @ base+1
12111    GET_VREG(r1, ip)                    @ r1<- vBase[1]
121121:  add     ip, r9, #0                  @ (nop)
12113    GET_VREG(r0, ip)                    @ r0<- vBase[0]
121140:
12115    ldr     r9, .LOP_EXECUTE_INLINE_RANGE_table       @ table of InlineOperation
12116    ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
12117    @ (not reached)
12118
12119.LOP_EXECUTE_INLINE_RANGE_table:
12120    .word   gDvmInlineOpsTable
12121
12122/* continuation for OP_IPUT_OBJECT_VOLATILE */
12123
12124    /*
12125     * Currently:
12126     *  r0 holds resolved field
12127     *  r9 holds object
12128     */
12129.LOP_IPUT_OBJECT_VOLATILE_finish:
12130    @bl      common_squeak0
12131    mov     r1, rINST, lsr #8           @ r1<- A+
12132    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12133    and     r1, r1, #15                 @ r1<- A
12134    cmp     r9, #0                      @ check object for null
12135    GET_VREG(r0, r1)                    @ r0<- fp[A]
12136    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12137    beq     common_errNullObject        @ object was null
12138    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12139    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12140    SMP_DMB                            @ releasing store
12141    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
12142    cmp     r0, #0                      @ stored a null reference?
12143    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
12144    GOTO_OPCODE(ip)                     @ jump to next instruction
12145
12146/* continuation for OP_SGET_OBJECT_VOLATILE */
12147
12148    /*
12149     * Continuation if the field has not yet been resolved.
12150     *  r1: BBBB field ref
12151     */
12152.LOP_SGET_OBJECT_VOLATILE_resolve:
12153    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12154    EXPORT_PC()                         @ resolve() could throw, so export now
12155    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12156    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12157    cmp     r0, #0                      @ success?
12158    bne     .LOP_SGET_OBJECT_VOLATILE_finish          @ yes, finish
12159    b       common_exceptionThrown      @ no, handle exception
12160
12161/* continuation for OP_SPUT_OBJECT_VOLATILE */
12162.LOP_SPUT_OBJECT_VOLATILE_finish:   @ field ptr in r0
12163    mov     r2, rINST, lsr #8           @ r2<- AA
12164    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12165    GET_VREG(r1, r2)                    @ r1<- fp[AA]
12166    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12167    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
12168    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12169    SMP_DMB                            @ releasing store
12170    str     r1, [r0, #offStaticField_value]  @ field<- vAA
12171    cmp     r1, #0                      @ stored a null object?
12172    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
12173    GOTO_OPCODE(ip)                     @ jump to next instruction
12174
12175/* continuation for OP_CONST_CLASS_JUMBO */
12176
12177    /*
12178     * Continuation if the Class has not yet been resolved.
12179     *  r1: AAAAAAAA (Class ref)
12180     *  r9: target register
12181     */
12182.LOP_CONST_CLASS_JUMBO_resolve:
12183    EXPORT_PC()
12184    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
12185    mov     r2, #1                      @ r2<- true
12186    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
12187    bl      dvmResolveClass             @ r0<- Class reference
12188    cmp     r0, #0                      @ failed?
12189    beq     common_exceptionThrown      @ yup, handle the exception
12190    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12191    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12192    SET_VREG(r0, r9)                    @ vBBBB<- r0
12193    GOTO_OPCODE(ip)                     @ jump to next instruction
12194
12195/* continuation for OP_CHECK_CAST_JUMBO */
12196
12197    /*
12198     * Trivial test failed, need to perform full check.  This is common.
12199     *  r0 holds obj->clazz
12200     *  r1 holds desired class resolved from AAAAAAAA
12201     *  r9 holds object
12202     */
12203.LOP_CHECK_CAST_JUMBO_fullcheck:
12204    mov     r10, r1                     @ avoid ClassObject getting clobbered
12205    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
12206    cmp     r0, #0                      @ failed?
12207    bne     .LOP_CHECK_CAST_JUMBO_okay            @ no, success
12208
12209    @ A cast has failed.  We need to throw a ClassCastException.
12210    EXPORT_PC()                         @ about to throw
12211    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
12212    mov     r1, r10                     @ r1<- desired class
12213    bl      dvmThrowClassCastException
12214    b       common_exceptionThrown
12215
12216    /*
12217     * Advance PC and get the next opcode.
12218     */
12219.LOP_CHECK_CAST_JUMBO_okay:
12220    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12221    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12222    GOTO_OPCODE(ip)                     @ jump to next instruction
12223
12224    /*
12225     * Resolution required.  This is the least-likely path.
12226     *
12227     *  r2 holds AAAAAAAA
12228     *  r9 holds object
12229     */
12230.LOP_CHECK_CAST_JUMBO_resolve:
12231    EXPORT_PC()                         @ resolve() could throw
12232    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
12233    mov     r1, r2                      @ r1<- AAAAAAAA
12234    mov     r2, #0                      @ r2<- false
12235    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12236    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12237    cmp     r0, #0                      @ got null?
12238    beq     common_exceptionThrown      @ yes, handle exception
12239    mov     r1, r0                      @ r1<- class resolved from AAAAAAAA
12240    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
12241    b       .LOP_CHECK_CAST_JUMBO_resolved        @ pick up where we left off
12242
12243/* continuation for OP_INSTANCE_OF_JUMBO */
12244
12245    /*
12246     * Class resolved, determine type of check necessary.  This is common.
12247     *  r0 holds obj->clazz
12248     *  r1 holds class resolved from AAAAAAAA
12249     *  r9 holds BBBB
12250     */
12251.LOP_INSTANCE_OF_JUMBO_resolved:
12252    cmp     r0, r1                      @ same class (trivial success)?
12253    beq     .LOP_INSTANCE_OF_JUMBO_trivial         @ yes, trivial finish
12254    @ fall through to OP_INSTANCE_OF_JUMBO_fullcheck
12255
12256    /*
12257     * Trivial test failed, need to perform full check.  This is common.
12258     *  r0 holds obj->clazz
12259     *  r1 holds class resolved from AAAAAAAA
12260     *  r9 holds BBBB
12261     */
12262.LOP_INSTANCE_OF_JUMBO_fullcheck:
12263    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
12264    @ fall through to OP_INSTANCE_OF_JUMBO_store
12265
12266    /*
12267     * r0 holds boolean result
12268     * r9 holds BBBB
12269     */
12270.LOP_INSTANCE_OF_JUMBO_store:
12271    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12272    SET_VREG(r0, r9)                    @ vBBBB<- r0
12273    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12274    GOTO_OPCODE(ip)                     @ jump to next instruction
12275
12276    /*
12277     * Trivial test succeeded, save and bail.
12278     *  r9 holds BBBB
12279     */
12280.LOP_INSTANCE_OF_JUMBO_trivial:
12281    mov     r0, #1                      @ indicate success
12282    @ could b OP_INSTANCE_OF_JUMBO_store, but copying is faster and cheaper
12283    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12284    SET_VREG(r0, r9)                    @ vBBBB<- r0
12285    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12286    GOTO_OPCODE(ip)                     @ jump to next instruction
12287
12288    /*
12289     * Resolution required.  This is the least-likely path.
12290     *
12291     *  r3 holds AAAAAAAA
12292     *  r9 holds BBBB
12293     */
12294
12295.LOP_INSTANCE_OF_JUMBO_resolve:
12296    EXPORT_PC()                         @ resolve() could throw
12297    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
12298    mov     r1, r3                      @ r1<- AAAAAAAA
12299    mov     r2, #1                      @ r2<- true
12300    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
12301    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12302    cmp     r0, #0                      @ got null?
12303    beq     common_exceptionThrown      @ yes, handle exception
12304    FETCH(r3, 4)                        @ r3<- vCCCC
12305    mov     r1, r0                      @ r1<- class resolved from AAAAAAAA
12306    GET_VREG(r0, r3)                    @ r0<- vCCCC (object)
12307    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
12308    b       .LOP_INSTANCE_OF_JUMBO_resolved        @ pick up where we left off
12309
12310/* continuation for OP_NEW_INSTANCE_JUMBO */
12311
12312    .balign 32                          @ minimize cache lines
12313.LOP_NEW_INSTANCE_JUMBO_finish: @ r0=new object
12314    FETCH(r3, 3)                        @ r3<- BBBB
12315    cmp     r0, #0                      @ failed?
12316    beq     common_exceptionThrown      @ yes, handle the exception
12317    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12318    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12319    SET_VREG(r0, r3)                    @ vBBBB<- r0
12320    GOTO_OPCODE(ip)                     @ jump to next instruction
12321
12322    /*
12323     * Class initialization required.
12324     *
12325     *  r0 holds class object
12326     */
12327.LOP_NEW_INSTANCE_JUMBO_needinit:
12328    mov     r9, r0                      @ save r0
12329    bl      dvmInitClass                @ initialize class
12330    cmp     r0, #0                      @ check boolean result
12331    mov     r0, r9                      @ restore r0
12332    bne     .LOP_NEW_INSTANCE_JUMBO_initialized     @ success, continue
12333    b       common_exceptionThrown      @ failed, deal with init exception
12334
12335    /*
12336     * Resolution required.  This is the least-likely path.
12337     *
12338     *  r1 holds AAAAAAAA
12339     */
12340.LOP_NEW_INSTANCE_JUMBO_resolve:
12341    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
12342    mov     r2, #0                      @ r2<- false
12343    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12344    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12345    cmp     r0, #0                      @ got null?
12346    bne     .LOP_NEW_INSTANCE_JUMBO_resolved        @ no, continue
12347    b       common_exceptionThrown      @ yes, handle exception
12348
12349/* continuation for OP_NEW_ARRAY_JUMBO */
12350
12351
12352    /*
12353     * Resolve class.  (This is an uncommon case.)
12354     *
12355     *  r1 holds array length
12356     *  r2 holds class ref AAAAAAAA
12357     */
12358.LOP_NEW_ARRAY_JUMBO_resolve:
12359    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
12360    mov     r9, r1                      @ r9<- length (save)
12361    mov     r1, r2                      @ r1<- AAAAAAAA
12362    mov     r2, #0                      @ r2<- false
12363    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12364    bl      dvmResolveClass             @ r0<- call(clazz, ref)
12365    cmp     r0, #0                      @ got null?
12366    mov     r1, r9                      @ r1<- length (restore)
12367    beq     common_exceptionThrown      @ yes, handle exception
12368    @ fall through to OP_NEW_ARRAY_JUMBO_finish
12369
12370    /*
12371     * Finish allocation.
12372     *
12373     *  r0 holds class
12374     *  r1 holds array length
12375     */
12376.LOP_NEW_ARRAY_JUMBO_finish:
12377    mov     r2, #ALLOC_DONT_TRACK       @ don't track in local refs table
12378    bl      dvmAllocArrayByClass        @ r0<- call(clazz, length, flags)
12379    cmp     r0, #0                      @ failed?
12380    FETCH(r2, 3)                        @ r2<- vBBBB
12381    beq     common_exceptionThrown      @ yes, handle the exception
12382    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12383    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12384    SET_VREG(r0, r2)                    @ vBBBB<- r0
12385    GOTO_OPCODE(ip)                     @ jump to next instruction
12386
12387/* continuation for OP_FILLED_NEW_ARRAY_JUMBO */
12388
12389    /*
12390     * On entry:
12391     *  r0 holds array class
12392     */
12393.LOP_FILLED_NEW_ARRAY_JUMBO_continue:
12394    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
12395    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
12396    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
12397    FETCH(r1, 3)                        @ r1<- BBBB (length)
12398    cmp     rINST, #'I'                 @ array of ints?
12399    cmpne   rINST, #'L'                 @ array of objects?
12400    cmpne   rINST, #'['                 @ array of arrays?
12401    mov     r9, r1                      @ save length in r9
12402    bne     .LOP_FILLED_NEW_ARRAY_JUMBO_notimpl         @ no, not handled yet
12403    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
12404    cmp     r0, #0                      @ null return?
12405    beq     common_exceptionThrown      @ alloc failed, handle exception
12406
12407    FETCH(r1, 4)                        @ r1<- CCCC
12408    str     r0, [rGLUE, #offGlue_retval]      @ retval.l <- new array
12409    str     rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type
12410    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
12411    subs    r9, r9, #1                  @ length--, check for neg
12412    FETCH_ADVANCE_INST(5)               @ advance to next instr, load rINST
12413    bmi     2f                          @ was zero, bail
12414
12415    @ copy values from registers into the array
12416    @ r0=array, r1=CCCC, r9=BBBB (length)
12417    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
124181:  ldr     r3, [r2], #4                @ r3<- *r2++
12419    subs    r9, r9, #1                  @ count--
12420    str     r3, [r0], #4                @ *contents++ = vX
12421    bpl     1b
12422
124232:  ldr     r0, [rGLUE, #offGlue_retval]     @ r0<- object
12424    ldr     r1, [rGLUE, #offGlue_retval+4]   @ r1<- type
12425    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12426    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
12427    cmp     r1, #'I'                         @ Is int array?
12428    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
12429    GOTO_OPCODE(ip)                          @ execute it
12430
12431    /*
12432     * Throw an exception indicating that we have not implemented this
12433     * mode of filled-new-array.
12434     */
12435.LOP_FILLED_NEW_ARRAY_JUMBO_notimpl:
12436    ldr     r0, .L_strInternalError
12437    ldr     r1, .L_strFilledNewArrayNotImpl
12438    bl      dvmThrowException
12439    b       common_exceptionThrown
12440
12441/* continuation for OP_IGET_JUMBO */
12442
12443    /*
12444     * Currently:
12445     *  r0 holds resolved field
12446     *  r9 holds object
12447     */
12448.LOP_IGET_JUMBO_resolved:
12449    cmp     r0, #0                      @ resolution unsuccessful?
12450    beq     common_exceptionThrown      @ yes, throw exception
12451    @ fall through to OP_IGET_JUMBO_finish
12452
12453    /*
12454     * Currently:
12455     *  r0 holds resolved field
12456     *  r9 holds object
12457     */
12458.LOP_IGET_JUMBO_finish:
12459    @bl      common_squeak0
12460    cmp     r9, #0                      @ check object for null
12461    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12462    beq     common_errNullObject        @ object was null
12463    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12464    @ no-op                             @ acquiring load
12465    FETCH(r2, 3)                        @ r2<- BBBB
12466    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12467    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12468    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12469    GOTO_OPCODE(ip)                     @ jump to next instruction
12470
12471/* continuation for OP_IGET_WIDE_JUMBO */
12472
12473    /*
12474     * Currently:
12475     *  r0 holds resolved field
12476     *  r9 holds object
12477     */
12478.LOP_IGET_WIDE_JUMBO_resolved:
12479    cmp     r0, #0                      @ resolution unsuccessful?
12480    beq     common_exceptionThrown      @ yes, throw exception
12481    @ fall through to OP_IGET_WIDE_JUMBO_finish
12482
12483    /*
12484     * Currently:
12485     *  r0 holds resolved field
12486     *  r9 holds object
12487     */
12488.LOP_IGET_WIDE_JUMBO_finish:
12489    cmp     r9, #0                      @ check object for null
12490    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12491    beq     common_errNullObject        @ object was null
12492    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
12493    FETCH(r2, 3)                        @ r2<- BBBB
12494    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12495    add     r3, rFP, r2, lsl #2         @ r3<- &fp[BBBB]
12496    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12497    stmia   r3, {r0-r1}                 @ fp[BBBB]<- r0/r1
12498    GOTO_OPCODE(ip)                     @ jump to next instruction
12499
12500/* continuation for OP_IGET_OBJECT_JUMBO */
12501
12502    /*
12503     * Currently:
12504     *  r0 holds resolved field
12505     *  r9 holds object
12506     */
12507.LOP_IGET_OBJECT_JUMBO_resolved:
12508    cmp     r0, #0                      @ resolution unsuccessful?
12509    beq     common_exceptionThrown      @ yes, throw exception
12510    @ fall through to OP_IGET_OBJECT_JUMBO_finish
12511
12512    /*
12513     * Currently:
12514     *  r0 holds resolved field
12515     *  r9 holds object
12516     */
12517.LOP_IGET_OBJECT_JUMBO_finish:
12518    @bl      common_squeak0
12519    cmp     r9, #0                      @ check object for null
12520    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12521    beq     common_errNullObject        @ object was null
12522    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12523    @ no-op                             @ acquiring load
12524    FETCH(r2, 3)                        @ r2<- BBBB
12525    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12526    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12527    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12528    GOTO_OPCODE(ip)                     @ jump to next instruction
12529
12530/* continuation for OP_IGET_BOOLEAN_JUMBO */
12531
12532    /*
12533     * Currently:
12534     *  r0 holds resolved field
12535     *  r9 holds object
12536     */
12537.LOP_IGET_BOOLEAN_JUMBO_resolved:
12538    cmp     r0, #0                      @ resolution unsuccessful?
12539    beq     common_exceptionThrown      @ yes, throw exception
12540    @ fall through to OP_IGET_BOOLEAN_JUMBO_finish
12541
12542    /*
12543     * Currently:
12544     *  r0 holds resolved field
12545     *  r9 holds object
12546     */
12547.LOP_IGET_BOOLEAN_JUMBO_finish:
12548    @bl      common_squeak1
12549    cmp     r9, #0                      @ check object for null
12550    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12551    beq     common_errNullObject        @ object was null
12552    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12553    @ no-op                             @ acquiring load
12554    FETCH(r2, 3)                        @ r2<- BBBB
12555    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12556    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12557    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12558    GOTO_OPCODE(ip)                     @ jump to next instruction
12559
12560/* continuation for OP_IGET_BYTE_JUMBO */
12561
12562    /*
12563     * Currently:
12564     *  r0 holds resolved field
12565     *  r9 holds object
12566     */
12567.LOP_IGET_BYTE_JUMBO_resolved:
12568    cmp     r0, #0                      @ resolution unsuccessful?
12569    beq     common_exceptionThrown      @ yes, throw exception
12570    @ fall through to OP_IGET_BYTE_JUMBO_finish
12571
12572    /*
12573     * Currently:
12574     *  r0 holds resolved field
12575     *  r9 holds object
12576     */
12577.LOP_IGET_BYTE_JUMBO_finish:
12578    @bl      common_squeak2
12579    cmp     r9, #0                      @ check object for null
12580    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12581    beq     common_errNullObject        @ object was null
12582    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12583    @ no-op                             @ acquiring load
12584    FETCH(r2, 3)                        @ r2<- BBBB
12585    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12586    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12587    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12588    GOTO_OPCODE(ip)                     @ jump to next instruction
12589
12590/* continuation for OP_IGET_CHAR_JUMBO */
12591
12592    /*
12593     * Currently:
12594     *  r0 holds resolved field
12595     *  r9 holds object
12596     */
12597.LOP_IGET_CHAR_JUMBO_resolved:
12598    cmp     r0, #0                      @ resolution unsuccessful?
12599    beq     common_exceptionThrown      @ yes, throw exception
12600    @ fall through to OP_IGET_CHAR_JUMBO_finish
12601
12602    /*
12603     * Currently:
12604     *  r0 holds resolved field
12605     *  r9 holds object
12606     */
12607.LOP_IGET_CHAR_JUMBO_finish:
12608    @bl      common_squeak3
12609    cmp     r9, #0                      @ check object for null
12610    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12611    beq     common_errNullObject        @ object was null
12612    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12613    @ no-op                             @ acquiring load
12614    FETCH(r2, 3)                        @ r2<- BBBB
12615    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12616    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12617    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12618    GOTO_OPCODE(ip)                     @ jump to next instruction
12619
12620/* continuation for OP_IGET_SHORT_JUMBO */
12621
12622    /*
12623     * Currently:
12624     *  r0 holds resolved field
12625     *  r9 holds object
12626     */
12627.LOP_IGET_SHORT_JUMBO_resolved:
12628    cmp     r0, #0                      @ resolution unsuccessful?
12629    beq     common_exceptionThrown      @ yes, throw exception
12630    @ fall through to OP_IGET_SHORT_JUMBO_finish
12631
12632    /*
12633     * Currently:
12634     *  r0 holds resolved field
12635     *  r9 holds object
12636     */
12637.LOP_IGET_SHORT_JUMBO_finish:
12638    @bl      common_squeak4
12639    cmp     r9, #0                      @ check object for null
12640    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12641    beq     common_errNullObject        @ object was null
12642    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12643    @ no-op                             @ acquiring load
12644    FETCH(r2, 3)                        @ r2<- BBBB
12645    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12646    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12647    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12648    GOTO_OPCODE(ip)                     @ jump to next instruction
12649
12650/* continuation for OP_IPUT_JUMBO */
12651
12652    /*
12653     * Currently:
12654     *  r0 holds resolved field
12655     *  r9 holds object
12656     */
12657.LOP_IPUT_JUMBO_resolved:
12658     cmp     r0, #0                     @ resolution unsuccessful?
12659     beq     common_exceptionThrown     @ yes, throw exception
12660     @ fall through to OP_IPUT_JUMBO_finish
12661
12662    /*
12663     * Currently:
12664     *  r0 holds resolved field
12665     *  r9 holds object
12666     */
12667.LOP_IPUT_JUMBO_finish:
12668    @bl      common_squeak0
12669    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12670    FETCH(r1, 3)                        @ r1<- BBBB
12671    cmp     r9, #0                      @ check object for null
12672    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12673    beq     common_errNullObject        @ object was null
12674    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12675    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12676    @ no-op                             @ releasing store
12677    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12678    GOTO_OPCODE(ip)                     @ jump to next instruction
12679
12680/* continuation for OP_IPUT_WIDE_JUMBO */
12681
12682    /*
12683     * Currently:
12684     *  r0 holds resolved field
12685     *  r9 holds object
12686     */
12687.LOP_IPUT_WIDE_JUMBO_resolved:
12688     cmp     r0, #0                     @ resolution unsuccessful?
12689     beq     common_exceptionThrown     @ yes, throw exception
12690     @ fall through to OP_IPUT_WIDE_JUMBO_finish
12691
12692    /*
12693     * Currently:
12694     *  r0 holds resolved field
12695     *  r9 holds object
12696     */
12697.LOP_IPUT_WIDE_JUMBO_finish:
12698    cmp     r9, #0                      @ check object for null
12699    FETCH(r2, 3)                        @ r1<- BBBB
12700    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12701    add     r2, rFP, r2, lsl #2         @ r3<- &fp[BBBB]
12702    beq     common_errNullObject        @ object was null
12703    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12704    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[BBBB]
12705    GET_INST_OPCODE(r10)                @ extract opcode from rINST
12706    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
12707    GOTO_OPCODE(r10)                    @ jump to next instruction
12708
12709/* continuation for OP_IPUT_OBJECT_JUMBO */
12710
12711    /*
12712     * Currently:
12713     *  r0 holds resolved field
12714     *  r9 holds object
12715     */
12716.LOP_IPUT_OBJECT_JUMBO_resolved:
12717     cmp     r0, #0                     @ resolution unsuccessful?
12718     beq     common_exceptionThrown     @ yes, throw exception
12719     @ fall through to OP_IPUT_OBJECT_JUMBO_finish
12720
12721    /*
12722     * Currently:
12723     *  r0 holds resolved field
12724     *  r9 holds object
12725     */
12726.LOP_IPUT_OBJECT_JUMBO_finish:
12727    @bl      common_squeak0
12728    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12729    FETCH(r1, 3)                        @ r1<- BBBB
12730    cmp     r9, #0                      @ check object for null
12731    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12732    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
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 (32 bits)<- r0
12738    cmp     r0, #0                      @ stored a null reference?
12739    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
12740    GOTO_OPCODE(ip)                     @ jump to next instruction
12741
12742/* continuation for OP_IPUT_BOOLEAN_JUMBO */
12743
12744    /*
12745     * Currently:
12746     *  r0 holds resolved field
12747     *  r9 holds object
12748     */
12749.LOP_IPUT_BOOLEAN_JUMBO_resolved:
12750     cmp     r0, #0                     @ resolution unsuccessful?
12751     beq     common_exceptionThrown     @ yes, throw exception
12752     @ fall through to OP_IPUT_BOOLEAN_JUMBO_finish
12753
12754    /*
12755     * Currently:
12756     *  r0 holds resolved field
12757     *  r9 holds object
12758     */
12759.LOP_IPUT_BOOLEAN_JUMBO_finish:
12760    @bl      common_squeak1
12761    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12762    FETCH(r1, 3)                        @ r1<- BBBB
12763    cmp     r9, #0                      @ check object for null
12764    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12765    beq     common_errNullObject        @ object was null
12766    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12767    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12768    @ no-op                             @ releasing store
12769    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12770    GOTO_OPCODE(ip)                     @ jump to next instruction
12771
12772/* continuation for OP_IPUT_BYTE_JUMBO */
12773
12774    /*
12775     * Currently:
12776     *  r0 holds resolved field
12777     *  r9 holds object
12778     */
12779.LOP_IPUT_BYTE_JUMBO_resolved:
12780     cmp     r0, #0                     @ resolution unsuccessful?
12781     beq     common_exceptionThrown     @ yes, throw exception
12782     @ fall through to OP_IPUT_BYTE_JUMBO_finish
12783
12784    /*
12785     * Currently:
12786     *  r0 holds resolved field
12787     *  r9 holds object
12788     */
12789.LOP_IPUT_BYTE_JUMBO_finish:
12790    @bl      common_squeak2
12791    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12792    FETCH(r1, 3)                        @ r1<- BBBB
12793    cmp     r9, #0                      @ check object for null
12794    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12795    beq     common_errNullObject        @ object was null
12796    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12797    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12798    @ no-op                             @ releasing store
12799    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12800    GOTO_OPCODE(ip)                     @ jump to next instruction
12801
12802/* continuation for OP_IPUT_CHAR_JUMBO */
12803
12804    /*
12805     * Currently:
12806     *  r0 holds resolved field
12807     *  r9 holds object
12808     */
12809.LOP_IPUT_CHAR_JUMBO_resolved:
12810     cmp     r0, #0                     @ resolution unsuccessful?
12811     beq     common_exceptionThrown     @ yes, throw exception
12812     @ fall through to OP_IPUT_CHAR_JUMBO_finish
12813
12814    /*
12815     * Currently:
12816     *  r0 holds resolved field
12817     *  r9 holds object
12818     */
12819.LOP_IPUT_CHAR_JUMBO_finish:
12820    @bl      common_squeak3
12821    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12822    FETCH(r1, 3)                        @ r1<- BBBB
12823    cmp     r9, #0                      @ check object for null
12824    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12825    beq     common_errNullObject        @ object was null
12826    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12827    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12828    @ no-op                             @ releasing store
12829    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12830    GOTO_OPCODE(ip)                     @ jump to next instruction
12831
12832/* continuation for OP_IPUT_SHORT_JUMBO */
12833
12834    /*
12835     * Currently:
12836     *  r0 holds resolved field
12837     *  r9 holds object
12838     */
12839.LOP_IPUT_SHORT_JUMBO_resolved:
12840     cmp     r0, #0                     @ resolution unsuccessful?
12841     beq     common_exceptionThrown     @ yes, throw exception
12842     @ fall through to OP_IPUT_SHORT_JUMBO_finish
12843
12844    /*
12845     * Currently:
12846     *  r0 holds resolved field
12847     *  r9 holds object
12848     */
12849.LOP_IPUT_SHORT_JUMBO_finish:
12850    @bl      common_squeak4
12851    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12852    FETCH(r1, 3)                        @ r1<- BBBB
12853    cmp     r9, #0                      @ check object for null
12854    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12855    beq     common_errNullObject        @ object was null
12856    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12857    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12858    @ no-op                             @ releasing store
12859    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12860    GOTO_OPCODE(ip)                     @ jump to next instruction
12861
12862/* continuation for OP_SGET_JUMBO */
12863
12864    /*
12865     * Continuation if the field has not yet been resolved.
12866     *  r1: AAAAAAAA field ref
12867     */
12868.LOP_SGET_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_JUMBO_finish          @ yes, finish
12875    b       common_exceptionThrown      @ no, handle exception
12876
12877/* continuation for OP_SGET_WIDE_JUMBO */
12878
12879    /*
12880     * Continuation if the field has not yet been resolved.
12881     *  r1: BBBB field ref
12882     *
12883     * Returns StaticField pointer in r0.
12884     */
12885.LOP_SGET_WIDE_JUMBO_resolve:
12886    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12887    EXPORT_PC()                         @ resolve() could throw, so export now
12888    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12889    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12890    cmp     r0, #0                      @ success?
12891    bne     .LOP_SGET_WIDE_JUMBO_finish          @ yes, finish
12892    b       common_exceptionThrown      @ no, handle exception
12893
12894/* continuation for OP_SGET_OBJECT_JUMBO */
12895
12896    /*
12897     * Continuation if the field has not yet been resolved.
12898     *  r1: AAAAAAAA field ref
12899     */
12900.LOP_SGET_OBJECT_JUMBO_resolve:
12901    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12902    EXPORT_PC()                         @ resolve() could throw, so export now
12903    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12904    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12905    cmp     r0, #0                      @ success?
12906    bne     .LOP_SGET_OBJECT_JUMBO_finish          @ yes, finish
12907    b       common_exceptionThrown      @ no, handle exception
12908
12909/* continuation for OP_SGET_BOOLEAN_JUMBO */
12910
12911    /*
12912     * Continuation if the field has not yet been resolved.
12913     *  r1: AAAAAAAA field ref
12914     */
12915.LOP_SGET_BOOLEAN_JUMBO_resolve:
12916    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12917    EXPORT_PC()                         @ resolve() could throw, so export now
12918    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12919    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12920    cmp     r0, #0                      @ success?
12921    bne     .LOP_SGET_BOOLEAN_JUMBO_finish          @ yes, finish
12922    b       common_exceptionThrown      @ no, handle exception
12923
12924/* continuation for OP_SGET_BYTE_JUMBO */
12925
12926    /*
12927     * Continuation if the field has not yet been resolved.
12928     *  r1: AAAAAAAA field ref
12929     */
12930.LOP_SGET_BYTE_JUMBO_resolve:
12931    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12932    EXPORT_PC()                         @ resolve() could throw, so export now
12933    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12934    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12935    cmp     r0, #0                      @ success?
12936    bne     .LOP_SGET_BYTE_JUMBO_finish          @ yes, finish
12937    b       common_exceptionThrown      @ no, handle exception
12938
12939/* continuation for OP_SGET_CHAR_JUMBO */
12940
12941    /*
12942     * Continuation if the field has not yet been resolved.
12943     *  r1: AAAAAAAA field ref
12944     */
12945.LOP_SGET_CHAR_JUMBO_resolve:
12946    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12947    EXPORT_PC()                         @ resolve() could throw, so export now
12948    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12949    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12950    cmp     r0, #0                      @ success?
12951    bne     .LOP_SGET_CHAR_JUMBO_finish          @ yes, finish
12952    b       common_exceptionThrown      @ no, handle exception
12953
12954/* continuation for OP_SGET_SHORT_JUMBO */
12955
12956    /*
12957     * Continuation if the field has not yet been resolved.
12958     *  r1: AAAAAAAA field ref
12959     */
12960.LOP_SGET_SHORT_JUMBO_resolve:
12961    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12962    EXPORT_PC()                         @ resolve() could throw, so export now
12963    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12964    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12965    cmp     r0, #0                      @ success?
12966    bne     .LOP_SGET_SHORT_JUMBO_finish          @ yes, finish
12967    b       common_exceptionThrown      @ no, handle exception
12968
12969/* continuation for OP_SPUT_JUMBO */
12970
12971    /*
12972     * Continuation if the field has not yet been resolved.
12973     *  r1: AAAAAAAA field ref
12974     */
12975.LOP_SPUT_JUMBO_resolve:
12976    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12977    EXPORT_PC()                         @ resolve() could throw, so export now
12978    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12979    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12980    cmp     r0, #0                      @ success?
12981    bne     .LOP_SPUT_JUMBO_finish          @ yes, finish
12982    b       common_exceptionThrown      @ no, handle exception
12983
12984/* continuation for OP_SPUT_WIDE_JUMBO */
12985
12986    /*
12987     * Continuation if the field has not yet been resolved.
12988     *  r1: BBBB field ref
12989     *  r9: &fp[AA]
12990     *
12991     * Returns StaticField pointer in r2.
12992     */
12993.LOP_SPUT_WIDE_JUMBO_resolve:
12994    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12995    EXPORT_PC()                         @ resolve() could throw, so export now
12996    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12997    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12998    cmp     r0, #0                      @ success?
12999    mov     r2, r0                      @ copy to r2
13000    bne     .LOP_SPUT_WIDE_JUMBO_finish          @ yes, finish
13001    b       common_exceptionThrown      @ no, handle exception
13002
13003/* continuation for OP_SPUT_OBJECT_JUMBO */
13004
13005.LOP_SPUT_OBJECT_JUMBO_finish:   @ field ptr in r0
13006    FETCH(r2, 3)                        @ r2<- BBBB
13007    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
13008    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
13009    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
13010    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
13011    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13012    @ no-op                             @ releasing store
13013    str     r1, [r0, #offStaticField_value]  @ field<- vBBBB
13014    cmp     r1, #0                      @ stored a null object?
13015    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
13016    GOTO_OPCODE(ip)                     @ jump to next instruction
13017
13018/* continuation for OP_SPUT_BOOLEAN_JUMBO */
13019
13020    /*
13021     * Continuation if the field has not yet been resolved.
13022     *  r1: AAAAAAAA field ref
13023     */
13024.LOP_SPUT_BOOLEAN_JUMBO_resolve:
13025    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13026    EXPORT_PC()                         @ resolve() could throw, so export now
13027    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13028    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13029    cmp     r0, #0                      @ success?
13030    bne     .LOP_SPUT_BOOLEAN_JUMBO_finish          @ yes, finish
13031    b       common_exceptionThrown      @ no, handle exception
13032
13033/* continuation for OP_SPUT_BYTE_JUMBO */
13034
13035    /*
13036     * Continuation if the field has not yet been resolved.
13037     *  r1: AAAAAAAA field ref
13038     */
13039.LOP_SPUT_BYTE_JUMBO_resolve:
13040    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13041    EXPORT_PC()                         @ resolve() could throw, so export now
13042    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13043    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13044    cmp     r0, #0                      @ success?
13045    bne     .LOP_SPUT_BYTE_JUMBO_finish          @ yes, finish
13046    b       common_exceptionThrown      @ no, handle exception
13047
13048/* continuation for OP_SPUT_CHAR_JUMBO */
13049
13050    /*
13051     * Continuation if the field has not yet been resolved.
13052     *  r1: AAAAAAAA field ref
13053     */
13054.LOP_SPUT_CHAR_JUMBO_resolve:
13055    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13056    EXPORT_PC()                         @ resolve() could throw, so export now
13057    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13058    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13059    cmp     r0, #0                      @ success?
13060    bne     .LOP_SPUT_CHAR_JUMBO_finish          @ yes, finish
13061    b       common_exceptionThrown      @ no, handle exception
13062
13063/* continuation for OP_SPUT_SHORT_JUMBO */
13064
13065    /*
13066     * Continuation if the field has not yet been resolved.
13067     *  r1: AAAAAAAA field ref
13068     */
13069.LOP_SPUT_SHORT_JUMBO_resolve:
13070    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13071    EXPORT_PC()                         @ resolve() could throw, so export now
13072    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13073    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13074    cmp     r0, #0                      @ success?
13075    bne     .LOP_SPUT_SHORT_JUMBO_finish          @ yes, finish
13076    b       common_exceptionThrown      @ no, handle exception
13077
13078/* continuation for OP_INVOKE_VIRTUAL_JUMBO */
13079
13080    /*
13081     * At this point:
13082     *  r0 = resolved base method
13083     */
13084.LOP_INVOKE_VIRTUAL_JUMBO_continue:
13085    FETCH(r10, 4)                       @ r10<- CCCC
13086    GET_VREG(r1, r10)                   @ r1<- "this" ptr
13087    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
13088    cmp     r1, #0                      @ is "this" null?
13089    beq     common_errNullObject        @ null "this", throw exception
13090    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
13091    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
13092    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
13093    bl      common_invokeMethodJumbo    @ continue on
13094
13095/* continuation for OP_INVOKE_SUPER_JUMBO */
13096
13097    /*
13098     * At this point:
13099     *  r0 = resolved base method
13100     *  r9 = method->clazz
13101     */
13102.LOP_INVOKE_SUPER_JUMBO_continue:
13103    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
13104    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
13105    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
13106    EXPORT_PC()                         @ must export for invoke
13107    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
13108    bcs     .LOP_INVOKE_SUPER_JUMBO_nsm             @ method not present in superclass
13109    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
13110    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
13111    bl      common_invokeMethodJumbo    @ continue on
13112
13113.LOP_INVOKE_SUPER_JUMBO_resolve:
13114    mov     r0, r9                      @ r0<- method->clazz
13115    mov     r2, #METHOD_VIRTUAL         @ resolver method type
13116    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
13117    cmp     r0, #0                      @ got null?
13118    bne     .LOP_INVOKE_SUPER_JUMBO_continue        @ no, continue
13119    b       common_exceptionThrown      @ yes, handle exception
13120
13121    /*
13122     * Throw a NoSuchMethodError with the method name as the message.
13123     *  r0 = resolved base method
13124     */
13125.LOP_INVOKE_SUPER_JUMBO_nsm:
13126    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
13127    b       common_errNoSuchMethod
13128
13129/* continuation for OP_INVOKE_DIRECT_JUMBO */
13130
13131    /*
13132     * On entry:
13133     *  r1 = reference (CCCC)
13134     *  r10 = "this" register
13135     */
13136.LOP_INVOKE_DIRECT_JUMBO_resolve:
13137    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
13138    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
13139    mov     r2, #METHOD_DIRECT          @ resolver method type
13140    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
13141    cmp     r0, #0                      @ got null?
13142    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
13143    bne     .LOP_INVOKE_DIRECT_JUMBO_finish          @ no, continue
13144    b       common_exceptionThrown      @ yes, handle exception
13145
13146    .size   dvmAsmSisterStart, .-dvmAsmSisterStart
13147    .global dvmAsmSisterEnd
13148dvmAsmSisterEnd:
13149
13150/* File: armv5te/footer.S */
13151
13152/*
13153 * ===========================================================================
13154 *  Common subroutines and data
13155 * ===========================================================================
13156 */
13157
13158
13159
13160    .text
13161    .align  2
13162
13163#if defined(WITH_JIT)
13164#if defined(WITH_SELF_VERIFICATION)
13165    .global dvmJitToInterpPunt
13166dvmJitToInterpPunt:
13167    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13168    mov    r2,#kSVSPunt                 @ r2<- interpreter entry point
13169    mov    r3, #0
13170    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13171    b      jitSVShadowRunEnd            @ doesn't return
13172
13173    .global dvmJitToInterpSingleStep
13174dvmJitToInterpSingleStep:
13175    str    lr,[rGLUE,#offGlue_jitResumeNPC]
13176    str    r1,[rGLUE,#offGlue_jitResumeDPC]
13177    mov    r2,#kSVSSingleStep           @ r2<- interpreter entry point
13178    b      jitSVShadowRunEnd            @ doesn't return
13179
13180    .global dvmJitToInterpNoChainNoProfile
13181dvmJitToInterpNoChainNoProfile:
13182    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13183    mov    r0,rPC                       @ pass our target PC
13184    mov    r2,#kSVSNoProfile            @ r2<- interpreter entry point
13185    mov    r3, #0                       @ 0 means !inJitCodeCache
13186    str    r3, [r10, #offThread_inJitCodeCache] @ back to the interp land
13187    b      jitSVShadowRunEnd            @ doesn't return
13188
13189    .global dvmJitToInterpTraceSelectNoChain
13190dvmJitToInterpTraceSelectNoChain:
13191    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13192    mov    r0,rPC                       @ pass our target PC
13193    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
13194    mov    r3, #0                       @ 0 means !inJitCodeCache
13195    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13196    b      jitSVShadowRunEnd            @ doesn't return
13197
13198    .global dvmJitToInterpTraceSelect
13199dvmJitToInterpTraceSelect:
13200    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13201    ldr    r0,[lr, #-1]                 @ pass our target PC
13202    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
13203    mov    r3, #0                       @ 0 means !inJitCodeCache
13204    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13205    b      jitSVShadowRunEnd            @ doesn't return
13206
13207    .global dvmJitToInterpBackwardBranch
13208dvmJitToInterpBackwardBranch:
13209    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13210    ldr    r0,[lr, #-1]                 @ pass our target PC
13211    mov    r2,#kSVSBackwardBranch       @ r2<- interpreter entry point
13212    mov    r3, #0                       @ 0 means !inJitCodeCache
13213    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13214    b      jitSVShadowRunEnd            @ doesn't return
13215
13216    .global dvmJitToInterpNormal
13217dvmJitToInterpNormal:
13218    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13219    ldr    r0,[lr, #-1]                 @ pass our target PC
13220    mov    r2,#kSVSNormal               @ r2<- interpreter entry point
13221    mov    r3, #0                       @ 0 means !inJitCodeCache
13222    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13223    b      jitSVShadowRunEnd            @ doesn't return
13224
13225    .global dvmJitToInterpNoChain
13226dvmJitToInterpNoChain:
13227    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13228    mov    r0,rPC                       @ pass our target PC
13229    mov    r2,#kSVSNoChain              @ r2<- interpreter entry point
13230    mov    r3, #0                       @ 0 means !inJitCodeCache
13231    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13232    b      jitSVShadowRunEnd            @ doesn't return
13233#else
13234/*
13235 * Return from the translation cache to the interpreter when the compiler is
13236 * having issues translating/executing a Dalvik instruction. We have to skip
13237 * the code cache lookup otherwise it is possible to indefinitely bouce
13238 * between the interpreter and the code cache if the instruction that fails
13239 * to be compiled happens to be at a trace start.
13240 */
13241    .global dvmJitToInterpPunt
13242dvmJitToInterpPunt:
13243    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13244    mov    rPC, r0
13245#if defined(WITH_JIT_TUNING)
13246    mov    r0,lr
13247    bl     dvmBumpPunt;
13248#endif
13249    EXPORT_PC()
13250    mov    r0, #0
13251    str    r0, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13252    adrl   rIBASE, dvmAsmInstructionStart
13253    FETCH_INST()
13254    GET_INST_OPCODE(ip)
13255    GOTO_OPCODE(ip)
13256
13257/*
13258 * Return to the interpreter to handle a single instruction.
13259 * On entry:
13260 *    r0 <= PC
13261 *    r1 <= PC of resume instruction
13262 *    lr <= resume point in translation
13263 */
13264    .global dvmJitToInterpSingleStep
13265dvmJitToInterpSingleStep:
13266    str    lr,[rGLUE,#offGlue_jitResumeNPC]
13267    str    r1,[rGLUE,#offGlue_jitResumeDPC]
13268    mov    r1,#kInterpEntryInstr
13269    @ enum is 4 byte in aapcs-EABI
13270    str    r1, [rGLUE, #offGlue_entryPoint]
13271    mov    rPC,r0
13272    EXPORT_PC()
13273
13274    adrl   rIBASE, dvmAsmInstructionStart
13275    mov    r2,#kJitSingleStep     @ Ask for single step and then revert
13276    str    r2,[rGLUE,#offGlue_jitState]
13277    mov    r1,#1                  @ set changeInterp to bail to debug interp
13278    b      common_gotoBail
13279
13280/*
13281 * Return from the translation cache and immediately request
13282 * a translation for the exit target.  Commonly used for callees.
13283 */
13284    .global dvmJitToInterpTraceSelectNoChain
13285dvmJitToInterpTraceSelectNoChain:
13286#if defined(WITH_JIT_TUNING)
13287    bl     dvmBumpNoChain
13288#endif
13289    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13290    mov    r0,rPC
13291    bl     dvmJitGetTraceAddr       @ Is there a translation?
13292    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13293    mov    r1, rPC                  @ arg1 of translation may need this
13294    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13295    cmp    r0,#0                    @ !0 means translation exists
13296    bxne   r0                       @ continue native execution if so
13297    b      2f                       @ branch over to use the interpreter
13298
13299/*
13300 * Return from the translation cache and immediately request
13301 * a translation for the exit target.  Commonly used following
13302 * invokes.
13303 */
13304    .global dvmJitToInterpTraceSelect
13305dvmJitToInterpTraceSelect:
13306    ldr    rPC,[lr, #-1]           @ get our target PC
13307    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13308    add    rINST,lr,#-5            @ save start of chain branch
13309    add    rINST, #-4              @  .. which is 9 bytes back
13310    mov    r0,rPC
13311    bl     dvmJitGetTraceAddr      @ Is there a translation?
13312    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13313    cmp    r0,#0
13314    beq    2f
13315    mov    r1,rINST
13316    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
13317    mov    r1, rPC                  @ arg1 of translation may need this
13318    mov    lr, #0                   @ in case target is HANDLER_INTERPRET
13319    cmp    r0,#0                    @ successful chain?
13320    bxne   r0                       @ continue native execution
13321    b      toInterpreter            @ didn't chain - resume with interpreter
13322
13323/* No translation, so request one if profiling isn't disabled*/
133242:
13325    adrl   rIBASE, dvmAsmInstructionStart
13326    GET_JIT_PROF_TABLE(r0)
13327    FETCH_INST()
13328    cmp    r0, #0
13329    movne  r2,#kJitTSelectRequestHot   @ ask for trace selection
13330    bne    common_selectTrace
13331    GET_INST_OPCODE(ip)
13332    GOTO_OPCODE(ip)
13333
13334/*
13335 * Return from the translation cache to the interpreter.
13336 * The return was done with a BLX from thumb mode, and
13337 * the following 32-bit word contains the target rPC value.
13338 * Note that lr (r14) will have its low-order bit set to denote
13339 * its thumb-mode origin.
13340 *
13341 * We'll need to stash our lr origin away, recover the new
13342 * target and then check to see if there is a translation available
13343 * for our new target.  If so, we do a translation chain and
13344 * go back to native execution.  Otherwise, it's back to the
13345 * interpreter (after treating this entry as a potential
13346 * trace start).
13347 */
13348    .global dvmJitToInterpNormal
13349dvmJitToInterpNormal:
13350    ldr    rPC,[lr, #-1]           @ get our target PC
13351    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13352    add    rINST,lr,#-5            @ save start of chain branch
13353    add    rINST,#-4               @ .. which is 9 bytes back
13354#if defined(WITH_JIT_TUNING)
13355    bl     dvmBumpNormal
13356#endif
13357    mov    r0,rPC
13358    bl     dvmJitGetTraceAddr      @ Is there a translation?
13359    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13360    cmp    r0,#0
13361    beq    toInterpreter            @ go if not, otherwise do chain
13362    mov    r1,rINST
13363    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
13364    mov    r1, rPC                  @ arg1 of translation may need this
13365    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13366    cmp    r0,#0                    @ successful chain?
13367    bxne   r0                       @ continue native execution
13368    b      toInterpreter            @ didn't chain - resume with interpreter
13369
13370/*
13371 * Return from the translation cache to the interpreter to do method invocation.
13372 * Check if translation exists for the callee, but don't chain to it.
13373 */
13374    .global dvmJitToInterpNoChainNoProfile
13375dvmJitToInterpNoChainNoProfile:
13376#if defined(WITH_JIT_TUNING)
13377    bl     dvmBumpNoChain
13378#endif
13379    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13380    mov    r0,rPC
13381    bl     dvmJitGetTraceAddr       @ Is there a translation?
13382    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13383    mov    r1, rPC                  @ arg1 of translation may need this
13384    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13385    cmp    r0,#0
13386    bxne   r0                       @ continue native execution if so
13387    EXPORT_PC()
13388    adrl   rIBASE, dvmAsmInstructionStart
13389    FETCH_INST()
13390    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13391    GOTO_OPCODE(ip)                     @ jump to next instruction
13392
13393/*
13394 * Return from the translation cache to the interpreter to do method invocation.
13395 * Check if translation exists for the callee, but don't chain to it.
13396 */
13397    .global dvmJitToInterpNoChain
13398dvmJitToInterpNoChain:
13399#if defined(WITH_JIT_TUNING)
13400    bl     dvmBumpNoChain
13401#endif
13402    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13403    mov    r0,rPC
13404    bl     dvmJitGetTraceAddr       @ Is there a translation?
13405    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13406    mov    r1, rPC                  @ arg1 of translation may need this
13407    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13408    cmp    r0,#0
13409    bxne   r0                       @ continue native execution if so
13410#endif
13411
13412/*
13413 * No translation, restore interpreter regs and start interpreting.
13414 * rGLUE & rFP were preserved in the translated code, and rPC has
13415 * already been restored by the time we get here.  We'll need to set
13416 * up rIBASE & rINST, and load the address of the JitTable into r0.
13417 */
13418toInterpreter:
13419    EXPORT_PC()
13420    adrl   rIBASE, dvmAsmInstructionStart
13421    FETCH_INST()
13422    GET_JIT_PROF_TABLE(r0)
13423    @ NOTE: intended fallthrough
13424
13425/*
13426 * Common code to update potential trace start counter, and initiate
13427 * a trace-build if appropriate.  On entry, rPC should point to the
13428 * next instruction to execute, and rINST should be already loaded with
13429 * the next opcode word, and r0 holds a pointer to the jit profile
13430 * table (pJitProfTable).
13431 */
13432common_testUpdateProfile:
13433    cmp     r0,#0
13434    GET_INST_OPCODE(ip)
13435    GOTO_OPCODE_IFEQ(ip)       @ if not profiling, fallthrough otherwise */
13436
13437common_updateProfile:
13438    eor     r3,rPC,rPC,lsr #12 @ cheap, but fast hash function
13439    lsl     r3,r3,#(32 - JIT_PROF_SIZE_LOG_2)          @ shift out excess bits
13440    ldrb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter
13441    GET_INST_OPCODE(ip)
13442    subs    r1,r1,#1           @ decrement counter
13443    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it
13444    GOTO_OPCODE_IFNE(ip)       @ if not threshold, fallthrough otherwise */
13445
13446/*
13447 * Here, we switch to the debug interpreter to request
13448 * trace selection.  First, though, check to see if there
13449 * is already a native translation in place (and, if so,
13450 * jump to it now).
13451 */
13452    GET_JIT_THRESHOLD(r1)
13453    ldr     r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
13454    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter
13455    EXPORT_PC()
13456    mov     r0,rPC
13457    bl      dvmJitGetTraceAddr          @ r0<- dvmJitGetTraceAddr(rPC)
13458    str     r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13459    mov     r1, rPC                     @ arg1 of translation may need this
13460    mov     lr, #0                      @  in case target is HANDLER_INTERPRET
13461    cmp     r0,#0
13462#if !defined(WITH_SELF_VERIFICATION)
13463    bxne    r0                          @ jump to the translation
13464    mov     r2,#kJitTSelectRequest      @ ask for trace selection
13465    @ fall-through to common_selectTrace
13466#else
13467    moveq   r2,#kJitTSelectRequest      @ ask for trace selection
13468    beq     common_selectTrace
13469    /*
13470     * At this point, we have a target translation.  However, if
13471     * that translation is actually the interpret-only pseudo-translation
13472     * we want to treat it the same as no translation.
13473     */
13474    mov     r10, r0                     @ save target
13475    bl      dvmCompilerGetInterpretTemplate
13476    cmp     r0, r10                     @ special case?
13477    bne     jitSVShadowRunStart         @ set up self verification shadow space
13478    @ Need to clear the inJitCodeCache flag
13479    ldr    r10, [rGLUE, #offGlue_self]  @ r10 <- glue->self
13480    mov    r3, #0                       @ 0 means not in the JIT code cache
13481    str    r3, [r10, #offThread_inJitCodeCache] @ back to the interp land
13482    GET_INST_OPCODE(ip)
13483    GOTO_OPCODE(ip)
13484    /* no return */
13485#endif
13486
13487/*
13488 * On entry:
13489 *  r2 is jit state, e.g. kJitTSelectRequest or kJitTSelectRequestHot
13490 */
13491common_selectTrace:
13492    str     r2,[rGLUE,#offGlue_jitState]
13493    mov     r2,#kInterpEntryInstr       @ normal entry reason
13494    str     r2,[rGLUE,#offGlue_entryPoint]
13495    mov     r1,#1                       @ set changeInterp
13496    b       common_gotoBail
13497
13498#if defined(WITH_SELF_VERIFICATION)
13499/*
13500 * Save PC and registers to shadow memory for self verification mode
13501 * before jumping to native translation.
13502 * On entry:
13503 *    rPC, rFP, rGLUE: the values that they should contain
13504 *    r10: the address of the target translation.
13505 */
13506jitSVShadowRunStart:
13507    mov     r0,rPC                      @ r0<- program counter
13508    mov     r1,rFP                      @ r1<- frame pointer
13509    mov     r2,rGLUE                    @ r2<- InterpState pointer
13510    mov     r3,r10                      @ r3<- target translation
13511    bl      dvmSelfVerificationSaveState @ save registers to shadow space
13512    ldr     rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space
13513    add     rGLUE,r0,#offShadowSpace_interpState @ rGLUE<- rGLUE in shadow space
13514    bx      r10                         @ jump to the translation
13515
13516/*
13517 * Restore PC, registers, and interpState to original values
13518 * before jumping back to the interpreter.
13519 */
13520jitSVShadowRunEnd:
13521    mov    r1,rFP                        @ pass ending fp
13522    bl     dvmSelfVerificationRestoreState @ restore pc and fp values
13523    ldr    rPC,[r0,#offShadowSpace_startPC] @ restore PC
13524    ldr    rFP,[r0,#offShadowSpace_fp]   @ restore FP
13525    ldr    rGLUE,[r0,#offShadowSpace_glue] @ restore InterpState
13526    ldr    r1,[r0,#offShadowSpace_svState] @ get self verification state
13527    cmp    r1,#0                         @ check for punt condition
13528    beq    1f
13529    mov    r2,#kJitSelfVerification      @ ask for self verification
13530    str    r2,[rGLUE,#offGlue_jitState]
13531    mov    r2,#kInterpEntryInstr         @ normal entry reason
13532    str    r2,[rGLUE,#offGlue_entryPoint]
13533    mov    r1,#1                         @ set changeInterp
13534    b      common_gotoBail
13535
135361:                                       @ exit to interpreter without check
13537    EXPORT_PC()
13538    adrl   rIBASE, dvmAsmInstructionStart
13539    FETCH_INST()
13540    GET_INST_OPCODE(ip)
13541    GOTO_OPCODE(ip)
13542#endif
13543
13544#endif
13545
13546/*
13547 * Common code when a backward branch is taken.
13548 *
13549 * TODO: we could avoid a branch by just setting r0 and falling through
13550 * into the common_periodicChecks code, and having a test on r0 at the
13551 * end determine if we should return to the caller or update & branch to
13552 * the next instr.
13553 *
13554 * On entry:
13555 *  r9 is PC adjustment *in bytes*
13556 */
13557common_backwardBranch:
13558    mov     r0, #kInterpEntryInstr
13559    bl      common_periodicChecks
13560#if defined(WITH_JIT)
13561    GET_JIT_PROF_TABLE(r0)
13562    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
13563    cmp     r0,#0
13564    bne     common_updateProfile
13565    GET_INST_OPCODE(ip)
13566    GOTO_OPCODE(ip)
13567#else
13568    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
13569    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13570    GOTO_OPCODE(ip)                     @ jump to next instruction
13571#endif
13572
13573
13574/*
13575 * Need to see if the thread needs to be suspended or debugger/profiler
13576 * activity has begun.  If so, we suspend the thread or side-exit to
13577 * the debug interpreter as appropriate.
13578 *
13579 * The common case is no activity on any of these, so we want to figure
13580 * that out quickly.  If something is up, we can then sort out what.
13581 *
13582 * We want to be fast if the VM was built without debugger or profiler
13583 * support, but we also need to recognize that the system is usually
13584 * shipped with both of these enabled.
13585 *
13586 * TODO: reduce this so we're just checking a single location.
13587 *
13588 * On entry:
13589 *  r0 is reentry type, e.g. kInterpEntryInstr (for debugger/profiling)
13590 *  r9 is trampoline PC adjustment *in bytes*
13591 */
13592common_periodicChecks:
13593    ldr     r1, [rGLUE, #offGlue_pInterpBreak] @ r3<- &interpBreak
13594    /* speculatively load address of thread-specific suspend count */
13595    ldr     r3, [rGLUE, #offGlue_pSelfSuspendCount] @ r3<- &suspendCount
13596    ldr     r1, [r1]                                @ r1<- interpBreak
13597    /* speculatively load thread-specific suspend count */
13598    ldr     ip, [r3]                    @ ip<- suspendCount (int)
13599    cmp     r1, #0                                  @ anything unusual?
13600    bxeq    lr                                      @ return if not
13601    /*
13602     * One or more interesting events have happened.  Figure out what.
13603     *
13604     * r0 still holds the reentry type.
13605     */
13606    cmp     ip, #0                      @ want suspend?
13607    beq     3f                          @ no, must be something else
13608
13609    stmfd   sp!, {r0, lr}               @ preserve r0 and lr
13610#if defined(WITH_JIT)
13611    /*
13612     * Refresh the Jit's cached copy of profile table pointer.  This pointer
13613     * doubles as the Jit's on/off switch.
13614     */
13615    ldr     r3, [rGLUE, #offGlue_ppJitProfTable] @ r3<-&gDvmJit.pJitProfTable
13616    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
13617    ldr     r3, [r3] @ r3 <- pJitProfTable
13618    EXPORT_PC()                         @ need for precise GC
13619    str     r3, [rGLUE, #offGlue_pJitProfTable] @ refresh Jit's on/off switch
13620#else
13621    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
13622    EXPORT_PC()                         @ need for precise GC
13623#endif
13624    bl      dvmCheckSuspendPending      @ do full check, suspend if necessary
13625    ldmfd   sp!, {r0, lr}               @ restore r0 and lr
13626
13627    /*
13628     * Reload the interpBreak flags - they may have changed while we
13629     * were suspended.
13630     */
13631    ldr     r1, [rGLUE, #offGlue_pInterpBreak]   @ r1<- &interpBreak
13632    ldr     r1, [r1]                    @ r1<- interpBreak
136333:
13634    /*
13635     * TODO: this code is too fragile.  Need a general mechanism
13636     * to identify what actions to take by submode.  Some profiling modes
13637     * (instruction count) need to single-step, while method tracing
13638     * may not.  Debugging with breakpoints can run unfettered, but
13639     * source-level single-stepping requires Dalvik singlestepping.
13640     * GC may require a one-shot action and then full-speed resumption.
13641     */
13642    ands    r1, #(kSubModeDebuggerActive | kSubModeEmulatorTrace | kSubModeInstCounting)
13643    bxeq    lr                          @ nothing to do, return
13644
13645    @ debugger/profiler enabled, bail out; glue->entryPoint was set above
13646    str     r0, [rGLUE, #offGlue_entryPoint]    @ store r0, need for debug/prof
13647    add     rPC, rPC, r9                @ update rPC
13648    mov     r1, #1                      @ "want switch" = true
13649    b       common_gotoBail             @ side exit
13650
13651
13652/*
13653 * The equivalent of "goto bail", this calls through the "bail handler".
13654 *
13655 * State registers will be saved to the "glue" area before bailing.
13656 *
13657 * On entry:
13658 *  r1 is "bool changeInterp", indicating if we want to switch to the
13659 *     other interpreter or just bail all the way out
13660 */
13661common_gotoBail:
13662    SAVE_PC_FP_TO_GLUE()                @ export state to "glue"
13663    mov     r0, rGLUE                   @ r0<- glue ptr
13664    b       dvmMterpStdBail             @ call(glue, changeInterp)
13665
13666    @add     r1, r1, #1                  @ using (boolean+1)
13667    @add     r0, rGLUE, #offGlue_jmpBuf  @ r0<- &glue->jmpBuf
13668    @bl      _longjmp                    @ does not return
13669    @bl      common_abort
13670
13671
13672/*
13673 * Common code for jumbo method invocation.
13674 * NOTE: this adjusts rPC to account for the difference in instruction width.
13675 * As a result, the savedPc in the stack frame will not be wholly accurate. So
13676 * long as that is only used for source file line number calculations, we're
13677 * okay.
13678 *
13679 * On entry:
13680 *  r0 is "Method* methodToCall", the method we're trying to call
13681 */
13682common_invokeMethodJumbo:
13683.LinvokeNewJumbo:
13684    @ prepare to copy args to "outs" area of current frame
13685    add     rPC, rPC, #4                @ adjust pc to make return consistent
13686    FETCH(r2, 1)                        @ r2<- BBBB (arg count)
13687    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13688    cmp     r2, #0                      @ no args?
13689    beq     .LinvokeArgsDone            @ if no args, skip the rest
13690    FETCH(r1, 2)                        @ r1<- CCCC
13691    b       .LinvokeRangeArgs           @ handle args like invoke range
13692
13693/*
13694 * Common code for method invocation with range.
13695 *
13696 * On entry:
13697 *  r0 is "Method* methodToCall", the method we're trying to call
13698 */
13699common_invokeMethodRange:
13700.LinvokeNewRange:
13701    @ prepare to copy args to "outs" area of current frame
13702    movs    r2, rINST, lsr #8           @ r2<- AA (arg count) -- test for zero
13703    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13704    beq     .LinvokeArgsDone            @ if no args, skip the rest
13705    FETCH(r1, 2)                        @ r1<- CCCC
13706
13707.LinvokeRangeArgs:
13708    @ r0=methodToCall, r1=CCCC, r2=count, r10=outs
13709    @ (very few methods have > 10 args; could unroll for common cases)
13710    add     r3, rFP, r1, lsl #2         @ r3<- &fp[CCCC]
13711    sub     r10, r10, r2, lsl #2        @ r10<- "outs" area, for call args
137121:  ldr     r1, [r3], #4                @ val = *fp++
13713    subs    r2, r2, #1                  @ count--
13714    str     r1, [r10], #4               @ *outs++ = val
13715    bne     1b                          @ ...while count != 0
13716    b       .LinvokeArgsDone
13717
13718/*
13719 * Common code for method invocation without range.
13720 *
13721 * On entry:
13722 *  r0 is "Method* methodToCall", the method we're trying to call
13723 */
13724common_invokeMethodNoRange:
13725.LinvokeNewNoRange:
13726    @ prepare to copy args to "outs" area of current frame
13727    movs    r2, rINST, lsr #12          @ r2<- B (arg count) -- test for zero
13728    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13729    FETCH(r1, 2)                        @ r1<- GFED (load here to hide latency)
13730    beq     .LinvokeArgsDone
13731
13732    @ r0=methodToCall, r1=GFED, r2=count, r10=outs
13733.LinvokeNonRange:
13734    rsb     r2, r2, #5                  @ r2<- 5-r2
13735    add     pc, pc, r2, lsl #4          @ computed goto, 4 instrs each
13736    bl      common_abort                @ (skipped due to ARM prefetch)
137375:  and     ip, rINST, #0x0f00          @ isolate A
13738    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vA (shift right 8, left 2)
13739    mov     r0, r0                      @ nop
13740    str     r2, [r10, #-4]!             @ *--outs = vA
137414:  and     ip, r1, #0xf000             @ isolate G
13742    ldr     r2, [rFP, ip, lsr #10]      @ r2<- vG (shift right 12, left 2)
13743    mov     r0, r0                      @ nop
13744    str     r2, [r10, #-4]!             @ *--outs = vG
137453:  and     ip, r1, #0x0f00             @ isolate F
13746    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vF
13747    mov     r0, r0                      @ nop
13748    str     r2, [r10, #-4]!             @ *--outs = vF
137492:  and     ip, r1, #0x00f0             @ isolate E
13750    ldr     r2, [rFP, ip, lsr #2]       @ r2<- vE
13751    mov     r0, r0                      @ nop
13752    str     r2, [r10, #-4]!             @ *--outs = vE
137531:  and     ip, r1, #0x000f             @ isolate D
13754    ldr     r2, [rFP, ip, lsl #2]       @ r2<- vD
13755    mov     r0, r0                      @ nop
13756    str     r2, [r10, #-4]!             @ *--outs = vD
137570:  @ fall through to .LinvokeArgsDone
13758
13759.LinvokeArgsDone: @ r0=methodToCall
13760    ldrh    r9, [r0, #offMethod_registersSize]  @ r9<- methodToCall->regsSize
13761    ldrh    r3, [r0, #offMethod_outsSize]  @ r3<- methodToCall->outsSize
13762    ldr     r2, [r0, #offMethod_insns]  @ r2<- method->insns
13763    ldr     rINST, [r0, #offMethod_clazz]  @ rINST<- method->clazz
13764    @ find space for the new stack frame, check for overflow
13765    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- stack save area
13766    sub     r1, r1, r9, lsl #2          @ r1<- newFp (old savearea - regsSize)
13767    SAVEAREA_FROM_FP(r10, r1)           @ r10<- newSaveArea
13768@    bl      common_dumpRegs
13769    ldr     r9, [rGLUE, #offGlue_interpStackEnd]    @ r9<- interpStackEnd
13770    sub     r3, r10, r3, lsl #2         @ r3<- bottom (newsave - outsSize)
13771    cmp     r3, r9                      @ bottom < interpStackEnd?
13772    ldr     lr, [rGLUE, #offGlue_pInterpBreak]
13773    ldr     r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags
13774    blo     .LstackOverflow             @ yes, this frame will overflow stack
13775
13776    @ set up newSaveArea
13777    ldr     lr, [lr]                    @ lr<- active submodes
13778#ifdef EASY_GDB
13779    SAVEAREA_FROM_FP(ip, rFP)           @ ip<- stack save area
13780    str     ip, [r10, #offStackSaveArea_prevSave]
13781#endif
13782    str     rFP, [r10, #offStackSaveArea_prevFrame]
13783    str     rPC, [r10, #offStackSaveArea_savedPc]
13784#if defined(WITH_JIT)
13785    mov     r9, #0
13786    str     r9, [r10, #offStackSaveArea_returnAddr]
13787#endif
13788    ands    lr, #kSubModeMethodTrace    @ method tracing?
13789    beq     1f                          @ skip if not
13790    stmfd   sp!, {r0-r3}                @ preserve r0-r3
13791    mov     r1, r6
13792    @ r0=methodToCall, r1=rGlue
13793    bl      dvmFastMethodTraceEnter
13794    ldmfd   sp!, {r0-r3}                @ restore r0-r3
137951:
13796    str     r0, [r10, #offStackSaveArea_method]
13797    tst     r3, #ACC_NATIVE
13798    bne     .LinvokeNative
13799
13800    /*
13801    stmfd   sp!, {r0-r3}
13802    bl      common_printNewline
13803    mov     r0, rFP
13804    mov     r1, #0
13805    bl      dvmDumpFp
13806    ldmfd   sp!, {r0-r3}
13807    stmfd   sp!, {r0-r3}
13808    mov     r0, r1
13809    mov     r1, r10
13810    bl      dvmDumpFp
13811    bl      common_printNewline
13812    ldmfd   sp!, {r0-r3}
13813    */
13814
13815    ldrh    r9, [r2]                        @ r9 <- load INST from new PC
13816    ldr     r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
13817    mov     rPC, r2                         @ publish new rPC
13818    ldr     r2, [rGLUE, #offGlue_self]      @ r2<- glue->self
13819
13820    @ Update "glue" values for the new method
13821    @ r0=methodToCall, r1=newFp, r2=self, r3=newMethodClass, r9=newINST
13822    str     r0, [rGLUE, #offGlue_method]    @ glue->method = methodToCall
13823    str     r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ...
13824#if defined(WITH_JIT)
13825    GET_JIT_PROF_TABLE(r0)
13826    mov     rFP, r1                         @ fp = newFp
13827    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
13828    mov     rINST, r9                       @ publish new rINST
13829    str     r1, [r2, #offThread_curFrame]   @ self->curFrame = newFp
13830    cmp     r0,#0
13831    bne     common_updateProfile
13832    GOTO_OPCODE(ip)                         @ jump to next instruction
13833#else
13834    mov     rFP, r1                         @ fp = newFp
13835    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
13836    mov     rINST, r9                       @ publish new rINST
13837    str     r1, [r2, #offThread_curFrame]   @ self->curFrame = newFp
13838    GOTO_OPCODE(ip)                         @ jump to next instruction
13839#endif
13840
13841.LinvokeNative:
13842    @ Prep for the native call
13843    @ r0=methodToCall, r1=newFp, r10=newSaveArea
13844    ldr     r3, [rGLUE, #offGlue_self]      @ r3<- glue->self
13845    ldr     lr, [rGLUE, #offGlue_pInterpBreak]
13846    ldr     r9, [r3, #offThread_jniLocal_topCookie] @ r9<- thread->localRef->...
13847    str     r1, [r3, #offThread_curFrame]   @ self->curFrame = newFp
13848    str     r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top
13849    ldr     lr, [lr]                    @ lr<- active submodes
13850    mov     r9, r3                      @ r9<- glue->self (preserve)
13851
13852    mov     r2, r0                      @ r2<- methodToCall
13853    mov     r0, r1                      @ r0<- newFp (points to args)
13854    add     r1, rGLUE, #offGlue_retval  @ r1<- &retval
13855
13856#ifdef ASSIST_DEBUGGER
13857    /* insert fake function header to help gdb find the stack frame */
13858    b       .Lskip
13859    .type   dalvik_mterp, %function
13860dalvik_mterp:
13861    .fnstart
13862    MTERP_ENTRY1
13863    MTERP_ENTRY2
13864.Lskip:
13865#endif
13866
13867    ands    lr, #kSubModeMethodTrace    @ method tracing?
13868    beq     110f                        @ hop if not
13869    @ r2=JNIMethod, r6=rGLUE
13870    stmfd   sp!, {r2,r6}
13871
13872    mov     lr, pc                      @ set return addr
13873    ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
13874
13875    @ r0=JNIMethod, r1=rGLUE
13876    ldmfd   sp!, {r0-r1}
13877    bl      dvmFastNativeMethodTraceExit
13878    b       220f
13879110:
13880    mov     lr, pc                      @ set return addr
13881    ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
13882220:
13883#if defined(WITH_JIT)
13884    ldr     r3, [rGLUE, #offGlue_ppJitProfTable] @ Refresh Jit's on/off status
13885#endif
13886
13887    @ native return; r9=self, r10=newSaveArea
13888    @ equivalent to dvmPopJniLocals
13889    ldr     r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top
13890    ldr     r1, [r9, #offThread_exception] @ check for exception
13891#if defined(WITH_JIT)
13892    ldr     r3, [r3]                    @ r3 <- gDvmJit.pProfTable
13893#endif
13894    str     rFP, [r9, #offThread_curFrame]  @ self->curFrame = fp
13895    cmp     r1, #0                      @ null?
13896    str     r0, [r9, #offThread_jniLocal_topCookie] @ new top <- old top
13897#if defined(WITH_JIT)
13898    str     r3, [rGLUE, #offGlue_pJitProfTable] @ refresh cached on/off switch
13899#endif
13900    bne     common_exceptionThrown      @ no, handle exception
13901
13902    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
13903    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13904    GOTO_OPCODE(ip)                     @ jump to next instruction
13905
13906.LstackOverflow:    @ r0=methodToCall
13907    mov     r1, r0                      @ r1<- methodToCall
13908    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- self
13909    bl      dvmHandleStackOverflow
13910    b       common_exceptionThrown
13911#ifdef ASSIST_DEBUGGER
13912    .fnend
13913#endif
13914
13915
13916    /*
13917     * Common code for method invocation, calling through "glue code".
13918     *
13919     * TODO: now that we have range and non-range invoke handlers, this
13920     *       needs to be split into two.  Maybe just create entry points
13921     *       that set r9 and jump here?
13922     *
13923     * On entry:
13924     *  r0 is "Method* methodToCall", the method we're trying to call
13925     *  r9 is "bool methodCallRange", indicating if this is a /range variant
13926     */
13927     .if    0
13928.LinvokeOld:
13929    sub     sp, sp, #8                  @ space for args + pad
13930    FETCH(ip, 2)                        @ ip<- FEDC or CCCC
13931    mov     r2, r0                      @ A2<- methodToCall
13932    mov     r0, rGLUE                   @ A0<- glue
13933    SAVE_PC_FP_TO_GLUE()                @ export state to "glue"
13934    mov     r1, r9                      @ A1<- methodCallRange
13935    mov     r3, rINST, lsr #8           @ A3<- AA
13936    str     ip, [sp, #0]                @ A4<- ip
13937    bl      dvmMterp_invokeMethod       @ call the C invokeMethod
13938    add     sp, sp, #8                  @ remove arg area
13939    b       common_resumeAfterGlueCall  @ continue to next instruction
13940    .endif
13941
13942
13943
13944/*
13945 * Common code for handling a return instruction.
13946 *
13947 * This does not return.
13948 */
13949common_returnFromMethod:
13950.LreturnNew:
13951    mov     r0, #kInterpEntryReturn
13952    mov     r9, #0
13953    bl      common_periodicChecks
13954
13955    ldr     lr, [rGLUE, #offGlue_pInterpBreak]
13956    SAVEAREA_FROM_FP(r0, rFP)
13957    ldr     lr, [lr]                    @ lr<- active submodes
13958    ldr     r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc
13959    ands    lr, #kSubModeMethodTrace    @ method tracing?
13960    beq     333f
13961    stmfd   sp!, {r0-r3}                @ preserve r0-r3
13962    mov     r0, r6
13963    @ r0=rGlue
13964    bl      dvmFastJavaMethodTraceExit
13965    ldmfd   sp!, {r0-r3}                @ restore r0-r3
13966333:
13967    ldr     rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame
13968    ldr     r3, [rGLUE, #offGlue_self]  @ r3<- glue->self
13969    ldr     r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)]
13970                                        @ r2<- method we're returning to
13971    cmp     r2, #0                      @ is this a break frame?
13972#if defined(WORKAROUND_CORTEX_A9_745320)
13973    /* Don't use conditional loads if the HW defect exists */
13974    beq     101f
13975    ldr     r10, [r2, #offMethod_clazz] @ r10<- method->clazz
13976101:
13977#else
13978    ldrne   r10, [r2, #offMethod_clazz] @ r10<- method->clazz
13979#endif
13980    mov     r1, #0                      @ "want switch" = false
13981    beq     common_gotoBail             @ break frame, bail out completely
13982
13983    PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST
13984    str     r2, [rGLUE, #offGlue_method]@ glue->method = newSave->method
13985    ldr     r1, [r10, #offClassObject_pDvmDex]   @ r1<- method->clazz->pDvmDex
13986    str     rFP, [r3, #offThread_curFrame]  @ self->curFrame = fp
13987#if defined(WITH_JIT)
13988    ldr     r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr
13989    mov     rPC, r9                     @ publish new rPC
13990    str     r1, [rGLUE, #offGlue_methodClassDex]
13991    str     r10, [r3, #offThread_inJitCodeCache]  @ may return to JIT'ed land
13992    cmp     r10, #0                      @ caller is compiled code
13993    blxne   r10
13994    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13995    GOTO_OPCODE(ip)                     @ jump to next instruction
13996#else
13997    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13998    mov     rPC, r9                     @ publish new rPC
13999    str     r1, [rGLUE, #offGlue_methodClassDex]
14000    GOTO_OPCODE(ip)                     @ jump to next instruction
14001#endif
14002
14003    /*
14004     * Return handling, calls through "glue code".
14005     */
14006     .if    0
14007.LreturnOld:
14008    SAVE_PC_FP_TO_GLUE()                @ export state
14009    mov     r0, rGLUE                   @ arg to function
14010    bl      dvmMterp_returnFromMethod
14011    b       common_resumeAfterGlueCall
14012    .endif
14013
14014
14015/*
14016 * Somebody has thrown an exception.  Handle it.
14017 *
14018 * If the exception processing code returns to us (instead of falling
14019 * out of the interpreter), continue with whatever the next instruction
14020 * now happens to be.
14021 *
14022 * This does not return.
14023 */
14024     .global dvmMterpCommonExceptionThrown
14025dvmMterpCommonExceptionThrown:
14026common_exceptionThrown:
14027.LexceptionNew:
14028    mov     r0, #kInterpEntryThrow
14029    mov     r9, #0
14030    bl      common_periodicChecks
14031
14032    ldr     r10, [rGLUE, #offGlue_self] @ r10<- glue->self
14033    ldr     r9, [r10, #offThread_exception] @ r9<- self->exception
14034    mov     r1, r10                     @ r1<- self
14035    mov     r0, r9                      @ r0<- exception
14036    bl      dvmAddTrackedAlloc          @ don't let the exception be GCed
14037    mov     r3, #0                      @ r3<- NULL
14038    str     r3, [r10, #offThread_exception] @ self->exception = NULL
14039
14040    /* set up args and a local for "&fp" */
14041    /* (str sp, [sp, #-4]!  would be perfect here, but is discouraged) */
14042    str     rFP, [sp, #-4]!             @ *--sp = fp
14043    mov     ip, sp                      @ ip<- &fp
14044    mov     r3, #0                      @ r3<- false
14045    str     ip, [sp, #-4]!              @ *--sp = &fp
14046    ldr     r1, [rGLUE, #offGlue_method] @ r1<- glue->method
14047    mov     r0, r10                     @ r0<- self
14048    ldr     r1, [r1, #offMethod_insns]  @ r1<- method->insns
14049    mov     r2, r9                      @ r2<- exception
14050    sub     r1, rPC, r1                 @ r1<- pc - method->insns
14051    mov     r1, r1, asr #1              @ r1<- offset in code units
14052
14053    /* call, r0 gets catchRelPc (a code-unit offset) */
14054    bl      dvmFindCatchBlock           @ call(self, relPc, exc, scan?, &fp)
14055
14056    /* fix earlier stack overflow if necessary; may trash rFP */
14057    ldrb    r1, [r10, #offThread_stackOverflowed]
14058    cmp     r1, #0                      @ did we overflow earlier?
14059    beq     1f                          @ no, skip ahead
14060    mov     rFP, r0                     @ save relPc result in rFP
14061    mov     r0, r10                     @ r0<- self
14062    mov     r1, r9                      @ r1<- exception
14063    bl      dvmCleanupStackOverflow     @ call(self)
14064    mov     r0, rFP                     @ restore result
140651:
14066
14067    /* update frame pointer and check result from dvmFindCatchBlock */
14068    ldr     rFP, [sp, #4]               @ retrieve the updated rFP
14069    cmp     r0, #0                      @ is catchRelPc < 0?
14070    add     sp, sp, #8                  @ restore stack
14071    bmi     .LnotCaughtLocally
14072
14073    /* adjust locals to match self->curFrame and updated PC */
14074    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- new save area
14075    ldr     r1, [r1, #offStackSaveArea_method] @ r1<- new method
14076    str     r1, [rGLUE, #offGlue_method]    @ glue->method = new method
14077    ldr     r2, [r1, #offMethod_clazz]      @ r2<- method->clazz
14078    ldr     r3, [r1, #offMethod_insns]      @ r3<- method->insns
14079    ldr     r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex
14080    add     rPC, r3, r0, asl #1             @ rPC<- method->insns + catchRelPc
14081    str     r2, [rGLUE, #offGlue_methodClassDex] @ glue->pDvmDex = meth...
14082
14083    /* release the tracked alloc on the exception */
14084    mov     r0, r9                      @ r0<- exception
14085    mov     r1, r10                     @ r1<- self
14086    bl      dvmReleaseTrackedAlloc      @ release the exception
14087
14088    /* restore the exception if the handler wants it */
14089    FETCH_INST()                        @ load rINST from rPC
14090    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14091    cmp     ip, #OP_MOVE_EXCEPTION      @ is it "move-exception"?
14092    streq   r9, [r10, #offThread_exception] @ yes, restore the exception
14093    GOTO_OPCODE(ip)                     @ jump to next instruction
14094
14095.LnotCaughtLocally: @ r9=exception, r10=self
14096    /* fix stack overflow if necessary */
14097    ldrb    r1, [r10, #offThread_stackOverflowed]
14098    cmp     r1, #0                      @ did we overflow earlier?
14099    movne   r0, r10                     @ if yes: r0<- self
14100    movne   r1, r9                      @ if yes: r1<- exception
14101    blne    dvmCleanupStackOverflow     @ if yes: call(self)
14102
14103    @ may want to show "not caught locally" debug messages here
14104#if DVM_SHOW_EXCEPTION >= 2
14105    /* call __android_log_print(prio, tag, format, ...) */
14106    /* "Exception %s from %s:%d not caught locally" */
14107    @ dvmLineNumFromPC(method, pc - method->insns)
14108    ldr     r0, [rGLUE, #offGlue_method]
14109    ldr     r1, [r0, #offMethod_insns]
14110    sub     r1, rPC, r1
14111    asr     r1, r1, #1
14112    bl      dvmLineNumFromPC
14113    str     r0, [sp, #-4]!
14114    @ dvmGetMethodSourceFile(method)
14115    ldr     r0, [rGLUE, #offGlue_method]
14116    bl      dvmGetMethodSourceFile
14117    str     r0, [sp, #-4]!
14118    @ exception->clazz->descriptor
14119    ldr     r3, [r9, #offObject_clazz]
14120    ldr     r3, [r3, #offClassObject_descriptor]
14121    @
14122    ldr     r2, strExceptionNotCaughtLocally
14123    ldr     r1, strLogTag
14124    mov     r0, #3                      @ LOG_DEBUG
14125    bl      __android_log_print
14126#endif
14127    str     r9, [r10, #offThread_exception] @ restore exception
14128    mov     r0, r9                      @ r0<- exception
14129    mov     r1, r10                     @ r1<- self
14130    bl      dvmReleaseTrackedAlloc      @ release the exception
14131    mov     r1, #0                      @ "want switch" = false
14132    b       common_gotoBail             @ bail out
14133
14134
14135    /*
14136     * Exception handling, calls through "glue code".
14137     */
14138    .if     0
14139.LexceptionOld:
14140    SAVE_PC_FP_TO_GLUE()                @ export state
14141    mov     r0, rGLUE                   @ arg to function
14142    bl      dvmMterp_exceptionThrown
14143    b       common_resumeAfterGlueCall
14144    .endif
14145
14146
14147/*
14148 * After returning from a "glued" function, pull out the updated
14149 * values and start executing at the next instruction.
14150 */
14151common_resumeAfterGlueCall:
14152    LOAD_PC_FP_FROM_GLUE()              @ pull rPC and rFP out of glue
14153    FETCH_INST()                        @ load rINST from rPC
14154    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14155    GOTO_OPCODE(ip)                     @ jump to next instruction
14156
14157/*
14158 * Invalid array index. Note that our calling convention is strange; we use r1
14159 * and r3 because those just happen to be the registers all our callers are
14160 * using. We shuffle them here before calling the C function.
14161 * r1: index
14162 * r3: size
14163 */
14164common_errArrayIndex:
14165    EXPORT_PC()
14166    mov     r0, r1
14167    mov     r1, r3
14168    bl      dvmThrowAIOOBE
14169    b       common_exceptionThrown
14170
14171/*
14172 * Integer divide or mod by zero.
14173 */
14174common_errDivideByZero:
14175    EXPORT_PC()
14176    ldr     r0, strArithmeticException
14177    ldr     r1, strDivideByZero
14178    bl      dvmThrowException
14179    b       common_exceptionThrown
14180
14181/*
14182 * Attempt to allocate an array with a negative size.
14183 */
14184common_errNegativeArraySize:
14185    EXPORT_PC()
14186    ldr     r0, strNegativeArraySizeException
14187    mov     r1, #0
14188    bl      dvmThrowException
14189    b       common_exceptionThrown
14190
14191/*
14192 * Invocation of a non-existent method.
14193 */
14194common_errNoSuchMethod:
14195    EXPORT_PC()
14196    ldr     r0, strNoSuchMethodError
14197    mov     r1, #0
14198    bl      dvmThrowException
14199    b       common_exceptionThrown
14200
14201/*
14202 * We encountered a null object when we weren't expecting one.  We
14203 * export the PC, throw a NullPointerException, and goto the exception
14204 * processing code.
14205 */
14206common_errNullObject:
14207    EXPORT_PC()
14208    ldr     r0, strNullPointerException
14209    mov     r1, #0
14210    bl      dvmThrowException
14211    b       common_exceptionThrown
14212
14213/*
14214 * For debugging, cause an immediate fault.  The source address will
14215 * be in lr (use a bl instruction to jump here).
14216 */
14217common_abort:
14218    ldr     pc, .LdeadFood
14219.LdeadFood:
14220    .word   0xdeadf00d
14221
14222/*
14223 * Spit out a "we were here", preserving all registers.  (The attempt
14224 * to save ip won't work, but we need to save an even number of
14225 * registers for EABI 64-bit stack alignment.)
14226 */
14227    .macro  SQUEAK num
14228common_squeak\num:
14229    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14230    ldr     r0, strSqueak
14231    mov     r1, #\num
14232    bl      printf
14233    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14234    bx      lr
14235    .endm
14236
14237    SQUEAK  0
14238    SQUEAK  1
14239    SQUEAK  2
14240    SQUEAK  3
14241    SQUEAK  4
14242    SQUEAK  5
14243
14244/*
14245 * Spit out the number in r0, preserving registers.
14246 */
14247common_printNum:
14248    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14249    mov     r1, r0
14250    ldr     r0, strSqueak
14251    bl      printf
14252    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14253    bx      lr
14254
14255/*
14256 * Print a newline, preserving registers.
14257 */
14258common_printNewline:
14259    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14260    ldr     r0, strNewline
14261    bl      printf
14262    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14263    bx      lr
14264
14265    /*
14266     * Print the 32-bit quantity in r0 as a hex value, preserving registers.
14267     */
14268common_printHex:
14269    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14270    mov     r1, r0
14271    ldr     r0, strPrintHex
14272    bl      printf
14273    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14274    bx      lr
14275
14276/*
14277 * Print the 64-bit quantity in r0-r1, preserving registers.
14278 */
14279common_printLong:
14280    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14281    mov     r3, r1
14282    mov     r2, r0
14283    ldr     r0, strPrintLong
14284    bl      printf
14285    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14286    bx      lr
14287
14288/*
14289 * Print full method info.  Pass the Method* in r0.  Preserves regs.
14290 */
14291common_printMethod:
14292    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14293    bl      dvmMterpPrintMethod
14294    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14295    bx      lr
14296
14297/*
14298 * Call a C helper function that dumps regs and possibly some
14299 * additional info.  Requires the C function to be compiled in.
14300 */
14301    .if     0
14302common_dumpRegs:
14303    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14304    bl      dvmMterpDumpArmRegs
14305    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14306    bx      lr
14307    .endif
14308
14309#if 0
14310/*
14311 * Experiment on VFP mode.
14312 *
14313 * uint32_t setFPSCR(uint32_t val, uint32_t mask)
14314 *
14315 * Updates the bits specified by "mask", setting them to the values in "val".
14316 */
14317setFPSCR:
14318    and     r0, r0, r1                  @ make sure no stray bits are set
14319    fmrx    r2, fpscr                   @ get VFP reg
14320    mvn     r1, r1                      @ bit-invert mask
14321    and     r2, r2, r1                  @ clear masked bits
14322    orr     r2, r2, r0                  @ set specified bits
14323    fmxr    fpscr, r2                   @ set VFP reg
14324    mov     r0, r2                      @ return new value
14325    bx      lr
14326
14327    .align  2
14328    .global dvmConfigureFP
14329    .type   dvmConfigureFP, %function
14330dvmConfigureFP:
14331    stmfd   sp!, {ip, lr}
14332    /* 0x03000000 sets DN/FZ */
14333    /* 0x00009f00 clears the six exception enable flags */
14334    bl      common_squeak0
14335    mov     r0, #0x03000000             @ r0<- 0x03000000
14336    add     r1, r0, #0x9f00             @ r1<- 0x03009f00
14337    bl      setFPSCR
14338    ldmfd   sp!, {ip, pc}
14339#endif
14340
14341
14342/*
14343 * String references, must be close to the code that uses them.
14344 */
14345    .align  2
14346strArithmeticException:
14347    .word   .LstrArithmeticException
14348strDivideByZero:
14349    .word   .LstrDivideByZero
14350strNegativeArraySizeException:
14351    .word   .LstrNegativeArraySizeException
14352strNoSuchMethodError:
14353    .word   .LstrNoSuchMethodError
14354strNullPointerException:
14355    .word   .LstrNullPointerException
14356
14357strLogTag:
14358    .word   .LstrLogTag
14359strExceptionNotCaughtLocally:
14360    .word   .LstrExceptionNotCaughtLocally
14361
14362strNewline:
14363    .word   .LstrNewline
14364strSqueak:
14365    .word   .LstrSqueak
14366strPrintHex:
14367    .word   .LstrPrintHex
14368strPrintLong:
14369    .word   .LstrPrintLong
14370
14371/*
14372 * Zero-terminated ASCII string data.
14373 *
14374 * On ARM we have two choices: do like gcc does, and LDR from a .word
14375 * with the address, or use an ADR pseudo-op to get the address
14376 * directly.  ADR saves 4 bytes and an indirection, but it's using a
14377 * PC-relative addressing mode and hence has a limited range, which
14378 * makes it not work well with mergeable string sections.
14379 */
14380    .section .rodata.str1.4,"aMS",%progbits,1
14381
14382.LstrBadEntryPoint:
14383    .asciz  "Bad entry point %d\n"
14384.LstrArithmeticException:
14385    .asciz  "Ljava/lang/ArithmeticException;"
14386.LstrDivideByZero:
14387    .asciz  "divide by zero"
14388.LstrFilledNewArrayNotImpl:
14389    .asciz  "filled-new-array only implemented for objects and 'int'"
14390.LstrInternalError:
14391    .asciz  "Ljava/lang/InternalError;"
14392.LstrInstantiationError:
14393    .asciz  "Ljava/lang/InstantiationError;"
14394.LstrNegativeArraySizeException:
14395    .asciz  "Ljava/lang/NegativeArraySizeException;"
14396.LstrNoSuchMethodError:
14397    .asciz  "Ljava/lang/NoSuchMethodError;"
14398.LstrNullPointerException:
14399    .asciz  "Ljava/lang/NullPointerException;"
14400
14401.LstrLogTag:
14402    .asciz  "mterp"
14403.LstrExceptionNotCaughtLocally:
14404    .asciz  "Exception %s from %s:%d not caught locally\n"
14405
14406.LstrNewline:
14407    .asciz  "\n"
14408.LstrSqueak:
14409    .asciz  "<%d>"
14410.LstrPrintHex:
14411    .asciz  "<0x%x>"
14412.LstrPrintLong:
14413    .asciz  "<%lld>"
14414
14415