InterpAsm-armv5te.S revision d3a92b577f11c6357c76dc850c6cbf352ef4c760
1/*
2 * This file was generated automatically by gen-mterp.py for 'armv5te'.
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: armv5te/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     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
1279     * on what value we'd like to return when one of the operands is NaN.
1280     *
1281     * The operation we're implementing is:
1282     *   if (x == y)
1283     *     return 0;
1284     *   else if (x < y)
1285     *     return -1;
1286     *   else if (x > y)
1287     *     return 1;
1288     *   else
1289     *     return {-1,1};  // one or both operands was NaN
1290     *
1291     * The straightforward implementation requires 3 calls to functions
1292     * that return a result in r0.  We can do it with two calls if our
1293     * EABI library supports __aeabi_cfcmple (only one if we want to check
1294     * for NaN directly):
1295     *   check x <= y
1296     *     if <, return -1
1297     *     if ==, return 0
1298     *   check y <= x
1299     *     if <, return 1
1300     *   return {-1,1}
1301     *
1302     * for: cmpl-float, cmpg-float
1303     */
1304    /* op vAA, vBB, vCC */
1305    FETCH(r0, 1)                        @ r0<- CCBB
1306    and     r2, r0, #255                @ r2<- BB
1307    mov     r3, r0, lsr #8              @ r3<- CC
1308    GET_VREG(r9, r2)                    @ r9<- vBB
1309    GET_VREG(r10, r3)                   @ r10<- vCC
1310    mov     r0, r9                      @ copy to arg registers
1311    mov     r1, r10
1312    bl      __aeabi_cfcmple             @ cmp <=: C clear if <, Z set if eq
1313    bhi     .LOP_CMPL_FLOAT_gt_or_nan       @ C set and Z clear, disambiguate
1314    mvncc   r1, #0                      @ (less than) r1<- -1
1315    moveq   r1, #0                      @ (equal) r1<- 0, trumps less than
1316.LOP_CMPL_FLOAT_finish:
1317    mov     r3, rINST, lsr #8           @ r3<- AA
1318    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1319    SET_VREG(r1, r3)                    @ vAA<- r1
1320    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1321    GOTO_OPCODE(ip)                     @ jump to next instruction
1322
1323/* ------------------------------ */
1324    .balign 64
1325.L_OP_CMPG_FLOAT: /* 0x2e */
1326/* File: armv5te/OP_CMPG_FLOAT.S */
1327/* File: armv5te/OP_CMPL_FLOAT.S */
1328    /*
1329     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1330     * destination register based on the results of the comparison.
1331     *
1332     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
1333     * on what value we'd like to return when one of the operands is NaN.
1334     *
1335     * The operation we're implementing is:
1336     *   if (x == y)
1337     *     return 0;
1338     *   else if (x < y)
1339     *     return -1;
1340     *   else if (x > y)
1341     *     return 1;
1342     *   else
1343     *     return {-1,1};  // one or both operands was NaN
1344     *
1345     * The straightforward implementation requires 3 calls to functions
1346     * that return a result in r0.  We can do it with two calls if our
1347     * EABI library supports __aeabi_cfcmple (only one if we want to check
1348     * for NaN directly):
1349     *   check x <= y
1350     *     if <, return -1
1351     *     if ==, return 0
1352     *   check y <= x
1353     *     if <, return 1
1354     *   return {-1,1}
1355     *
1356     * for: cmpl-float, cmpg-float
1357     */
1358    /* op vAA, vBB, vCC */
1359    FETCH(r0, 1)                        @ r0<- CCBB
1360    and     r2, r0, #255                @ r2<- BB
1361    mov     r3, r0, lsr #8              @ r3<- CC
1362    GET_VREG(r9, r2)                    @ r9<- vBB
1363    GET_VREG(r10, r3)                   @ r10<- vCC
1364    mov     r0, r9                      @ copy to arg registers
1365    mov     r1, r10
1366    bl      __aeabi_cfcmple             @ cmp <=: C clear if <, Z set if eq
1367    bhi     .LOP_CMPG_FLOAT_gt_or_nan       @ C set and Z clear, disambiguate
1368    mvncc   r1, #0                      @ (less than) r1<- -1
1369    moveq   r1, #0                      @ (equal) r1<- 0, trumps less than
1370.LOP_CMPG_FLOAT_finish:
1371    mov     r3, rINST, lsr #8           @ r3<- AA
1372    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1373    SET_VREG(r1, r3)                    @ vAA<- r1
1374    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1375    GOTO_OPCODE(ip)                     @ jump to next instruction
1376
1377
1378/* ------------------------------ */
1379    .balign 64
1380.L_OP_CMPL_DOUBLE: /* 0x2f */
1381/* File: armv5te/OP_CMPL_DOUBLE.S */
1382    /*
1383     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1384     * destination register based on the results of the comparison.
1385     *
1386     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
1387     * on what value we'd like to return when one of the operands is NaN.
1388     *
1389     * See OP_CMPL_FLOAT for an explanation.
1390     *
1391     * For: cmpl-double, cmpg-double
1392     */
1393    /* op vAA, vBB, vCC */
1394    FETCH(r0, 1)                        @ r0<- CCBB
1395    and     r9, r0, #255                @ r9<- BB
1396    mov     r10, r0, lsr #8             @ r10<- CC
1397    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BB]
1398    add     r10, rFP, r10, lsl #2       @ r10<- &fp[CC]
1399    ldmia   r9, {r0-r1}                 @ r0/r1<- vBB/vBB+1
1400    ldmia   r10, {r2-r3}                @ r2/r3<- vCC/vCC+1
1401    bl      __aeabi_cdcmple             @ cmp <=: C clear if <, Z set if eq
1402    bhi     .LOP_CMPL_DOUBLE_gt_or_nan       @ C set and Z clear, disambiguate
1403    mvncc   r1, #0                      @ (less than) r1<- -1
1404    moveq   r1, #0                      @ (equal) r1<- 0, trumps less than
1405.LOP_CMPL_DOUBLE_finish:
1406    mov     r3, rINST, lsr #8           @ r3<- AA
1407    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1408    SET_VREG(r1, r3)                    @ vAA<- r1
1409    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1410    GOTO_OPCODE(ip)                     @ jump to next instruction
1411
1412/* ------------------------------ */
1413    .balign 64
1414.L_OP_CMPG_DOUBLE: /* 0x30 */
1415/* File: armv5te/OP_CMPG_DOUBLE.S */
1416/* File: armv5te/OP_CMPL_DOUBLE.S */
1417    /*
1418     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1419     * destination register based on the results of the comparison.
1420     *
1421     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
1422     * on what value we'd like to return when one of the operands is NaN.
1423     *
1424     * See OP_CMPL_FLOAT for an explanation.
1425     *
1426     * For: cmpl-double, cmpg-double
1427     */
1428    /* op vAA, vBB, vCC */
1429    FETCH(r0, 1)                        @ r0<- CCBB
1430    and     r9, r0, #255                @ r9<- BB
1431    mov     r10, r0, lsr #8             @ r10<- CC
1432    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BB]
1433    add     r10, rFP, r10, lsl #2       @ r10<- &fp[CC]
1434    ldmia   r9, {r0-r1}                 @ r0/r1<- vBB/vBB+1
1435    ldmia   r10, {r2-r3}                @ r2/r3<- vCC/vCC+1
1436    bl      __aeabi_cdcmple             @ cmp <=: C clear if <, Z set if eq
1437    bhi     .LOP_CMPG_DOUBLE_gt_or_nan       @ C set and Z clear, disambiguate
1438    mvncc   r1, #0                      @ (less than) r1<- -1
1439    moveq   r1, #0                      @ (equal) r1<- 0, trumps less than
1440.LOP_CMPG_DOUBLE_finish:
1441    mov     r3, rINST, lsr #8           @ r3<- AA
1442    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1443    SET_VREG(r1, r3)                    @ vAA<- r1
1444    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1445    GOTO_OPCODE(ip)                     @ jump to next instruction
1446
1447
1448/* ------------------------------ */
1449    .balign 64
1450.L_OP_CMP_LONG: /* 0x31 */
1451/* File: armv5te/OP_CMP_LONG.S */
1452    /*
1453     * Compare two 64-bit values.  Puts 0, 1, or -1 into the destination
1454     * register based on the results of the comparison.
1455     *
1456     * We load the full values with LDM, but in practice many values could
1457     * be resolved by only looking at the high word.  This could be made
1458     * faster or slower by splitting the LDM into a pair of LDRs.
1459     *
1460     * If we just wanted to set condition flags, we could do this:
1461     *  subs    ip, r0, r2
1462     *  sbcs    ip, r1, r3
1463     *  subeqs  ip, r0, r2
1464     * Leaving { <0, 0, >0 } in ip.  However, we have to set it to a specific
1465     * integer value, which we can do with 2 conditional mov/mvn instructions
1466     * (set 1, set -1; if they're equal we already have 0 in ip), giving
1467     * us a constant 5-cycle path plus a branch at the end to the
1468     * instruction epilogue code.  The multi-compare approach below needs
1469     * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch
1470     * in the worst case (the 64-bit values are equal).
1471     */
1472    /* cmp-long vAA, vBB, vCC */
1473    FETCH(r0, 1)                        @ r0<- CCBB
1474    mov     r9, rINST, lsr #8           @ r9<- AA
1475    and     r2, r0, #255                @ r2<- BB
1476    mov     r3, r0, lsr #8              @ r3<- CC
1477    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
1478    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
1479    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
1480    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
1481    cmp     r1, r3                      @ compare (vBB+1, vCC+1)
1482    blt     .LOP_CMP_LONG_less            @ signed compare on high part
1483    bgt     .LOP_CMP_LONG_greater
1484    subs    r1, r0, r2                  @ r1<- r0 - r2
1485    bhi     .LOP_CMP_LONG_greater         @ unsigned compare on low part
1486    bne     .LOP_CMP_LONG_less
1487    b       .LOP_CMP_LONG_finish          @ equal; r1 already holds 0
1488
1489/* ------------------------------ */
1490    .balign 64
1491.L_OP_IF_EQ: /* 0x32 */
1492/* File: armv5te/OP_IF_EQ.S */
1493/* File: armv5te/bincmp.S */
1494    /*
1495     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1496     * fragment that specifies the *reverse* comparison to perform, e.g.
1497     * for "if-le" you would use "gt".
1498     *
1499     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1500     */
1501    /* if-cmp vA, vB, +CCCC */
1502    mov     r0, rINST, lsr #8           @ r0<- A+
1503    mov     r1, rINST, lsr #12          @ r1<- B
1504    and     r0, r0, #15
1505    GET_VREG(r3, r1)                    @ r3<- vB
1506    GET_VREG(r2, r0)                    @ r2<- vA
1507    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1508    cmp     r2, r3                      @ compare (vA, vB)
1509    bne  1f                      @ branch to 1 if comparison failed
1510    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1511    movs    r9, r9, asl #1              @ convert to bytes, check sign
1512    bmi     common_backwardBranch       @ yes, do periodic checks
15131:
1514#if defined(WITH_JIT)
1515    GET_JIT_PROF_TABLE(r0)
1516    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1517    b        common_testUpdateProfile
1518#else
1519    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1520    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1521    GOTO_OPCODE(ip)                     @ jump to next instruction
1522#endif
1523
1524
1525/* ------------------------------ */
1526    .balign 64
1527.L_OP_IF_NE: /* 0x33 */
1528/* File: armv5te/OP_IF_NE.S */
1529/* File: armv5te/bincmp.S */
1530    /*
1531     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1532     * fragment that specifies the *reverse* comparison to perform, e.g.
1533     * for "if-le" you would use "gt".
1534     *
1535     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1536     */
1537    /* if-cmp vA, vB, +CCCC */
1538    mov     r0, rINST, lsr #8           @ r0<- A+
1539    mov     r1, rINST, lsr #12          @ r1<- B
1540    and     r0, r0, #15
1541    GET_VREG(r3, r1)                    @ r3<- vB
1542    GET_VREG(r2, r0)                    @ r2<- vA
1543    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1544    cmp     r2, r3                      @ compare (vA, vB)
1545    beq  1f                      @ branch to 1 if comparison failed
1546    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1547    movs    r9, r9, asl #1              @ convert to bytes, check sign
1548    bmi     common_backwardBranch       @ yes, do periodic checks
15491:
1550#if defined(WITH_JIT)
1551    GET_JIT_PROF_TABLE(r0)
1552    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1553    b        common_testUpdateProfile
1554#else
1555    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1556    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1557    GOTO_OPCODE(ip)                     @ jump to next instruction
1558#endif
1559
1560
1561/* ------------------------------ */
1562    .balign 64
1563.L_OP_IF_LT: /* 0x34 */
1564/* File: armv5te/OP_IF_LT.S */
1565/* File: armv5te/bincmp.S */
1566    /*
1567     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1568     * fragment that specifies the *reverse* comparison to perform, e.g.
1569     * for "if-le" you would use "gt".
1570     *
1571     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1572     */
1573    /* if-cmp vA, vB, +CCCC */
1574    mov     r0, rINST, lsr #8           @ r0<- A+
1575    mov     r1, rINST, lsr #12          @ r1<- B
1576    and     r0, r0, #15
1577    GET_VREG(r3, r1)                    @ r3<- vB
1578    GET_VREG(r2, r0)                    @ r2<- vA
1579    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1580    cmp     r2, r3                      @ compare (vA, vB)
1581    bge  1f                      @ branch to 1 if comparison failed
1582    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1583    movs    r9, r9, asl #1              @ convert to bytes, check sign
1584    bmi     common_backwardBranch       @ yes, do periodic checks
15851:
1586#if defined(WITH_JIT)
1587    GET_JIT_PROF_TABLE(r0)
1588    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1589    b        common_testUpdateProfile
1590#else
1591    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1592    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1593    GOTO_OPCODE(ip)                     @ jump to next instruction
1594#endif
1595
1596
1597/* ------------------------------ */
1598    .balign 64
1599.L_OP_IF_GE: /* 0x35 */
1600/* File: armv5te/OP_IF_GE.S */
1601/* File: armv5te/bincmp.S */
1602    /*
1603     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1604     * fragment that specifies the *reverse* comparison to perform, e.g.
1605     * for "if-le" you would use "gt".
1606     *
1607     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1608     */
1609    /* if-cmp vA, vB, +CCCC */
1610    mov     r0, rINST, lsr #8           @ r0<- A+
1611    mov     r1, rINST, lsr #12          @ r1<- B
1612    and     r0, r0, #15
1613    GET_VREG(r3, r1)                    @ r3<- vB
1614    GET_VREG(r2, r0)                    @ r2<- vA
1615    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1616    cmp     r2, r3                      @ compare (vA, vB)
1617    blt  1f                      @ branch to 1 if comparison failed
1618    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1619    movs    r9, r9, asl #1              @ convert to bytes, check sign
1620    bmi     common_backwardBranch       @ yes, do periodic checks
16211:
1622#if defined(WITH_JIT)
1623    GET_JIT_PROF_TABLE(r0)
1624    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1625    b        common_testUpdateProfile
1626#else
1627    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1628    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1629    GOTO_OPCODE(ip)                     @ jump to next instruction
1630#endif
1631
1632
1633/* ------------------------------ */
1634    .balign 64
1635.L_OP_IF_GT: /* 0x36 */
1636/* File: armv5te/OP_IF_GT.S */
1637/* File: armv5te/bincmp.S */
1638    /*
1639     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1640     * fragment that specifies the *reverse* comparison to perform, e.g.
1641     * for "if-le" you would use "gt".
1642     *
1643     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1644     */
1645    /* if-cmp vA, vB, +CCCC */
1646    mov     r0, rINST, lsr #8           @ r0<- A+
1647    mov     r1, rINST, lsr #12          @ r1<- B
1648    and     r0, r0, #15
1649    GET_VREG(r3, r1)                    @ r3<- vB
1650    GET_VREG(r2, r0)                    @ r2<- vA
1651    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1652    cmp     r2, r3                      @ compare (vA, vB)
1653    ble  1f                      @ branch to 1 if comparison failed
1654    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1655    movs    r9, r9, asl #1              @ convert to bytes, check sign
1656    bmi     common_backwardBranch       @ yes, do periodic checks
16571:
1658#if defined(WITH_JIT)
1659    GET_JIT_PROF_TABLE(r0)
1660    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1661    b        common_testUpdateProfile
1662#else
1663    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1664    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1665    GOTO_OPCODE(ip)                     @ jump to next instruction
1666#endif
1667
1668
1669/* ------------------------------ */
1670    .balign 64
1671.L_OP_IF_LE: /* 0x37 */
1672/* File: armv5te/OP_IF_LE.S */
1673/* File: armv5te/bincmp.S */
1674    /*
1675     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1676     * fragment that specifies the *reverse* comparison to perform, e.g.
1677     * for "if-le" you would use "gt".
1678     *
1679     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1680     */
1681    /* if-cmp vA, vB, +CCCC */
1682    mov     r0, rINST, lsr #8           @ r0<- A+
1683    mov     r1, rINST, lsr #12          @ r1<- B
1684    and     r0, r0, #15
1685    GET_VREG(r3, r1)                    @ r3<- vB
1686    GET_VREG(r2, r0)                    @ r2<- vA
1687    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1688    cmp     r2, r3                      @ compare (vA, vB)
1689    bgt  1f                      @ branch to 1 if comparison failed
1690    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1691    movs    r9, r9, asl #1              @ convert to bytes, check sign
1692    bmi     common_backwardBranch       @ yes, do periodic checks
16931:
1694#if defined(WITH_JIT)
1695    GET_JIT_PROF_TABLE(r0)
1696    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1697    b        common_testUpdateProfile
1698#else
1699    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1700    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1701    GOTO_OPCODE(ip)                     @ jump to next instruction
1702#endif
1703
1704
1705/* ------------------------------ */
1706    .balign 64
1707.L_OP_IF_EQZ: /* 0x38 */
1708/* File: armv5te/OP_IF_EQZ.S */
1709/* File: armv5te/zcmp.S */
1710    /*
1711     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1712     * fragment that specifies the *reverse* comparison to perform, e.g.
1713     * for "if-le" you would use "gt".
1714     *
1715     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1716     */
1717    /* if-cmp vAA, +BBBB */
1718    mov     r0, rINST, lsr #8           @ r0<- AA
1719    GET_VREG(r2, r0)                    @ r2<- vAA
1720    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1721    cmp     r2, #0                      @ compare (vA, 0)
1722    bne  1f                      @ branch to 1 if comparison failed
1723    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1724    movs    r9, r9, asl #1              @ convert to bytes, check sign
1725    bmi     common_backwardBranch       @ backward branch, do periodic checks
17261:
1727#if defined(WITH_JIT)
1728    GET_JIT_PROF_TABLE(r0)
1729    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1730    cmp     r0,#0
1731    bne     common_updateProfile
1732    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1733    GOTO_OPCODE(ip)                     @ jump to next instruction
1734#else
1735    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1736    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1737    GOTO_OPCODE(ip)                     @ jump to next instruction
1738#endif
1739
1740
1741/* ------------------------------ */
1742    .balign 64
1743.L_OP_IF_NEZ: /* 0x39 */
1744/* File: armv5te/OP_IF_NEZ.S */
1745/* File: armv5te/zcmp.S */
1746    /*
1747     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1748     * fragment that specifies the *reverse* comparison to perform, e.g.
1749     * for "if-le" you would use "gt".
1750     *
1751     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1752     */
1753    /* if-cmp vAA, +BBBB */
1754    mov     r0, rINST, lsr #8           @ r0<- AA
1755    GET_VREG(r2, r0)                    @ r2<- vAA
1756    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1757    cmp     r2, #0                      @ compare (vA, 0)
1758    beq  1f                      @ branch to 1 if comparison failed
1759    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1760    movs    r9, r9, asl #1              @ convert to bytes, check sign
1761    bmi     common_backwardBranch       @ backward branch, do periodic checks
17621:
1763#if defined(WITH_JIT)
1764    GET_JIT_PROF_TABLE(r0)
1765    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1766    cmp     r0,#0
1767    bne     common_updateProfile
1768    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1769    GOTO_OPCODE(ip)                     @ jump to next instruction
1770#else
1771    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1772    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1773    GOTO_OPCODE(ip)                     @ jump to next instruction
1774#endif
1775
1776
1777/* ------------------------------ */
1778    .balign 64
1779.L_OP_IF_LTZ: /* 0x3a */
1780/* File: armv5te/OP_IF_LTZ.S */
1781/* File: armv5te/zcmp.S */
1782    /*
1783     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1784     * fragment that specifies the *reverse* comparison to perform, e.g.
1785     * for "if-le" you would use "gt".
1786     *
1787     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1788     */
1789    /* if-cmp vAA, +BBBB */
1790    mov     r0, rINST, lsr #8           @ r0<- AA
1791    GET_VREG(r2, r0)                    @ r2<- vAA
1792    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1793    cmp     r2, #0                      @ compare (vA, 0)
1794    bge  1f                      @ branch to 1 if comparison failed
1795    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1796    movs    r9, r9, asl #1              @ convert to bytes, check sign
1797    bmi     common_backwardBranch       @ backward branch, do periodic checks
17981:
1799#if defined(WITH_JIT)
1800    GET_JIT_PROF_TABLE(r0)
1801    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1802    cmp     r0,#0
1803    bne     common_updateProfile
1804    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1805    GOTO_OPCODE(ip)                     @ jump to next instruction
1806#else
1807    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1808    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1809    GOTO_OPCODE(ip)                     @ jump to next instruction
1810#endif
1811
1812
1813/* ------------------------------ */
1814    .balign 64
1815.L_OP_IF_GEZ: /* 0x3b */
1816/* File: armv5te/OP_IF_GEZ.S */
1817/* File: armv5te/zcmp.S */
1818    /*
1819     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1820     * fragment that specifies the *reverse* comparison to perform, e.g.
1821     * for "if-le" you would use "gt".
1822     *
1823     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1824     */
1825    /* if-cmp vAA, +BBBB */
1826    mov     r0, rINST, lsr #8           @ r0<- AA
1827    GET_VREG(r2, r0)                    @ r2<- vAA
1828    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1829    cmp     r2, #0                      @ compare (vA, 0)
1830    blt  1f                      @ branch to 1 if comparison failed
1831    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1832    movs    r9, r9, asl #1              @ convert to bytes, check sign
1833    bmi     common_backwardBranch       @ backward branch, do periodic checks
18341:
1835#if defined(WITH_JIT)
1836    GET_JIT_PROF_TABLE(r0)
1837    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1838    cmp     r0,#0
1839    bne     common_updateProfile
1840    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1841    GOTO_OPCODE(ip)                     @ jump to next instruction
1842#else
1843    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1844    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1845    GOTO_OPCODE(ip)                     @ jump to next instruction
1846#endif
1847
1848
1849/* ------------------------------ */
1850    .balign 64
1851.L_OP_IF_GTZ: /* 0x3c */
1852/* File: armv5te/OP_IF_GTZ.S */
1853/* File: armv5te/zcmp.S */
1854    /*
1855     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1856     * fragment that specifies the *reverse* comparison to perform, e.g.
1857     * for "if-le" you would use "gt".
1858     *
1859     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1860     */
1861    /* if-cmp vAA, +BBBB */
1862    mov     r0, rINST, lsr #8           @ r0<- AA
1863    GET_VREG(r2, r0)                    @ r2<- vAA
1864    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1865    cmp     r2, #0                      @ compare (vA, 0)
1866    ble  1f                      @ branch to 1 if comparison failed
1867    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1868    movs    r9, r9, asl #1              @ convert to bytes, check sign
1869    bmi     common_backwardBranch       @ backward branch, do periodic checks
18701:
1871#if defined(WITH_JIT)
1872    GET_JIT_PROF_TABLE(r0)
1873    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1874    cmp     r0,#0
1875    bne     common_updateProfile
1876    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1877    GOTO_OPCODE(ip)                     @ jump to next instruction
1878#else
1879    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1880    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1881    GOTO_OPCODE(ip)                     @ jump to next instruction
1882#endif
1883
1884
1885/* ------------------------------ */
1886    .balign 64
1887.L_OP_IF_LEZ: /* 0x3d */
1888/* File: armv5te/OP_IF_LEZ.S */
1889/* File: armv5te/zcmp.S */
1890    /*
1891     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1892     * fragment that specifies the *reverse* comparison to perform, e.g.
1893     * for "if-le" you would use "gt".
1894     *
1895     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1896     */
1897    /* if-cmp vAA, +BBBB */
1898    mov     r0, rINST, lsr #8           @ r0<- AA
1899    GET_VREG(r2, r0)                    @ r2<- vAA
1900    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1901    cmp     r2, #0                      @ compare (vA, 0)
1902    bgt  1f                      @ branch to 1 if comparison failed
1903    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1904    movs    r9, r9, asl #1              @ convert to bytes, check sign
1905    bmi     common_backwardBranch       @ backward branch, do periodic checks
19061:
1907#if defined(WITH_JIT)
1908    GET_JIT_PROF_TABLE(r0)
1909    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1910    cmp     r0,#0
1911    bne     common_updateProfile
1912    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1913    GOTO_OPCODE(ip)                     @ jump to next instruction
1914#else
1915    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1916    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1917    GOTO_OPCODE(ip)                     @ jump to next instruction
1918#endif
1919
1920
1921/* ------------------------------ */
1922    .balign 64
1923.L_OP_UNUSED_3E: /* 0x3e */
1924/* File: armv5te/OP_UNUSED_3E.S */
1925/* File: armv5te/unused.S */
1926    bl      common_abort
1927
1928
1929/* ------------------------------ */
1930    .balign 64
1931.L_OP_UNUSED_3F: /* 0x3f */
1932/* File: armv5te/OP_UNUSED_3F.S */
1933/* File: armv5te/unused.S */
1934    bl      common_abort
1935
1936
1937/* ------------------------------ */
1938    .balign 64
1939.L_OP_UNUSED_40: /* 0x40 */
1940/* File: armv5te/OP_UNUSED_40.S */
1941/* File: armv5te/unused.S */
1942    bl      common_abort
1943
1944
1945/* ------------------------------ */
1946    .balign 64
1947.L_OP_UNUSED_41: /* 0x41 */
1948/* File: armv5te/OP_UNUSED_41.S */
1949/* File: armv5te/unused.S */
1950    bl      common_abort
1951
1952
1953/* ------------------------------ */
1954    .balign 64
1955.L_OP_UNUSED_42: /* 0x42 */
1956/* File: armv5te/OP_UNUSED_42.S */
1957/* File: armv5te/unused.S */
1958    bl      common_abort
1959
1960
1961/* ------------------------------ */
1962    .balign 64
1963.L_OP_UNUSED_43: /* 0x43 */
1964/* File: armv5te/OP_UNUSED_43.S */
1965/* File: armv5te/unused.S */
1966    bl      common_abort
1967
1968
1969/* ------------------------------ */
1970    .balign 64
1971.L_OP_AGET: /* 0x44 */
1972/* File: armv5te/OP_AGET.S */
1973    /*
1974     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1975     *
1976     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
1977     * instructions.  We use a pair of FETCH_Bs instead.
1978     *
1979     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1980     */
1981    /* op vAA, vBB, vCC */
1982    FETCH_B(r2, 1, 0)                   @ r2<- BB
1983    mov     r9, rINST, lsr #8           @ r9<- AA
1984    FETCH_B(r3, 1, 1)                   @ r3<- CC
1985    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1986    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1987    cmp     r0, #0                      @ null array object?
1988    beq     common_errNullObject        @ yes, bail
1989    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1990    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
1991    cmp     r1, r3                      @ compare unsigned index, length
1992    bcs     common_errArrayIndex        @ index >= length, bail
1993    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1994    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
1995    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1996    SET_VREG(r2, r9)                    @ vAA<- r2
1997    GOTO_OPCODE(ip)                     @ jump to next instruction
1998
1999/* ------------------------------ */
2000    .balign 64
2001.L_OP_AGET_WIDE: /* 0x45 */
2002/* File: armv5te/OP_AGET_WIDE.S */
2003    /*
2004     * Array get, 64 bits.  vAA <- vBB[vCC].
2005     *
2006     * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD.
2007     */
2008    /* aget-wide vAA, vBB, vCC */
2009    FETCH(r0, 1)                        @ r0<- CCBB
2010    mov     r9, rINST, lsr #8           @ r9<- AA
2011    and     r2, r0, #255                @ r2<- BB
2012    mov     r3, r0, lsr #8              @ r3<- CC
2013    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2014    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2015    cmp     r0, #0                      @ null array object?
2016    beq     common_errNullObject        @ yes, bail
2017    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2018    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
2019    cmp     r1, r3                      @ compare unsigned index, length
2020    bcc     .LOP_AGET_WIDE_finish          @ okay, continue below
2021    b       common_errArrayIndex        @ index >= length, bail
2022    @ May want to swap the order of these two branches depending on how the
2023    @ branch prediction (if any) handles conditional forward branches vs.
2024    @ unconditional forward branches.
2025
2026/* ------------------------------ */
2027    .balign 64
2028.L_OP_AGET_OBJECT: /* 0x46 */
2029/* File: armv5te/OP_AGET_OBJECT.S */
2030/* File: armv5te/OP_AGET.S */
2031    /*
2032     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2033     *
2034     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2035     * instructions.  We use a pair of FETCH_Bs instead.
2036     *
2037     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2038     */
2039    /* op vAA, vBB, vCC */
2040    FETCH_B(r2, 1, 0)                   @ r2<- BB
2041    mov     r9, rINST, lsr #8           @ r9<- AA
2042    FETCH_B(r3, 1, 1)                   @ r3<- CC
2043    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2044    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2045    cmp     r0, #0                      @ null array object?
2046    beq     common_errNullObject        @ yes, bail
2047    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2048    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
2049    cmp     r1, r3                      @ compare unsigned index, length
2050    bcs     common_errArrayIndex        @ index >= length, bail
2051    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2052    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2053    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2054    SET_VREG(r2, r9)                    @ vAA<- r2
2055    GOTO_OPCODE(ip)                     @ jump to next instruction
2056
2057
2058/* ------------------------------ */
2059    .balign 64
2060.L_OP_AGET_BOOLEAN: /* 0x47 */
2061/* File: armv5te/OP_AGET_BOOLEAN.S */
2062/* File: armv5te/OP_AGET.S */
2063    /*
2064     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2065     *
2066     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2067     * instructions.  We use a pair of FETCH_Bs instead.
2068     *
2069     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2070     */
2071    /* op vAA, vBB, vCC */
2072    FETCH_B(r2, 1, 0)                   @ r2<- BB
2073    mov     r9, rINST, lsr #8           @ r9<- AA
2074    FETCH_B(r3, 1, 1)                   @ r3<- CC
2075    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2076    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2077    cmp     r0, #0                      @ null array object?
2078    beq     common_errNullObject        @ yes, bail
2079    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2080    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2081    cmp     r1, r3                      @ compare unsigned index, length
2082    bcs     common_errArrayIndex        @ index >= length, bail
2083    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2084    ldrb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2085    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2086    SET_VREG(r2, r9)                    @ vAA<- r2
2087    GOTO_OPCODE(ip)                     @ jump to next instruction
2088
2089
2090/* ------------------------------ */
2091    .balign 64
2092.L_OP_AGET_BYTE: /* 0x48 */
2093/* File: armv5te/OP_AGET_BYTE.S */
2094/* File: armv5te/OP_AGET.S */
2095    /*
2096     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2097     *
2098     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2099     * instructions.  We use a pair of FETCH_Bs instead.
2100     *
2101     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2102     */
2103    /* op vAA, vBB, vCC */
2104    FETCH_B(r2, 1, 0)                   @ r2<- BB
2105    mov     r9, rINST, lsr #8           @ r9<- AA
2106    FETCH_B(r3, 1, 1)                   @ r3<- CC
2107    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2108    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2109    cmp     r0, #0                      @ null array object?
2110    beq     common_errNullObject        @ yes, bail
2111    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2112    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2113    cmp     r1, r3                      @ compare unsigned index, length
2114    bcs     common_errArrayIndex        @ index >= length, bail
2115    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2116    ldrsb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2117    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2118    SET_VREG(r2, r9)                    @ vAA<- r2
2119    GOTO_OPCODE(ip)                     @ jump to next instruction
2120
2121
2122/* ------------------------------ */
2123    .balign 64
2124.L_OP_AGET_CHAR: /* 0x49 */
2125/* File: armv5te/OP_AGET_CHAR.S */
2126/* File: armv5te/OP_AGET.S */
2127    /*
2128     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2129     *
2130     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2131     * instructions.  We use a pair of FETCH_Bs instead.
2132     *
2133     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2134     */
2135    /* op vAA, vBB, vCC */
2136    FETCH_B(r2, 1, 0)                   @ r2<- BB
2137    mov     r9, rINST, lsr #8           @ r9<- AA
2138    FETCH_B(r3, 1, 1)                   @ r3<- CC
2139    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2140    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2141    cmp     r0, #0                      @ null array object?
2142    beq     common_errNullObject        @ yes, bail
2143    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2144    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2145    cmp     r1, r3                      @ compare unsigned index, length
2146    bcs     common_errArrayIndex        @ index >= length, bail
2147    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2148    ldrh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2149    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2150    SET_VREG(r2, r9)                    @ vAA<- r2
2151    GOTO_OPCODE(ip)                     @ jump to next instruction
2152
2153
2154/* ------------------------------ */
2155    .balign 64
2156.L_OP_AGET_SHORT: /* 0x4a */
2157/* File: armv5te/OP_AGET_SHORT.S */
2158/* File: armv5te/OP_AGET.S */
2159    /*
2160     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2161     *
2162     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2163     * instructions.  We use a pair of FETCH_Bs instead.
2164     *
2165     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2166     */
2167    /* op vAA, vBB, vCC */
2168    FETCH_B(r2, 1, 0)                   @ r2<- BB
2169    mov     r9, rINST, lsr #8           @ r9<- AA
2170    FETCH_B(r3, 1, 1)                   @ r3<- CC
2171    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2172    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2173    cmp     r0, #0                      @ null array object?
2174    beq     common_errNullObject        @ yes, bail
2175    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2176    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2177    cmp     r1, r3                      @ compare unsigned index, length
2178    bcs     common_errArrayIndex        @ index >= length, bail
2179    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2180    ldrsh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2181    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2182    SET_VREG(r2, r9)                    @ vAA<- r2
2183    GOTO_OPCODE(ip)                     @ jump to next instruction
2184
2185
2186/* ------------------------------ */
2187    .balign 64
2188.L_OP_APUT: /* 0x4b */
2189/* File: armv5te/OP_APUT.S */
2190    /*
2191     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2192     *
2193     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2194     * instructions.  We use a pair of FETCH_Bs instead.
2195     *
2196     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2197     */
2198    /* op vAA, vBB, vCC */
2199    FETCH_B(r2, 1, 0)                   @ r2<- BB
2200    mov     r9, rINST, lsr #8           @ r9<- AA
2201    FETCH_B(r3, 1, 1)                   @ r3<- CC
2202    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2203    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2204    cmp     r0, #0                      @ null array object?
2205    beq     common_errNullObject        @ yes, bail
2206    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2207    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
2208    cmp     r1, r3                      @ compare unsigned index, length
2209    bcs     common_errArrayIndex        @ index >= length, bail
2210    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2211    GET_VREG(r2, r9)                    @ r2<- vAA
2212    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2213    str  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2214    GOTO_OPCODE(ip)                     @ jump to next instruction
2215
2216/* ------------------------------ */
2217    .balign 64
2218.L_OP_APUT_WIDE: /* 0x4c */
2219/* File: armv5te/OP_APUT_WIDE.S */
2220    /*
2221     * Array put, 64 bits.  vBB[vCC] <- vAA.
2222     *
2223     * Arrays of long/double are 64-bit aligned, so it's okay to use STRD.
2224     */
2225    /* aput-wide vAA, vBB, vCC */
2226    FETCH(r0, 1)                        @ r0<- CCBB
2227    mov     r9, rINST, lsr #8           @ r9<- AA
2228    and     r2, r0, #255                @ r2<- BB
2229    mov     r3, r0, lsr #8              @ r3<- CC
2230    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2231    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2232    cmp     r0, #0                      @ null array object?
2233    beq     common_errNullObject        @ yes, bail
2234    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2235    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
2236    cmp     r1, r3                      @ compare unsigned index, length
2237    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2238    bcc     .LOP_APUT_WIDE_finish          @ okay, continue below
2239    b       common_errArrayIndex        @ index >= length, bail
2240    @ May want to swap the order of these two branches depending on how the
2241    @ branch prediction (if any) handles conditional forward branches vs.
2242    @ unconditional forward branches.
2243
2244/* ------------------------------ */
2245    .balign 64
2246.L_OP_APUT_OBJECT: /* 0x4d */
2247/* File: armv5te/OP_APUT_OBJECT.S */
2248    /*
2249     * Store an object into an array.  vBB[vCC] <- vAA.
2250     */
2251    /* op vAA, vBB, vCC */
2252    FETCH(r0, 1)                        @ r0<- CCBB
2253    mov     r9, rINST, lsr #8           @ r9<- AA
2254    and     r2, r0, #255                @ r2<- BB
2255    mov     r3, r0, lsr #8              @ r3<- CC
2256    GET_VREG(rINST, r2)                 @ rINST<- vBB (array object)
2257    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2258    cmp     rINST, #0                   @ null array object?
2259    GET_VREG(r9, r9)                    @ r9<- vAA
2260    beq     common_errNullObject        @ yes, bail
2261    ldr     r3, [rINST, #offArrayObject_length]   @ r3<- arrayObj->length
2262    add     r10, rINST, r1, lsl #2      @ r10<- arrayObj + index*width
2263    cmp     r1, r3                      @ compare unsigned index, length
2264    bcc     .LOP_APUT_OBJECT_finish          @ we're okay, continue on
2265    b       common_errArrayIndex        @ index >= length, bail
2266
2267
2268/* ------------------------------ */
2269    .balign 64
2270.L_OP_APUT_BOOLEAN: /* 0x4e */
2271/* File: armv5te/OP_APUT_BOOLEAN.S */
2272/* File: armv5te/OP_APUT.S */
2273    /*
2274     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2275     *
2276     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2277     * instructions.  We use a pair of FETCH_Bs instead.
2278     *
2279     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2280     */
2281    /* op vAA, vBB, vCC */
2282    FETCH_B(r2, 1, 0)                   @ r2<- BB
2283    mov     r9, rINST, lsr #8           @ r9<- AA
2284    FETCH_B(r3, 1, 1)                   @ r3<- CC
2285    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2286    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2287    cmp     r0, #0                      @ null array object?
2288    beq     common_errNullObject        @ yes, bail
2289    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2290    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2291    cmp     r1, r3                      @ compare unsigned index, length
2292    bcs     common_errArrayIndex        @ index >= length, bail
2293    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2294    GET_VREG(r2, r9)                    @ r2<- vAA
2295    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2296    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2297    GOTO_OPCODE(ip)                     @ jump to next instruction
2298
2299
2300/* ------------------------------ */
2301    .balign 64
2302.L_OP_APUT_BYTE: /* 0x4f */
2303/* File: armv5te/OP_APUT_BYTE.S */
2304/* File: armv5te/OP_APUT.S */
2305    /*
2306     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2307     *
2308     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2309     * instructions.  We use a pair of FETCH_Bs instead.
2310     *
2311     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2312     */
2313    /* op vAA, vBB, vCC */
2314    FETCH_B(r2, 1, 0)                   @ r2<- BB
2315    mov     r9, rINST, lsr #8           @ r9<- AA
2316    FETCH_B(r3, 1, 1)                   @ r3<- CC
2317    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2318    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2319    cmp     r0, #0                      @ null array object?
2320    beq     common_errNullObject        @ yes, bail
2321    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2322    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2323    cmp     r1, r3                      @ compare unsigned index, length
2324    bcs     common_errArrayIndex        @ index >= length, bail
2325    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2326    GET_VREG(r2, r9)                    @ r2<- vAA
2327    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2328    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2329    GOTO_OPCODE(ip)                     @ jump to next instruction
2330
2331
2332/* ------------------------------ */
2333    .balign 64
2334.L_OP_APUT_CHAR: /* 0x50 */
2335/* File: armv5te/OP_APUT_CHAR.S */
2336/* File: armv5te/OP_APUT.S */
2337    /*
2338     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2339     *
2340     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2341     * instructions.  We use a pair of FETCH_Bs instead.
2342     *
2343     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2344     */
2345    /* op vAA, vBB, vCC */
2346    FETCH_B(r2, 1, 0)                   @ r2<- BB
2347    mov     r9, rINST, lsr #8           @ r9<- AA
2348    FETCH_B(r3, 1, 1)                   @ r3<- CC
2349    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2350    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2351    cmp     r0, #0                      @ null array object?
2352    beq     common_errNullObject        @ yes, bail
2353    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2354    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2355    cmp     r1, r3                      @ compare unsigned index, length
2356    bcs     common_errArrayIndex        @ index >= length, bail
2357    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2358    GET_VREG(r2, r9)                    @ r2<- vAA
2359    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2360    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2361    GOTO_OPCODE(ip)                     @ jump to next instruction
2362
2363
2364/* ------------------------------ */
2365    .balign 64
2366.L_OP_APUT_SHORT: /* 0x51 */
2367/* File: armv5te/OP_APUT_SHORT.S */
2368/* File: armv5te/OP_APUT.S */
2369    /*
2370     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2371     *
2372     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2373     * instructions.  We use a pair of FETCH_Bs instead.
2374     *
2375     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2376     */
2377    /* op vAA, vBB, vCC */
2378    FETCH_B(r2, 1, 0)                   @ r2<- BB
2379    mov     r9, rINST, lsr #8           @ r9<- AA
2380    FETCH_B(r3, 1, 1)                   @ r3<- CC
2381    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2382    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2383    cmp     r0, #0                      @ null array object?
2384    beq     common_errNullObject        @ yes, bail
2385    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2386    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2387    cmp     r1, r3                      @ compare unsigned index, length
2388    bcs     common_errArrayIndex        @ index >= length, bail
2389    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2390    GET_VREG(r2, r9)                    @ r2<- vAA
2391    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2392    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2393    GOTO_OPCODE(ip)                     @ jump to next instruction
2394
2395
2396/* ------------------------------ */
2397    .balign 64
2398.L_OP_IGET: /* 0x52 */
2399/* File: armv5te/OP_IGET.S */
2400    /*
2401     * General 32-bit instance field get.
2402     *
2403     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2404     */
2405    /* op vA, vB, field@CCCC */
2406    mov     r0, rINST, lsr #12          @ r0<- B
2407    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2408    FETCH(r1, 1)                        @ r1<- field ref CCCC
2409    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2410    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2411    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2412    cmp     r0, #0                      @ is resolved entry null?
2413    bne     .LOP_IGET_finish          @ no, already resolved
24148:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2415    EXPORT_PC()                         @ resolve() could throw
2416    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2417    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2418    cmp     r0, #0
2419    bne     .LOP_IGET_finish
2420    b       common_exceptionThrown
2421
2422/* ------------------------------ */
2423    .balign 64
2424.L_OP_IGET_WIDE: /* 0x53 */
2425/* File: armv5te/OP_IGET_WIDE.S */
2426    /*
2427     * Wide 32-bit instance field get.
2428     */
2429    /* iget-wide vA, vB, field@CCCC */
2430    mov     r0, rINST, lsr #12          @ r0<- B
2431    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2432    FETCH(r1, 1)                        @ r1<- field ref CCCC
2433    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
2434    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2435    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2436    cmp     r0, #0                      @ is resolved entry null?
2437    bne     .LOP_IGET_WIDE_finish          @ no, already resolved
24388:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
2439    EXPORT_PC()                         @ resolve() could throw
2440    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2441    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2442    cmp     r0, #0
2443    bne     .LOP_IGET_WIDE_finish
2444    b       common_exceptionThrown
2445
2446/* ------------------------------ */
2447    .balign 64
2448.L_OP_IGET_OBJECT: /* 0x54 */
2449/* File: armv5te/OP_IGET_OBJECT.S */
2450/* File: armv5te/OP_IGET.S */
2451    /*
2452     * General 32-bit instance field get.
2453     *
2454     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2455     */
2456    /* op vA, vB, field@CCCC */
2457    mov     r0, rINST, lsr #12          @ r0<- B
2458    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2459    FETCH(r1, 1)                        @ r1<- field ref CCCC
2460    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2461    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2462    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2463    cmp     r0, #0                      @ is resolved entry null?
2464    bne     .LOP_IGET_OBJECT_finish          @ no, already resolved
24658:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2466    EXPORT_PC()                         @ resolve() could throw
2467    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2468    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2469    cmp     r0, #0
2470    bne     .LOP_IGET_OBJECT_finish
2471    b       common_exceptionThrown
2472
2473
2474/* ------------------------------ */
2475    .balign 64
2476.L_OP_IGET_BOOLEAN: /* 0x55 */
2477/* File: armv5te/OP_IGET_BOOLEAN.S */
2478@include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" }
2479/* File: armv5te/OP_IGET.S */
2480    /*
2481     * General 32-bit instance field get.
2482     *
2483     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2484     */
2485    /* op vA, vB, field@CCCC */
2486    mov     r0, rINST, lsr #12          @ r0<- B
2487    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2488    FETCH(r1, 1)                        @ r1<- field ref CCCC
2489    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2490    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2491    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2492    cmp     r0, #0                      @ is resolved entry null?
2493    bne     .LOP_IGET_BOOLEAN_finish          @ no, already resolved
24948:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2495    EXPORT_PC()                         @ resolve() could throw
2496    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2497    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2498    cmp     r0, #0
2499    bne     .LOP_IGET_BOOLEAN_finish
2500    b       common_exceptionThrown
2501
2502
2503/* ------------------------------ */
2504    .balign 64
2505.L_OP_IGET_BYTE: /* 0x56 */
2506/* File: armv5te/OP_IGET_BYTE.S */
2507@include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" }
2508/* File: armv5te/OP_IGET.S */
2509    /*
2510     * General 32-bit instance field get.
2511     *
2512     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2513     */
2514    /* op vA, vB, field@CCCC */
2515    mov     r0, rINST, lsr #12          @ r0<- B
2516    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2517    FETCH(r1, 1)                        @ r1<- field ref CCCC
2518    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2519    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2520    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2521    cmp     r0, #0                      @ is resolved entry null?
2522    bne     .LOP_IGET_BYTE_finish          @ no, already resolved
25238:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2524    EXPORT_PC()                         @ resolve() could throw
2525    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2526    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2527    cmp     r0, #0
2528    bne     .LOP_IGET_BYTE_finish
2529    b       common_exceptionThrown
2530
2531
2532/* ------------------------------ */
2533    .balign 64
2534.L_OP_IGET_CHAR: /* 0x57 */
2535/* File: armv5te/OP_IGET_CHAR.S */
2536@include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" }
2537/* File: armv5te/OP_IGET.S */
2538    /*
2539     * General 32-bit instance field get.
2540     *
2541     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2542     */
2543    /* op vA, vB, field@CCCC */
2544    mov     r0, rINST, lsr #12          @ r0<- B
2545    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2546    FETCH(r1, 1)                        @ r1<- field ref CCCC
2547    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2548    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2549    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2550    cmp     r0, #0                      @ is resolved entry null?
2551    bne     .LOP_IGET_CHAR_finish          @ no, already resolved
25528:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2553    EXPORT_PC()                         @ resolve() could throw
2554    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2555    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2556    cmp     r0, #0
2557    bne     .LOP_IGET_CHAR_finish
2558    b       common_exceptionThrown
2559
2560
2561/* ------------------------------ */
2562    .balign 64
2563.L_OP_IGET_SHORT: /* 0x58 */
2564/* File: armv5te/OP_IGET_SHORT.S */
2565@include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" }
2566/* File: armv5te/OP_IGET.S */
2567    /*
2568     * General 32-bit instance field get.
2569     *
2570     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2571     */
2572    /* op vA, vB, field@CCCC */
2573    mov     r0, rINST, lsr #12          @ r0<- B
2574    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2575    FETCH(r1, 1)                        @ r1<- field ref CCCC
2576    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2577    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2578    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2579    cmp     r0, #0                      @ is resolved entry null?
2580    bne     .LOP_IGET_SHORT_finish          @ no, already resolved
25818:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2582    EXPORT_PC()                         @ resolve() could throw
2583    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2584    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2585    cmp     r0, #0
2586    bne     .LOP_IGET_SHORT_finish
2587    b       common_exceptionThrown
2588
2589
2590/* ------------------------------ */
2591    .balign 64
2592.L_OP_IPUT: /* 0x59 */
2593/* File: armv5te/OP_IPUT.S */
2594    /*
2595     * General 32-bit instance field put.
2596     *
2597     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2598     */
2599    /* op vA, vB, field@CCCC */
2600    mov     r0, rINST, lsr #12          @ r0<- B
2601    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2602    FETCH(r1, 1)                        @ r1<- field ref CCCC
2603    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2604    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2605    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2606    cmp     r0, #0                      @ is resolved entry null?
2607    bne     .LOP_IPUT_finish          @ no, already resolved
26088:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2609    EXPORT_PC()                         @ resolve() could throw
2610    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2611    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2612    cmp     r0, #0                      @ success?
2613    bne     .LOP_IPUT_finish          @ yes, finish up
2614    b       common_exceptionThrown
2615
2616/* ------------------------------ */
2617    .balign 64
2618.L_OP_IPUT_WIDE: /* 0x5a */
2619/* File: armv5te/OP_IPUT_WIDE.S */
2620    /* iput-wide vA, vB, field@CCCC */
2621    mov     r0, rINST, lsr #12          @ r0<- B
2622    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2623    FETCH(r1, 1)                        @ r1<- field ref CCCC
2624    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
2625    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2626    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2627    cmp     r0, #0                      @ is resolved entry null?
2628    bne     .LOP_IPUT_WIDE_finish          @ no, already resolved
26298:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
2630    EXPORT_PC()                         @ resolve() could throw
2631    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2632    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2633    cmp     r0, #0                      @ success?
2634    bne     .LOP_IPUT_WIDE_finish          @ yes, finish up
2635    b       common_exceptionThrown
2636
2637/* ------------------------------ */
2638    .balign 64
2639.L_OP_IPUT_OBJECT: /* 0x5b */
2640/* File: armv5te/OP_IPUT_OBJECT.S */
2641    /*
2642     * 32-bit instance field put.
2643     *
2644     * for: iput-object, iput-object-volatile
2645     */
2646    /* op vA, vB, field@CCCC */
2647    mov     r0, rINST, lsr #12          @ r0<- B
2648    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2649    FETCH(r1, 1)                        @ r1<- field ref CCCC
2650    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2651    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2652    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2653    cmp     r0, #0                      @ is resolved entry null?
2654    bne     .LOP_IPUT_OBJECT_finish          @ no, already resolved
26558:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2656    EXPORT_PC()                         @ resolve() could throw
2657    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2658    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2659    cmp     r0, #0                      @ success?
2660    bne     .LOP_IPUT_OBJECT_finish          @ yes, finish up
2661    b       common_exceptionThrown
2662
2663/* ------------------------------ */
2664    .balign 64
2665.L_OP_IPUT_BOOLEAN: /* 0x5c */
2666/* File: armv5te/OP_IPUT_BOOLEAN.S */
2667@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" }
2668/* File: armv5te/OP_IPUT.S */
2669    /*
2670     * General 32-bit instance field put.
2671     *
2672     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2673     */
2674    /* op vA, vB, field@CCCC */
2675    mov     r0, rINST, lsr #12          @ r0<- B
2676    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2677    FETCH(r1, 1)                        @ r1<- field ref CCCC
2678    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2679    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2680    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2681    cmp     r0, #0                      @ is resolved entry null?
2682    bne     .LOP_IPUT_BOOLEAN_finish          @ no, already resolved
26838:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2684    EXPORT_PC()                         @ resolve() could throw
2685    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2686    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2687    cmp     r0, #0                      @ success?
2688    bne     .LOP_IPUT_BOOLEAN_finish          @ yes, finish up
2689    b       common_exceptionThrown
2690
2691
2692/* ------------------------------ */
2693    .balign 64
2694.L_OP_IPUT_BYTE: /* 0x5d */
2695/* File: armv5te/OP_IPUT_BYTE.S */
2696@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" }
2697/* File: armv5te/OP_IPUT.S */
2698    /*
2699     * General 32-bit instance field put.
2700     *
2701     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2702     */
2703    /* op vA, vB, field@CCCC */
2704    mov     r0, rINST, lsr #12          @ r0<- B
2705    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2706    FETCH(r1, 1)                        @ r1<- field ref CCCC
2707    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2708    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2709    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2710    cmp     r0, #0                      @ is resolved entry null?
2711    bne     .LOP_IPUT_BYTE_finish          @ no, already resolved
27128:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2713    EXPORT_PC()                         @ resolve() could throw
2714    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2715    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2716    cmp     r0, #0                      @ success?
2717    bne     .LOP_IPUT_BYTE_finish          @ yes, finish up
2718    b       common_exceptionThrown
2719
2720
2721/* ------------------------------ */
2722    .balign 64
2723.L_OP_IPUT_CHAR: /* 0x5e */
2724/* File: armv5te/OP_IPUT_CHAR.S */
2725@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" }
2726/* File: armv5te/OP_IPUT.S */
2727    /*
2728     * General 32-bit instance field put.
2729     *
2730     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2731     */
2732    /* op vA, vB, field@CCCC */
2733    mov     r0, rINST, lsr #12          @ r0<- B
2734    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2735    FETCH(r1, 1)                        @ r1<- field ref CCCC
2736    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2737    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2738    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2739    cmp     r0, #0                      @ is resolved entry null?
2740    bne     .LOP_IPUT_CHAR_finish          @ no, already resolved
27418:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2742    EXPORT_PC()                         @ resolve() could throw
2743    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2744    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2745    cmp     r0, #0                      @ success?
2746    bne     .LOP_IPUT_CHAR_finish          @ yes, finish up
2747    b       common_exceptionThrown
2748
2749
2750/* ------------------------------ */
2751    .balign 64
2752.L_OP_IPUT_SHORT: /* 0x5f */
2753/* File: armv5te/OP_IPUT_SHORT.S */
2754@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" }
2755/* File: armv5te/OP_IPUT.S */
2756    /*
2757     * General 32-bit instance field put.
2758     *
2759     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2760     */
2761    /* op vA, vB, field@CCCC */
2762    mov     r0, rINST, lsr #12          @ r0<- B
2763    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2764    FETCH(r1, 1)                        @ r1<- field ref CCCC
2765    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2766    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2767    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2768    cmp     r0, #0                      @ is resolved entry null?
2769    bne     .LOP_IPUT_SHORT_finish          @ no, already resolved
27708:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2771    EXPORT_PC()                         @ resolve() could throw
2772    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2773    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2774    cmp     r0, #0                      @ success?
2775    bne     .LOP_IPUT_SHORT_finish          @ yes, finish up
2776    b       common_exceptionThrown
2777
2778
2779/* ------------------------------ */
2780    .balign 64
2781.L_OP_SGET: /* 0x60 */
2782/* File: armv5te/OP_SGET.S */
2783    /*
2784     * General 32-bit SGET handler.
2785     *
2786     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2787     */
2788    /* op vAA, field@BBBB */
2789    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2790    FETCH(r1, 1)                        @ r1<- field ref BBBB
2791    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2792    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2793    cmp     r0, #0                      @ is resolved entry null?
2794    beq     .LOP_SGET_resolve         @ yes, do resolve
2795.LOP_SGET_finish: @ field ptr in r0
2796    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2797    @ no-op                             @ acquiring load
2798    mov     r2, rINST, lsr #8           @ r2<- AA
2799    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2800    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2801    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2802    GOTO_OPCODE(ip)                     @ jump to next instruction
2803
2804/* ------------------------------ */
2805    .balign 64
2806.L_OP_SGET_WIDE: /* 0x61 */
2807/* File: armv5te/OP_SGET_WIDE.S */
2808    /*
2809     * 64-bit SGET handler.
2810     */
2811    /* sget-wide vAA, field@BBBB */
2812    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2813    FETCH(r1, 1)                        @ r1<- field ref BBBB
2814    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2815    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2816    cmp     r0, #0                      @ is resolved entry null?
2817    beq     .LOP_SGET_WIDE_resolve         @ yes, do resolve
2818.LOP_SGET_WIDE_finish:
2819    mov     r9, rINST, lsr #8           @ r9<- AA
2820    .if 0
2821    add     r0, r0, #offStaticField_value @ r0<- pointer to data
2822    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
2823    .else
2824    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
2825    .endif
2826    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2827    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2828    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
2829    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2830    GOTO_OPCODE(ip)                     @ jump to next instruction
2831
2832/* ------------------------------ */
2833    .balign 64
2834.L_OP_SGET_OBJECT: /* 0x62 */
2835/* File: armv5te/OP_SGET_OBJECT.S */
2836/* File: armv5te/OP_SGET.S */
2837    /*
2838     * General 32-bit SGET handler.
2839     *
2840     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2841     */
2842    /* op vAA, field@BBBB */
2843    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2844    FETCH(r1, 1)                        @ r1<- field ref BBBB
2845    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2846    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2847    cmp     r0, #0                      @ is resolved entry null?
2848    beq     .LOP_SGET_OBJECT_resolve         @ yes, do resolve
2849.LOP_SGET_OBJECT_finish: @ field ptr in r0
2850    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2851    @ no-op                             @ acquiring load
2852    mov     r2, rINST, lsr #8           @ r2<- AA
2853    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2854    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2855    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2856    GOTO_OPCODE(ip)                     @ jump to next instruction
2857
2858
2859/* ------------------------------ */
2860    .balign 64
2861.L_OP_SGET_BOOLEAN: /* 0x63 */
2862/* File: armv5te/OP_SGET_BOOLEAN.S */
2863/* File: armv5te/OP_SGET.S */
2864    /*
2865     * General 32-bit SGET handler.
2866     *
2867     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2868     */
2869    /* op vAA, field@BBBB */
2870    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2871    FETCH(r1, 1)                        @ r1<- field ref BBBB
2872    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2873    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2874    cmp     r0, #0                      @ is resolved entry null?
2875    beq     .LOP_SGET_BOOLEAN_resolve         @ yes, do resolve
2876.LOP_SGET_BOOLEAN_finish: @ field ptr in r0
2877    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2878    @ no-op                             @ acquiring load
2879    mov     r2, rINST, lsr #8           @ r2<- AA
2880    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2881    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2882    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2883    GOTO_OPCODE(ip)                     @ jump to next instruction
2884
2885
2886/* ------------------------------ */
2887    .balign 64
2888.L_OP_SGET_BYTE: /* 0x64 */
2889/* File: armv5te/OP_SGET_BYTE.S */
2890/* File: armv5te/OP_SGET.S */
2891    /*
2892     * General 32-bit SGET handler.
2893     *
2894     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2895     */
2896    /* op vAA, field@BBBB */
2897    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2898    FETCH(r1, 1)                        @ r1<- field ref BBBB
2899    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2900    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2901    cmp     r0, #0                      @ is resolved entry null?
2902    beq     .LOP_SGET_BYTE_resolve         @ yes, do resolve
2903.LOP_SGET_BYTE_finish: @ field ptr in r0
2904    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2905    @ no-op                             @ acquiring load
2906    mov     r2, rINST, lsr #8           @ r2<- AA
2907    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2908    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2909    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2910    GOTO_OPCODE(ip)                     @ jump to next instruction
2911
2912
2913/* ------------------------------ */
2914    .balign 64
2915.L_OP_SGET_CHAR: /* 0x65 */
2916/* File: armv5te/OP_SGET_CHAR.S */
2917/* File: armv5te/OP_SGET.S */
2918    /*
2919     * General 32-bit SGET handler.
2920     *
2921     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2922     */
2923    /* op vAA, field@BBBB */
2924    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2925    FETCH(r1, 1)                        @ r1<- field ref BBBB
2926    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2927    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2928    cmp     r0, #0                      @ is resolved entry null?
2929    beq     .LOP_SGET_CHAR_resolve         @ yes, do resolve
2930.LOP_SGET_CHAR_finish: @ field ptr in r0
2931    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2932    @ no-op                             @ acquiring load
2933    mov     r2, rINST, lsr #8           @ r2<- AA
2934    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2935    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2936    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2937    GOTO_OPCODE(ip)                     @ jump to next instruction
2938
2939
2940/* ------------------------------ */
2941    .balign 64
2942.L_OP_SGET_SHORT: /* 0x66 */
2943/* File: armv5te/OP_SGET_SHORT.S */
2944/* File: armv5te/OP_SGET.S */
2945    /*
2946     * General 32-bit SGET handler.
2947     *
2948     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2949     */
2950    /* op vAA, field@BBBB */
2951    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2952    FETCH(r1, 1)                        @ r1<- field ref BBBB
2953    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2954    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2955    cmp     r0, #0                      @ is resolved entry null?
2956    beq     .LOP_SGET_SHORT_resolve         @ yes, do resolve
2957.LOP_SGET_SHORT_finish: @ field ptr in r0
2958    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2959    @ no-op                             @ acquiring load
2960    mov     r2, rINST, lsr #8           @ r2<- AA
2961    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2962    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2963    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2964    GOTO_OPCODE(ip)                     @ jump to next instruction
2965
2966
2967/* ------------------------------ */
2968    .balign 64
2969.L_OP_SPUT: /* 0x67 */
2970/* File: armv5te/OP_SPUT.S */
2971    /*
2972     * General 32-bit SPUT handler.
2973     *
2974     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2975     */
2976    /* op vAA, field@BBBB */
2977    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2978    FETCH(r1, 1)                        @ r1<- field ref BBBB
2979    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2980    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2981    cmp     r0, #0                      @ is resolved entry null?
2982    beq     .LOP_SPUT_resolve         @ yes, do resolve
2983.LOP_SPUT_finish:   @ field ptr in r0
2984    mov     r2, rINST, lsr #8           @ r2<- AA
2985    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2986    GET_VREG(r1, r2)                    @ r1<- fp[AA]
2987    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2988    @ no-op                             @ releasing store
2989    str     r1, [r0, #offStaticField_value] @ field<- vAA
2990    GOTO_OPCODE(ip)                     @ jump to next instruction
2991
2992/* ------------------------------ */
2993    .balign 64
2994.L_OP_SPUT_WIDE: /* 0x68 */
2995/* File: armv5te/OP_SPUT_WIDE.S */
2996    /*
2997     * 64-bit SPUT handler.
2998     */
2999    /* sput-wide vAA, field@BBBB */
3000    ldr     r0, [rGLUE, #offGlue_methodClassDex]  @ r0<- DvmDex
3001    FETCH(r1, 1)                        @ r1<- field ref BBBB
3002    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
3003    mov     r9, rINST, lsr #8           @ r9<- AA
3004    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
3005    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
3006    cmp     r2, #0                      @ is resolved entry null?
3007    beq     .LOP_SPUT_WIDE_resolve         @ yes, do resolve
3008.LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9
3009    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3010    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
3011    GET_INST_OPCODE(r10)                @ extract opcode from rINST
3012    .if 0
3013    add     r2, r2, #offStaticField_value @ r2<- pointer to data
3014    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
3015    .else
3016    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
3017    .endif
3018    GOTO_OPCODE(r10)                    @ jump to next instruction
3019
3020/* ------------------------------ */
3021    .balign 64
3022.L_OP_SPUT_OBJECT: /* 0x69 */
3023/* File: armv5te/OP_SPUT_OBJECT.S */
3024    /*
3025     * 32-bit SPUT handler for objects
3026     *
3027     * for: sput-object, sput-object-volatile
3028     */
3029    /* op vAA, field@BBBB */
3030    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3031    FETCH(r1, 1)                        @ r1<- field ref BBBB
3032    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3033    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3034    cmp     r0, #0                      @ is resolved entry null?
3035    bne     .LOP_SPUT_OBJECT_finish          @ no, continue
3036    ldr     r9, [rGLUE, #offGlue_method]    @ r9<- current method
3037    EXPORT_PC()                         @ resolve() could throw, so export now
3038    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
3039    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
3040    cmp     r0, #0                      @ success?
3041    bne     .LOP_SPUT_OBJECT_finish          @ yes, finish
3042    b       common_exceptionThrown      @ no, handle exception
3043
3044
3045/* ------------------------------ */
3046    .balign 64
3047.L_OP_SPUT_BOOLEAN: /* 0x6a */
3048/* File: armv5te/OP_SPUT_BOOLEAN.S */
3049/* File: armv5te/OP_SPUT.S */
3050    /*
3051     * General 32-bit SPUT handler.
3052     *
3053     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3054     */
3055    /* op vAA, field@BBBB */
3056    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3057    FETCH(r1, 1)                        @ r1<- field ref BBBB
3058    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3059    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3060    cmp     r0, #0                      @ is resolved entry null?
3061    beq     .LOP_SPUT_BOOLEAN_resolve         @ yes, do resolve
3062.LOP_SPUT_BOOLEAN_finish:   @ field ptr in r0
3063    mov     r2, rINST, lsr #8           @ r2<- AA
3064    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3065    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3066    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3067    @ no-op                             @ releasing store
3068    str     r1, [r0, #offStaticField_value] @ field<- vAA
3069    GOTO_OPCODE(ip)                     @ jump to next instruction
3070
3071
3072/* ------------------------------ */
3073    .balign 64
3074.L_OP_SPUT_BYTE: /* 0x6b */
3075/* File: armv5te/OP_SPUT_BYTE.S */
3076/* File: armv5te/OP_SPUT.S */
3077    /*
3078     * General 32-bit SPUT handler.
3079     *
3080     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3081     */
3082    /* op vAA, field@BBBB */
3083    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3084    FETCH(r1, 1)                        @ r1<- field ref BBBB
3085    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3086    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3087    cmp     r0, #0                      @ is resolved entry null?
3088    beq     .LOP_SPUT_BYTE_resolve         @ yes, do resolve
3089.LOP_SPUT_BYTE_finish:   @ field ptr in r0
3090    mov     r2, rINST, lsr #8           @ r2<- AA
3091    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3092    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3093    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3094    @ no-op                             @ releasing store
3095    str     r1, [r0, #offStaticField_value] @ field<- vAA
3096    GOTO_OPCODE(ip)                     @ jump to next instruction
3097
3098
3099/* ------------------------------ */
3100    .balign 64
3101.L_OP_SPUT_CHAR: /* 0x6c */
3102/* File: armv5te/OP_SPUT_CHAR.S */
3103/* File: armv5te/OP_SPUT.S */
3104    /*
3105     * General 32-bit SPUT handler.
3106     *
3107     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3108     */
3109    /* op vAA, field@BBBB */
3110    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3111    FETCH(r1, 1)                        @ r1<- field ref BBBB
3112    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3113    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3114    cmp     r0, #0                      @ is resolved entry null?
3115    beq     .LOP_SPUT_CHAR_resolve         @ yes, do resolve
3116.LOP_SPUT_CHAR_finish:   @ field ptr in r0
3117    mov     r2, rINST, lsr #8           @ r2<- AA
3118    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3119    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3120    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3121    @ no-op                             @ releasing store
3122    str     r1, [r0, #offStaticField_value] @ field<- vAA
3123    GOTO_OPCODE(ip)                     @ jump to next instruction
3124
3125
3126/* ------------------------------ */
3127    .balign 64
3128.L_OP_SPUT_SHORT: /* 0x6d */
3129/* File: armv5te/OP_SPUT_SHORT.S */
3130/* File: armv5te/OP_SPUT.S */
3131    /*
3132     * General 32-bit SPUT handler.
3133     *
3134     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3135     */
3136    /* op vAA, field@BBBB */
3137    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3138    FETCH(r1, 1)                        @ r1<- field ref BBBB
3139    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3140    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3141    cmp     r0, #0                      @ is resolved entry null?
3142    beq     .LOP_SPUT_SHORT_resolve         @ yes, do resolve
3143.LOP_SPUT_SHORT_finish:   @ field ptr in r0
3144    mov     r2, rINST, lsr #8           @ r2<- AA
3145    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3146    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3147    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3148    @ no-op                             @ releasing store
3149    str     r1, [r0, #offStaticField_value] @ field<- vAA
3150    GOTO_OPCODE(ip)                     @ jump to next instruction
3151
3152
3153/* ------------------------------ */
3154    .balign 64
3155.L_OP_INVOKE_VIRTUAL: /* 0x6e */
3156/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3157    /*
3158     * Handle a virtual method call.
3159     *
3160     * for: invoke-virtual, invoke-virtual/range
3161     */
3162    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3163    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3164    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3165    FETCH(r1, 1)                        @ r1<- BBBB
3166    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3167    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3168    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3169    .if     (!0)
3170    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3171    .endif
3172    cmp     r0, #0                      @ already resolved?
3173    EXPORT_PC()                         @ must export for invoke
3174    bne     .LOP_INVOKE_VIRTUAL_continue        @ yes, continue on
3175    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
3176    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3177    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3178    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3179    cmp     r0, #0                      @ got null?
3180    bne     .LOP_INVOKE_VIRTUAL_continue        @ no, continue
3181    b       common_exceptionThrown      @ yes, handle exception
3182
3183/* ------------------------------ */
3184    .balign 64
3185.L_OP_INVOKE_SUPER: /* 0x6f */
3186/* File: armv5te/OP_INVOKE_SUPER.S */
3187    /*
3188     * Handle a "super" method call.
3189     *
3190     * for: invoke-super, invoke-super/range
3191     */
3192    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3193    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3194    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3195    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3196    .if     (!0)
3197    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3198    .endif
3199    FETCH(r1, 1)                        @ r1<- BBBB
3200    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3201    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3202    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3203    cmp     r2, #0                      @ null "this"?
3204    ldr     r9, [rGLUE, #offGlue_method] @ r9<- current method
3205    beq     common_errNullObject        @ null "this", throw exception
3206    cmp     r0, #0                      @ already resolved?
3207    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
3208    EXPORT_PC()                         @ must export for invoke
3209    bne     .LOP_INVOKE_SUPER_continue        @ resolved, continue on
3210    b       .LOP_INVOKE_SUPER_resolve         @ do resolve now
3211
3212/* ------------------------------ */
3213    .balign 64
3214.L_OP_INVOKE_DIRECT: /* 0x70 */
3215/* File: armv5te/OP_INVOKE_DIRECT.S */
3216    /*
3217     * Handle a direct method call.
3218     *
3219     * (We could defer the "is 'this' pointer null" test to the common
3220     * method invocation code, and use a flag to indicate that static
3221     * calls don't count.  If we do this as part of copying the arguments
3222     * out we could avoiding loading the first arg twice.)
3223     *
3224     * for: invoke-direct, invoke-direct/range
3225     */
3226    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3227    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3228    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3229    FETCH(r1, 1)                        @ r1<- BBBB
3230    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3231    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3232    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3233    .if     (!0)
3234    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3235    .endif
3236    cmp     r0, #0                      @ already resolved?
3237    EXPORT_PC()                         @ must export for invoke
3238    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3239    beq     .LOP_INVOKE_DIRECT_resolve         @ not resolved, do it now
3240.LOP_INVOKE_DIRECT_finish:
3241    cmp     r2, #0                      @ null "this" ref?
3242    bne     common_invokeMethodNoRange   @ no, continue on
3243    b       common_errNullObject        @ yes, throw exception
3244
3245/* ------------------------------ */
3246    .balign 64
3247.L_OP_INVOKE_STATIC: /* 0x71 */
3248/* File: armv5te/OP_INVOKE_STATIC.S */
3249    /*
3250     * Handle a static method call.
3251     *
3252     * for: invoke-static, invoke-static/range
3253     */
3254    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3255    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3256    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3257    FETCH(r1, 1)                        @ r1<- BBBB
3258    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3259    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3260    cmp     r0, #0                      @ already resolved?
3261    EXPORT_PC()                         @ must export for invoke
3262    bne     common_invokeMethodNoRange @ yes, continue on
32630:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
3264    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3265    mov     r2, #METHOD_STATIC          @ resolver method type
3266    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3267    cmp     r0, #0                      @ got null?
3268    bne     common_invokeMethodNoRange @ no, continue
3269    b       common_exceptionThrown      @ yes, handle exception
3270
3271/* ------------------------------ */
3272    .balign 64
3273.L_OP_INVOKE_INTERFACE: /* 0x72 */
3274/* File: armv5te/OP_INVOKE_INTERFACE.S */
3275    /*
3276     * Handle an interface method call.
3277     *
3278     * for: invoke-interface, invoke-interface/range
3279     */
3280    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3281    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3282    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3283    FETCH(r1, 1)                        @ r1<- BBBB
3284    .if     (!0)
3285    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3286    .endif
3287    EXPORT_PC()                         @ must export for invoke
3288    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
3289    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- methodClassDex
3290    cmp     r0, #0                      @ null obj?
3291    ldr     r2, [rGLUE, #offGlue_method]  @ r2<- method
3292    beq     common_errNullObject        @ yes, fail
3293    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
3294    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3295    cmp     r0, #0                      @ failed?
3296    beq     common_exceptionThrown      @ yes, handle exception
3297    b       common_invokeMethodNoRange @ jump to common handler
3298
3299/* ------------------------------ */
3300    .balign 64
3301.L_OP_UNUSED_73: /* 0x73 */
3302/* File: armv5te/OP_UNUSED_73.S */
3303/* File: armv5te/unused.S */
3304    bl      common_abort
3305
3306
3307/* ------------------------------ */
3308    .balign 64
3309.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
3310/* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */
3311/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3312    /*
3313     * Handle a virtual method call.
3314     *
3315     * for: invoke-virtual, invoke-virtual/range
3316     */
3317    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3318    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3319    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3320    FETCH(r1, 1)                        @ r1<- BBBB
3321    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3322    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3323    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3324    .if     (!1)
3325    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3326    .endif
3327    cmp     r0, #0                      @ already resolved?
3328    EXPORT_PC()                         @ must export for invoke
3329    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ yes, continue on
3330    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
3331    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3332    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3333    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3334    cmp     r0, #0                      @ got null?
3335    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ no, continue
3336    b       common_exceptionThrown      @ yes, handle exception
3337
3338
3339/* ------------------------------ */
3340    .balign 64
3341.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */
3342/* File: armv5te/OP_INVOKE_SUPER_RANGE.S */
3343/* File: armv5te/OP_INVOKE_SUPER.S */
3344    /*
3345     * Handle a "super" method call.
3346     *
3347     * for: invoke-super, invoke-super/range
3348     */
3349    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3350    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3351    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3352    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3353    .if     (!1)
3354    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3355    .endif
3356    FETCH(r1, 1)                        @ r1<- BBBB
3357    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3358    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3359    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3360    cmp     r2, #0                      @ null "this"?
3361    ldr     r9, [rGLUE, #offGlue_method] @ r9<- current method
3362    beq     common_errNullObject        @ null "this", throw exception
3363    cmp     r0, #0                      @ already resolved?
3364    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
3365    EXPORT_PC()                         @ must export for invoke
3366    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ resolved, continue on
3367    b       .LOP_INVOKE_SUPER_RANGE_resolve         @ do resolve now
3368
3369
3370/* ------------------------------ */
3371    .balign 64
3372.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
3373/* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */
3374/* File: armv5te/OP_INVOKE_DIRECT.S */
3375    /*
3376     * Handle a direct method call.
3377     *
3378     * (We could defer the "is 'this' pointer null" test to the common
3379     * method invocation code, and use a flag to indicate that static
3380     * calls don't count.  If we do this as part of copying the arguments
3381     * out we could avoiding loading the first arg twice.)
3382     *
3383     * for: invoke-direct, invoke-direct/range
3384     */
3385    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3386    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3387    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3388    FETCH(r1, 1)                        @ r1<- BBBB
3389    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3390    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3391    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3392    .if     (!1)
3393    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3394    .endif
3395    cmp     r0, #0                      @ already resolved?
3396    EXPORT_PC()                         @ must export for invoke
3397    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3398    beq     .LOP_INVOKE_DIRECT_RANGE_resolve         @ not resolved, do it now
3399.LOP_INVOKE_DIRECT_RANGE_finish:
3400    cmp     r2, #0                      @ null "this" ref?
3401    bne     common_invokeMethodRange   @ no, continue on
3402    b       common_errNullObject        @ yes, throw exception
3403
3404
3405/* ------------------------------ */
3406    .balign 64
3407.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */
3408/* File: armv5te/OP_INVOKE_STATIC_RANGE.S */
3409/* File: armv5te/OP_INVOKE_STATIC.S */
3410    /*
3411     * Handle a static method call.
3412     *
3413     * for: invoke-static, invoke-static/range
3414     */
3415    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3416    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3417    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3418    FETCH(r1, 1)                        @ r1<- BBBB
3419    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3420    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3421    cmp     r0, #0                      @ already resolved?
3422    EXPORT_PC()                         @ must export for invoke
3423    bne     common_invokeMethodRange @ yes, continue on
34240:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
3425    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3426    mov     r2, #METHOD_STATIC          @ resolver method type
3427    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3428    cmp     r0, #0                      @ got null?
3429    bne     common_invokeMethodRange @ no, continue
3430    b       common_exceptionThrown      @ yes, handle exception
3431
3432
3433/* ------------------------------ */
3434    .balign 64
3435.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
3436/* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */
3437/* File: armv5te/OP_INVOKE_INTERFACE.S */
3438    /*
3439     * Handle an interface method call.
3440     *
3441     * for: invoke-interface, invoke-interface/range
3442     */
3443    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3444    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3445    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3446    FETCH(r1, 1)                        @ r1<- BBBB
3447    .if     (!1)
3448    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3449    .endif
3450    EXPORT_PC()                         @ must export for invoke
3451    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
3452    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- methodClassDex
3453    cmp     r0, #0                      @ null obj?
3454    ldr     r2, [rGLUE, #offGlue_method]  @ r2<- method
3455    beq     common_errNullObject        @ yes, fail
3456    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
3457    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3458    cmp     r0, #0                      @ failed?
3459    beq     common_exceptionThrown      @ yes, handle exception
3460    b       common_invokeMethodRange @ jump to common handler
3461
3462
3463/* ------------------------------ */
3464    .balign 64
3465.L_OP_UNUSED_79: /* 0x79 */
3466/* File: armv5te/OP_UNUSED_79.S */
3467/* File: armv5te/unused.S */
3468    bl      common_abort
3469
3470
3471/* ------------------------------ */
3472    .balign 64
3473.L_OP_UNUSED_7A: /* 0x7a */
3474/* File: armv5te/OP_UNUSED_7A.S */
3475/* File: armv5te/unused.S */
3476    bl      common_abort
3477
3478
3479/* ------------------------------ */
3480    .balign 64
3481.L_OP_NEG_INT: /* 0x7b */
3482/* File: armv5te/OP_NEG_INT.S */
3483/* File: armv5te/unop.S */
3484    /*
3485     * Generic 32-bit unary operation.  Provide an "instr" line that
3486     * specifies an instruction that performs "result = op r0".
3487     * This could be an ARM instruction or a function call.
3488     *
3489     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3490     *      int-to-byte, int-to-char, int-to-short
3491     */
3492    /* unop vA, vB */
3493    mov     r3, rINST, lsr #12          @ r3<- B
3494    mov     r9, rINST, lsr #8           @ r9<- A+
3495    GET_VREG(r0, r3)                    @ r0<- vB
3496    and     r9, r9, #15
3497                               @ optional op; may set condition codes
3498    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3499    rsb     r0, r0, #0                              @ r0<- op, r0-r3 changed
3500    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3501    SET_VREG(r0, r9)                    @ vAA<- r0
3502    GOTO_OPCODE(ip)                     @ jump to next instruction
3503    /* 9-10 instructions */
3504
3505
3506/* ------------------------------ */
3507    .balign 64
3508.L_OP_NOT_INT: /* 0x7c */
3509/* File: armv5te/OP_NOT_INT.S */
3510/* File: armv5te/unop.S */
3511    /*
3512     * Generic 32-bit unary operation.  Provide an "instr" line that
3513     * specifies an instruction that performs "result = op r0".
3514     * This could be an ARM instruction or a function call.
3515     *
3516     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3517     *      int-to-byte, int-to-char, int-to-short
3518     */
3519    /* unop vA, vB */
3520    mov     r3, rINST, lsr #12          @ r3<- B
3521    mov     r9, rINST, lsr #8           @ r9<- A+
3522    GET_VREG(r0, r3)                    @ r0<- vB
3523    and     r9, r9, #15
3524                               @ optional op; may set condition codes
3525    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3526    mvn     r0, r0                              @ r0<- op, r0-r3 changed
3527    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3528    SET_VREG(r0, r9)                    @ vAA<- r0
3529    GOTO_OPCODE(ip)                     @ jump to next instruction
3530    /* 9-10 instructions */
3531
3532
3533/* ------------------------------ */
3534    .balign 64
3535.L_OP_NEG_LONG: /* 0x7d */
3536/* File: armv5te/OP_NEG_LONG.S */
3537/* File: armv5te/unopWide.S */
3538    /*
3539     * Generic 64-bit unary operation.  Provide an "instr" line that
3540     * specifies an instruction that performs "result = op r0/r1".
3541     * This could be an ARM instruction or a function call.
3542     *
3543     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3544     */
3545    /* unop vA, vB */
3546    mov     r9, rINST, lsr #8           @ r9<- A+
3547    mov     r3, rINST, lsr #12          @ r3<- B
3548    and     r9, r9, #15
3549    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3550    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3551    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3552    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3553    rsbs    r0, r0, #0                           @ optional op; may set condition codes
3554    rsc     r1, r1, #0                              @ r0/r1<- op, r2-r3 changed
3555    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3556    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3557    GOTO_OPCODE(ip)                     @ jump to next instruction
3558    /* 12-13 instructions */
3559
3560
3561/* ------------------------------ */
3562    .balign 64
3563.L_OP_NOT_LONG: /* 0x7e */
3564/* File: armv5te/OP_NOT_LONG.S */
3565/* File: armv5te/unopWide.S */
3566    /*
3567     * Generic 64-bit unary operation.  Provide an "instr" line that
3568     * specifies an instruction that performs "result = op r0/r1".
3569     * This could be an ARM instruction or a function call.
3570     *
3571     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3572     */
3573    /* unop vA, vB */
3574    mov     r9, rINST, lsr #8           @ r9<- A+
3575    mov     r3, rINST, lsr #12          @ r3<- B
3576    and     r9, r9, #15
3577    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3578    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3579    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3580    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3581    mvn     r0, r0                           @ optional op; may set condition codes
3582    mvn     r1, r1                              @ r0/r1<- op, r2-r3 changed
3583    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3584    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3585    GOTO_OPCODE(ip)                     @ jump to next instruction
3586    /* 12-13 instructions */
3587
3588
3589/* ------------------------------ */
3590    .balign 64
3591.L_OP_NEG_FLOAT: /* 0x7f */
3592/* File: armv5te/OP_NEG_FLOAT.S */
3593/* File: armv5te/unop.S */
3594    /*
3595     * Generic 32-bit unary operation.  Provide an "instr" line that
3596     * specifies an instruction that performs "result = op r0".
3597     * This could be an ARM instruction or a function call.
3598     *
3599     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3600     *      int-to-byte, int-to-char, int-to-short
3601     */
3602    /* unop vA, vB */
3603    mov     r3, rINST, lsr #12          @ r3<- B
3604    mov     r9, rINST, lsr #8           @ r9<- A+
3605    GET_VREG(r0, r3)                    @ r0<- vB
3606    and     r9, r9, #15
3607                               @ optional op; may set condition codes
3608    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3609    add     r0, r0, #0x80000000                              @ r0<- op, r0-r3 changed
3610    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3611    SET_VREG(r0, r9)                    @ vAA<- r0
3612    GOTO_OPCODE(ip)                     @ jump to next instruction
3613    /* 9-10 instructions */
3614
3615
3616/* ------------------------------ */
3617    .balign 64
3618.L_OP_NEG_DOUBLE: /* 0x80 */
3619/* File: armv5te/OP_NEG_DOUBLE.S */
3620/* File: armv5te/unopWide.S */
3621    /*
3622     * Generic 64-bit unary operation.  Provide an "instr" line that
3623     * specifies an instruction that performs "result = op r0/r1".
3624     * This could be an ARM instruction or a function call.
3625     *
3626     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3627     */
3628    /* unop vA, vB */
3629    mov     r9, rINST, lsr #8           @ r9<- A+
3630    mov     r3, rINST, lsr #12          @ r3<- B
3631    and     r9, r9, #15
3632    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3633    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3634    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3635    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3636                               @ optional op; may set condition codes
3637    add     r1, r1, #0x80000000                              @ r0/r1<- op, r2-r3 changed
3638    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3639    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3640    GOTO_OPCODE(ip)                     @ jump to next instruction
3641    /* 12-13 instructions */
3642
3643
3644/* ------------------------------ */
3645    .balign 64
3646.L_OP_INT_TO_LONG: /* 0x81 */
3647/* File: armv5te/OP_INT_TO_LONG.S */
3648/* File: armv5te/unopWider.S */
3649    /*
3650     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3651     * that specifies an instruction that performs "result = op r0", where
3652     * "result" is a 64-bit quantity in r0/r1.
3653     *
3654     * For: int-to-long, int-to-double, float-to-long, float-to-double
3655     */
3656    /* unop vA, vB */
3657    mov     r9, rINST, lsr #8           @ r9<- A+
3658    mov     r3, rINST, lsr #12          @ r3<- B
3659    and     r9, r9, #15
3660    GET_VREG(r0, r3)                    @ r0<- vB
3661    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3662                               @ optional op; may set condition codes
3663    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3664    mov     r1, r0, asr #31                              @ r0<- op, r0-r3 changed
3665    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3666    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3667    GOTO_OPCODE(ip)                     @ jump to next instruction
3668    /* 10-11 instructions */
3669
3670
3671/* ------------------------------ */
3672    .balign 64
3673.L_OP_INT_TO_FLOAT: /* 0x82 */
3674/* File: armv5te/OP_INT_TO_FLOAT.S */
3675/* File: armv5te/unop.S */
3676    /*
3677     * Generic 32-bit unary operation.  Provide an "instr" line that
3678     * specifies an instruction that performs "result = op r0".
3679     * This could be an ARM instruction or a function call.
3680     *
3681     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3682     *      int-to-byte, int-to-char, int-to-short
3683     */
3684    /* unop vA, vB */
3685    mov     r3, rINST, lsr #12          @ r3<- B
3686    mov     r9, rINST, lsr #8           @ r9<- A+
3687    GET_VREG(r0, r3)                    @ r0<- vB
3688    and     r9, r9, #15
3689                               @ optional op; may set condition codes
3690    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3691    bl      __aeabi_i2f                              @ r0<- op, r0-r3 changed
3692    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3693    SET_VREG(r0, r9)                    @ vAA<- r0
3694    GOTO_OPCODE(ip)                     @ jump to next instruction
3695    /* 9-10 instructions */
3696
3697
3698/* ------------------------------ */
3699    .balign 64
3700.L_OP_INT_TO_DOUBLE: /* 0x83 */
3701/* File: armv5te/OP_INT_TO_DOUBLE.S */
3702/* File: armv5te/unopWider.S */
3703    /*
3704     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3705     * that specifies an instruction that performs "result = op r0", where
3706     * "result" is a 64-bit quantity in r0/r1.
3707     *
3708     * For: int-to-long, int-to-double, float-to-long, float-to-double
3709     */
3710    /* unop vA, vB */
3711    mov     r9, rINST, lsr #8           @ r9<- A+
3712    mov     r3, rINST, lsr #12          @ r3<- B
3713    and     r9, r9, #15
3714    GET_VREG(r0, r3)                    @ r0<- vB
3715    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3716                               @ optional op; may set condition codes
3717    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3718    bl      __aeabi_i2d                              @ r0<- op, r0-r3 changed
3719    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3720    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3721    GOTO_OPCODE(ip)                     @ jump to next instruction
3722    /* 10-11 instructions */
3723
3724
3725/* ------------------------------ */
3726    .balign 64
3727.L_OP_LONG_TO_INT: /* 0x84 */
3728/* File: armv5te/OP_LONG_TO_INT.S */
3729/* we ignore the high word, making this equivalent to a 32-bit reg move */
3730/* File: armv5te/OP_MOVE.S */
3731    /* for move, move-object, long-to-int */
3732    /* op vA, vB */
3733    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
3734    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
3735    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3736    GET_VREG(r2, r1)                    @ r2<- fp[B]
3737    and     r0, r0, #15
3738    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
3739    SET_VREG(r2, r0)                    @ fp[A]<- r2
3740    GOTO_OPCODE(ip)                     @ execute next instruction
3741
3742
3743/* ------------------------------ */
3744    .balign 64
3745.L_OP_LONG_TO_FLOAT: /* 0x85 */
3746/* File: armv5te/OP_LONG_TO_FLOAT.S */
3747/* File: armv5te/unopNarrower.S */
3748    /*
3749     * Generic 64bit-to-32bit unary operation.  Provide an "instr" line
3750     * that specifies an instruction that performs "result = op r0/r1", where
3751     * "result" is a 32-bit quantity in r0.
3752     *
3753     * For: long-to-float, double-to-int, double-to-float
3754     *
3755     * (This would work for long-to-int, but that instruction is actually
3756     * an exact match for OP_MOVE.)
3757     */
3758    /* unop vA, vB */
3759    mov     r3, rINST, lsr #12          @ r3<- B
3760    mov     r9, rINST, lsr #8           @ r9<- A+
3761    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3762    and     r9, r9, #15
3763    ldmia   r3, {r0-r1}                 @ r0/r1<- vB/vB+1
3764    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3765                               @ optional op; may set condition codes
3766    bl      __aeabi_l2f                              @ r0<- op, r0-r3 changed
3767    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3768    SET_VREG(r0, r9)                    @ vA<- r0
3769    GOTO_OPCODE(ip)                     @ jump to next instruction
3770    /* 10-11 instructions */
3771
3772
3773/* ------------------------------ */
3774    .balign 64
3775.L_OP_LONG_TO_DOUBLE: /* 0x86 */
3776/* File: armv5te/OP_LONG_TO_DOUBLE.S */
3777/* File: armv5te/unopWide.S */
3778    /*
3779     * Generic 64-bit unary operation.  Provide an "instr" line that
3780     * specifies an instruction that performs "result = op r0/r1".
3781     * This could be an ARM instruction or a function call.
3782     *
3783     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3784     */
3785    /* unop vA, vB */
3786    mov     r9, rINST, lsr #8           @ r9<- A+
3787    mov     r3, rINST, lsr #12          @ r3<- B
3788    and     r9, r9, #15
3789    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3790    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3791    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3792    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3793                               @ optional op; may set condition codes
3794    bl      __aeabi_l2d                              @ r0/r1<- op, r2-r3 changed
3795    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3796    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3797    GOTO_OPCODE(ip)                     @ jump to next instruction
3798    /* 12-13 instructions */
3799
3800
3801/* ------------------------------ */
3802    .balign 64
3803.L_OP_FLOAT_TO_INT: /* 0x87 */
3804/* File: armv5te/OP_FLOAT_TO_INT.S */
3805/* EABI appears to have Java-style conversions of +inf/-inf/NaN */
3806/* File: armv5te/unop.S */
3807    /*
3808     * Generic 32-bit unary operation.  Provide an "instr" line that
3809     * specifies an instruction that performs "result = op r0".
3810     * This could be an ARM instruction or a function call.
3811     *
3812     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3813     *      int-to-byte, int-to-char, int-to-short
3814     */
3815    /* unop vA, vB */
3816    mov     r3, rINST, lsr #12          @ r3<- B
3817    mov     r9, rINST, lsr #8           @ r9<- A+
3818    GET_VREG(r0, r3)                    @ r0<- vB
3819    and     r9, r9, #15
3820                               @ optional op; may set condition codes
3821    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3822    bl      __aeabi_f2iz                              @ r0<- op, r0-r3 changed
3823    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3824    SET_VREG(r0, r9)                    @ vAA<- r0
3825    GOTO_OPCODE(ip)                     @ jump to next instruction
3826    /* 9-10 instructions */
3827
3828
3829#if 0
3830@include "armv5te/unop.S" {"instr":"bl      f2i_doconv"}
3831@break
3832/*
3833 * Convert the float in r0 to an int in r0.
3834 *
3835 * We have to clip values to int min/max per the specification.  The
3836 * expected common case is a "reasonable" value that converts directly
3837 * to modest integer.  The EABI convert function isn't doing this for us.
3838 */
3839f2i_doconv:
3840    stmfd   sp!, {r4, lr}
3841    mov     r1, #0x4f000000             @ (float)maxint
3842    mov     r4, r0
3843    bl      __aeabi_fcmpge              @ is arg >= maxint?
3844    cmp     r0, #0                      @ nonzero == yes
3845    mvnne   r0, #0x80000000             @ return maxint (7fffffff)
3846    ldmnefd sp!, {r4, pc}
3847
3848    mov     r0, r4                      @ recover arg
3849    mov     r1, #0xcf000000             @ (float)minint
3850    bl      __aeabi_fcmple              @ is arg <= minint?
3851    cmp     r0, #0                      @ nonzero == yes
3852    movne   r0, #0x80000000             @ return minint (80000000)
3853    ldmnefd sp!, {r4, pc}
3854
3855    mov     r0, r4                      @ recover arg
3856    mov     r1, r4
3857    bl      __aeabi_fcmpeq              @ is arg == self?
3858    cmp     r0, #0                      @ zero == no
3859    ldmeqfd sp!, {r4, pc}               @ return zero for NaN
3860
3861    mov     r0, r4                      @ recover arg
3862    bl      __aeabi_f2iz                @ convert float to int
3863    ldmfd   sp!, {r4, pc}
3864#endif
3865
3866/* ------------------------------ */
3867    .balign 64
3868.L_OP_FLOAT_TO_LONG: /* 0x88 */
3869/* File: armv5te/OP_FLOAT_TO_LONG.S */
3870@include "armv5te/unopWider.S" {"instr":"bl      __aeabi_f2lz"}
3871/* File: armv5te/unopWider.S */
3872    /*
3873     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3874     * that specifies an instruction that performs "result = op r0", where
3875     * "result" is a 64-bit quantity in r0/r1.
3876     *
3877     * For: int-to-long, int-to-double, float-to-long, float-to-double
3878     */
3879    /* unop vA, vB */
3880    mov     r9, rINST, lsr #8           @ r9<- A+
3881    mov     r3, rINST, lsr #12          @ r3<- B
3882    and     r9, r9, #15
3883    GET_VREG(r0, r3)                    @ r0<- vB
3884    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3885                               @ optional op; may set condition codes
3886    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3887    bl      f2l_doconv                              @ r0<- op, r0-r3 changed
3888    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3889    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3890    GOTO_OPCODE(ip)                     @ jump to next instruction
3891    /* 10-11 instructions */
3892
3893
3894
3895/* ------------------------------ */
3896    .balign 64
3897.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */
3898/* File: armv5te/OP_FLOAT_TO_DOUBLE.S */
3899/* File: armv5te/unopWider.S */
3900    /*
3901     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3902     * that specifies an instruction that performs "result = op r0", where
3903     * "result" is a 64-bit quantity in r0/r1.
3904     *
3905     * For: int-to-long, int-to-double, float-to-long, float-to-double
3906     */
3907    /* unop vA, vB */
3908    mov     r9, rINST, lsr #8           @ r9<- A+
3909    mov     r3, rINST, lsr #12          @ r3<- B
3910    and     r9, r9, #15
3911    GET_VREG(r0, r3)                    @ r0<- vB
3912    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3913                               @ optional op; may set condition codes
3914    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3915    bl      __aeabi_f2d                              @ r0<- op, r0-r3 changed
3916    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3917    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3918    GOTO_OPCODE(ip)                     @ jump to next instruction
3919    /* 10-11 instructions */
3920
3921
3922/* ------------------------------ */
3923    .balign 64
3924.L_OP_DOUBLE_TO_INT: /* 0x8a */
3925/* File: armv5te/OP_DOUBLE_TO_INT.S */
3926/* EABI appears to have Java-style conversions of +inf/-inf/NaN */
3927/* File: armv5te/unopNarrower.S */
3928    /*
3929     * Generic 64bit-to-32bit unary operation.  Provide an "instr" line
3930     * that specifies an instruction that performs "result = op r0/r1", where
3931     * "result" is a 32-bit quantity in r0.
3932     *
3933     * For: long-to-float, double-to-int, double-to-float
3934     *
3935     * (This would work for long-to-int, but that instruction is actually
3936     * an exact match for OP_MOVE.)
3937     */
3938    /* unop vA, vB */
3939    mov     r3, rINST, lsr #12          @ r3<- B
3940    mov     r9, rINST, lsr #8           @ r9<- A+
3941    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3942    and     r9, r9, #15
3943    ldmia   r3, {r0-r1}                 @ r0/r1<- vB/vB+1
3944    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3945                               @ optional op; may set condition codes
3946    bl      __aeabi_d2iz                              @ r0<- op, r0-r3 changed
3947    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3948    SET_VREG(r0, r9)                    @ vA<- r0
3949    GOTO_OPCODE(ip)                     @ jump to next instruction
3950    /* 10-11 instructions */
3951
3952
3953#if 0
3954@include "armv5te/unopNarrower.S" {"instr":"bl      d2i_doconv"}
3955@break
3956/*
3957 * Convert the double in r0/r1 to an int in r0.
3958 *
3959 * We have to clip values to int min/max per the specification.  The
3960 * expected common case is a "reasonable" value that converts directly
3961 * to modest integer.  The EABI convert function isn't doing this for us.
3962 */
3963d2i_doconv:
3964    stmfd   sp!, {r4, r5, lr}           @ save regs
3965    mov     r2, #0x80000000             @ maxint, as a double (low word)
3966    mov     r2, r2, asr #9              @  0xffc00000
3967    sub     sp, sp, #4                  @ align for EABI
3968    mvn     r3, #0xbe000000             @ maxint, as a double (high word)
3969    sub     r3, r3, #0x00200000         @  0x41dfffff
3970    mov     r4, r0                      @ save a copy of r0
3971    mov     r5, r1                      @  and r1
3972    bl      __aeabi_dcmpge              @ is arg >= maxint?
3973    cmp     r0, #0                      @ nonzero == yes
3974    mvnne   r0, #0x80000000             @ return maxint (0x7fffffff)
3975    bne     1f
3976
3977    mov     r0, r4                      @ recover arg
3978    mov     r1, r5
3979    mov     r3, #0xc1000000             @ minint, as a double (high word)
3980    add     r3, r3, #0x00e00000         @  0xc1e00000
3981    mov     r2, #0                      @ minint, as a double (low word)
3982    bl      __aeabi_dcmple              @ is arg <= minint?
3983    cmp     r0, #0                      @ nonzero == yes
3984    movne   r0, #0x80000000             @ return minint (80000000)
3985    bne     1f
3986
3987    mov     r0, r4                      @ recover arg
3988    mov     r1, r5
3989    mov     r2, r4                      @ compare against self
3990    mov     r3, r5
3991    bl      __aeabi_dcmpeq              @ is arg == self?
3992    cmp     r0, #0                      @ zero == no
3993    beq     1f                          @ return zero for NaN
3994
3995    mov     r0, r4                      @ recover arg
3996    mov     r1, r5
3997    bl      __aeabi_d2iz                @ convert double to int
3998
39991:
4000    add     sp, sp, #4
4001    ldmfd   sp!, {r4, r5, pc}
4002#endif
4003
4004/* ------------------------------ */
4005    .balign 64
4006.L_OP_DOUBLE_TO_LONG: /* 0x8b */
4007/* File: armv5te/OP_DOUBLE_TO_LONG.S */
4008@include "armv5te/unopWide.S" {"instr":"bl      __aeabi_d2lz"}
4009/* File: armv5te/unopWide.S */
4010    /*
4011     * Generic 64-bit unary operation.  Provide an "instr" line that
4012     * specifies an instruction that performs "result = op r0/r1".
4013     * This could be an ARM instruction or a function call.
4014     *
4015     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
4016     */
4017    /* unop vA, vB */
4018    mov     r9, rINST, lsr #8           @ r9<- A+
4019    mov     r3, rINST, lsr #12          @ r3<- B
4020    and     r9, r9, #15
4021    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
4022    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
4023    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
4024    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
4025                               @ optional op; may set condition codes
4026    bl      d2l_doconv                              @ r0/r1<- op, r2-r3 changed
4027    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4028    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
4029    GOTO_OPCODE(ip)                     @ jump to next instruction
4030    /* 12-13 instructions */
4031
4032
4033
4034/* ------------------------------ */
4035    .balign 64
4036.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */
4037/* File: armv5te/OP_DOUBLE_TO_FLOAT.S */
4038/* File: armv5te/unopNarrower.S */
4039    /*
4040     * Generic 64bit-to-32bit unary operation.  Provide an "instr" line
4041     * that specifies an instruction that performs "result = op r0/r1", where
4042     * "result" is a 32-bit quantity in r0.
4043     *
4044     * For: long-to-float, double-to-int, double-to-float
4045     *
4046     * (This would work for long-to-int, but that instruction is actually
4047     * an exact match for OP_MOVE.)
4048     */
4049    /* unop vA, vB */
4050    mov     r3, rINST, lsr #12          @ r3<- B
4051    mov     r9, rINST, lsr #8           @ r9<- A+
4052    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
4053    and     r9, r9, #15
4054    ldmia   r3, {r0-r1}                 @ r0/r1<- vB/vB+1
4055    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
4056                               @ optional op; may set condition codes
4057    bl      __aeabi_d2f                              @ r0<- op, r0-r3 changed
4058    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4059    SET_VREG(r0, r9)                    @ vA<- r0
4060    GOTO_OPCODE(ip)                     @ jump to next instruction
4061    /* 10-11 instructions */
4062
4063
4064/* ------------------------------ */
4065    .balign 64
4066.L_OP_INT_TO_BYTE: /* 0x8d */
4067/* File: armv5te/OP_INT_TO_BYTE.S */
4068/* File: armv5te/unop.S */
4069    /*
4070     * Generic 32-bit unary operation.  Provide an "instr" line that
4071     * specifies an instruction that performs "result = op r0".
4072     * This could be an ARM instruction or a function call.
4073     *
4074     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
4075     *      int-to-byte, int-to-char, int-to-short
4076     */
4077    /* unop vA, vB */
4078    mov     r3, rINST, lsr #12          @ r3<- B
4079    mov     r9, rINST, lsr #8           @ r9<- A+
4080    GET_VREG(r0, r3)                    @ r0<- vB
4081    and     r9, r9, #15
4082    mov     r0, r0, asl #24                           @ optional op; may set condition codes
4083    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
4084    mov     r0, r0, asr #24                              @ r0<- op, r0-r3 changed
4085    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4086    SET_VREG(r0, r9)                    @ vAA<- r0
4087    GOTO_OPCODE(ip)                     @ jump to next instruction
4088    /* 9-10 instructions */
4089
4090
4091/* ------------------------------ */
4092    .balign 64
4093.L_OP_INT_TO_CHAR: /* 0x8e */
4094/* File: armv5te/OP_INT_TO_CHAR.S */
4095/* File: armv5te/unop.S */
4096    /*
4097     * Generic 32-bit unary operation.  Provide an "instr" line that
4098     * specifies an instruction that performs "result = op r0".
4099     * This could be an ARM instruction or a function call.
4100     *
4101     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
4102     *      int-to-byte, int-to-char, int-to-short
4103     */
4104    /* unop vA, vB */
4105    mov     r3, rINST, lsr #12          @ r3<- B
4106    mov     r9, rINST, lsr #8           @ r9<- A+
4107    GET_VREG(r0, r3)                    @ r0<- vB
4108    and     r9, r9, #15
4109    mov     r0, r0, asl #16                           @ optional op; may set condition codes
4110    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
4111    mov     r0, r0, lsr #16                              @ r0<- op, r0-r3 changed
4112    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4113    SET_VREG(r0, r9)                    @ vAA<- r0
4114    GOTO_OPCODE(ip)                     @ jump to next instruction
4115    /* 9-10 instructions */
4116
4117
4118/* ------------------------------ */
4119    .balign 64
4120.L_OP_INT_TO_SHORT: /* 0x8f */
4121/* File: armv5te/OP_INT_TO_SHORT.S */
4122/* File: armv5te/unop.S */
4123    /*
4124     * Generic 32-bit unary operation.  Provide an "instr" line that
4125     * specifies an instruction that performs "result = op r0".
4126     * This could be an ARM instruction or a function call.
4127     *
4128     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
4129     *      int-to-byte, int-to-char, int-to-short
4130     */
4131    /* unop vA, vB */
4132    mov     r3, rINST, lsr #12          @ r3<- B
4133    mov     r9, rINST, lsr #8           @ r9<- A+
4134    GET_VREG(r0, r3)                    @ r0<- vB
4135    and     r9, r9, #15
4136    mov     r0, r0, asl #16                           @ optional op; may set condition codes
4137    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
4138    mov     r0, r0, asr #16                              @ r0<- op, r0-r3 changed
4139    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4140    SET_VREG(r0, r9)                    @ vAA<- r0
4141    GOTO_OPCODE(ip)                     @ jump to next instruction
4142    /* 9-10 instructions */
4143
4144
4145/* ------------------------------ */
4146    .balign 64
4147.L_OP_ADD_INT: /* 0x90 */
4148/* File: armv5te/OP_ADD_INT.S */
4149/* File: armv5te/binop.S */
4150    /*
4151     * Generic 32-bit binary operation.  Provide an "instr" line that
4152     * specifies an instruction that performs "result = r0 op r1".
4153     * This could be an ARM instruction or a function call.  (If the result
4154     * comes back in a register other than r0, you can override "result".)
4155     *
4156     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4157     * vCC (r1).  Useful for integer division and modulus.  Note that we
4158     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4159     * handles it correctly.
4160     *
4161     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4162     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4163     *      mul-float, div-float, rem-float
4164     */
4165    /* binop vAA, vBB, vCC */
4166    FETCH(r0, 1)                        @ r0<- CCBB
4167    mov     r9, rINST, lsr #8           @ r9<- AA
4168    mov     r3, r0, lsr #8              @ r3<- CC
4169    and     r2, r0, #255                @ r2<- BB
4170    GET_VREG(r1, r3)                    @ r1<- vCC
4171    GET_VREG(r0, r2)                    @ r0<- vBB
4172    .if 0
4173    cmp     r1, #0                      @ is second operand zero?
4174    beq     common_errDivideByZero
4175    .endif
4176
4177    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4178                               @ optional op; may set condition codes
4179    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
4180    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4181    SET_VREG(r0, r9)               @ vAA<- r0
4182    GOTO_OPCODE(ip)                     @ jump to next instruction
4183    /* 11-14 instructions */
4184
4185
4186/* ------------------------------ */
4187    .balign 64
4188.L_OP_SUB_INT: /* 0x91 */
4189/* File: armv5te/OP_SUB_INT.S */
4190/* File: armv5te/binop.S */
4191    /*
4192     * Generic 32-bit binary operation.  Provide an "instr" line that
4193     * specifies an instruction that performs "result = r0 op r1".
4194     * This could be an ARM instruction or a function call.  (If the result
4195     * comes back in a register other than r0, you can override "result".)
4196     *
4197     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4198     * vCC (r1).  Useful for integer division and modulus.  Note that we
4199     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4200     * handles it correctly.
4201     *
4202     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4203     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4204     *      mul-float, div-float, rem-float
4205     */
4206    /* binop vAA, vBB, vCC */
4207    FETCH(r0, 1)                        @ r0<- CCBB
4208    mov     r9, rINST, lsr #8           @ r9<- AA
4209    mov     r3, r0, lsr #8              @ r3<- CC
4210    and     r2, r0, #255                @ r2<- BB
4211    GET_VREG(r1, r3)                    @ r1<- vCC
4212    GET_VREG(r0, r2)                    @ r0<- vBB
4213    .if 0
4214    cmp     r1, #0                      @ is second operand zero?
4215    beq     common_errDivideByZero
4216    .endif
4217
4218    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4219                               @ optional op; may set condition codes
4220    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
4221    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4222    SET_VREG(r0, r9)               @ vAA<- r0
4223    GOTO_OPCODE(ip)                     @ jump to next instruction
4224    /* 11-14 instructions */
4225
4226
4227/* ------------------------------ */
4228    .balign 64
4229.L_OP_MUL_INT: /* 0x92 */
4230/* File: armv5te/OP_MUL_INT.S */
4231/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
4232/* File: armv5te/binop.S */
4233    /*
4234     * Generic 32-bit binary operation.  Provide an "instr" line that
4235     * specifies an instruction that performs "result = r0 op r1".
4236     * This could be an ARM instruction or a function call.  (If the result
4237     * comes back in a register other than r0, you can override "result".)
4238     *
4239     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4240     * vCC (r1).  Useful for integer division and modulus.  Note that we
4241     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4242     * handles it correctly.
4243     *
4244     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4245     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4246     *      mul-float, div-float, rem-float
4247     */
4248    /* binop vAA, vBB, vCC */
4249    FETCH(r0, 1)                        @ r0<- CCBB
4250    mov     r9, rINST, lsr #8           @ r9<- AA
4251    mov     r3, r0, lsr #8              @ r3<- CC
4252    and     r2, r0, #255                @ r2<- BB
4253    GET_VREG(r1, r3)                    @ r1<- vCC
4254    GET_VREG(r0, r2)                    @ r0<- vBB
4255    .if 0
4256    cmp     r1, #0                      @ is second operand zero?
4257    beq     common_errDivideByZero
4258    .endif
4259
4260    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4261                               @ optional op; may set condition codes
4262    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
4263    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4264    SET_VREG(r0, r9)               @ vAA<- r0
4265    GOTO_OPCODE(ip)                     @ jump to next instruction
4266    /* 11-14 instructions */
4267
4268
4269/* ------------------------------ */
4270    .balign 64
4271.L_OP_DIV_INT: /* 0x93 */
4272/* File: armv5te/OP_DIV_INT.S */
4273/* File: armv5te/binop.S */
4274    /*
4275     * Generic 32-bit binary operation.  Provide an "instr" line that
4276     * specifies an instruction that performs "result = r0 op r1".
4277     * This could be an ARM instruction or a function call.  (If the result
4278     * comes back in a register other than r0, you can override "result".)
4279     *
4280     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4281     * vCC (r1).  Useful for integer division and modulus.  Note that we
4282     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4283     * handles it correctly.
4284     *
4285     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4286     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4287     *      mul-float, div-float, rem-float
4288     */
4289    /* binop vAA, vBB, vCC */
4290    FETCH(r0, 1)                        @ r0<- CCBB
4291    mov     r9, rINST, lsr #8           @ r9<- AA
4292    mov     r3, r0, lsr #8              @ r3<- CC
4293    and     r2, r0, #255                @ r2<- BB
4294    GET_VREG(r1, r3)                    @ r1<- vCC
4295    GET_VREG(r0, r2)                    @ r0<- vBB
4296    .if 1
4297    cmp     r1, #0                      @ is second operand zero?
4298    beq     common_errDivideByZero
4299    .endif
4300
4301    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4302                               @ optional op; may set condition codes
4303    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
4304    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4305    SET_VREG(r0, r9)               @ vAA<- r0
4306    GOTO_OPCODE(ip)                     @ jump to next instruction
4307    /* 11-14 instructions */
4308
4309
4310/* ------------------------------ */
4311    .balign 64
4312.L_OP_REM_INT: /* 0x94 */
4313/* File: armv5te/OP_REM_INT.S */
4314/* idivmod returns quotient in r0 and remainder in r1 */
4315/* File: armv5te/binop.S */
4316    /*
4317     * Generic 32-bit binary operation.  Provide an "instr" line that
4318     * specifies an instruction that performs "result = r0 op r1".
4319     * This could be an ARM instruction or a function call.  (If the result
4320     * comes back in a register other than r0, you can override "result".)
4321     *
4322     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4323     * vCC (r1).  Useful for integer division and modulus.  Note that we
4324     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4325     * handles it correctly.
4326     *
4327     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4328     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4329     *      mul-float, div-float, rem-float
4330     */
4331    /* binop vAA, vBB, vCC */
4332    FETCH(r0, 1)                        @ r0<- CCBB
4333    mov     r9, rINST, lsr #8           @ r9<- AA
4334    mov     r3, r0, lsr #8              @ r3<- CC
4335    and     r2, r0, #255                @ r2<- BB
4336    GET_VREG(r1, r3)                    @ r1<- vCC
4337    GET_VREG(r0, r2)                    @ r0<- vBB
4338    .if 1
4339    cmp     r1, #0                      @ is second operand zero?
4340    beq     common_errDivideByZero
4341    .endif
4342
4343    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4344                               @ optional op; may set condition codes
4345    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
4346    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4347    SET_VREG(r1, r9)               @ vAA<- r1
4348    GOTO_OPCODE(ip)                     @ jump to next instruction
4349    /* 11-14 instructions */
4350
4351
4352/* ------------------------------ */
4353    .balign 64
4354.L_OP_AND_INT: /* 0x95 */
4355/* File: armv5te/OP_AND_INT.S */
4356/* File: armv5te/binop.S */
4357    /*
4358     * Generic 32-bit binary operation.  Provide an "instr" line that
4359     * specifies an instruction that performs "result = r0 op r1".
4360     * This could be an ARM instruction or a function call.  (If the result
4361     * comes back in a register other than r0, you can override "result".)
4362     *
4363     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4364     * vCC (r1).  Useful for integer division and modulus.  Note that we
4365     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4366     * handles it correctly.
4367     *
4368     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4369     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4370     *      mul-float, div-float, rem-float
4371     */
4372    /* binop vAA, vBB, vCC */
4373    FETCH(r0, 1)                        @ r0<- CCBB
4374    mov     r9, rINST, lsr #8           @ r9<- AA
4375    mov     r3, r0, lsr #8              @ r3<- CC
4376    and     r2, r0, #255                @ r2<- BB
4377    GET_VREG(r1, r3)                    @ r1<- vCC
4378    GET_VREG(r0, r2)                    @ r0<- vBB
4379    .if 0
4380    cmp     r1, #0                      @ is second operand zero?
4381    beq     common_errDivideByZero
4382    .endif
4383
4384    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4385                               @ optional op; may set condition codes
4386    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
4387    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4388    SET_VREG(r0, r9)               @ vAA<- r0
4389    GOTO_OPCODE(ip)                     @ jump to next instruction
4390    /* 11-14 instructions */
4391
4392
4393/* ------------------------------ */
4394    .balign 64
4395.L_OP_OR_INT: /* 0x96 */
4396/* File: armv5te/OP_OR_INT.S */
4397/* File: armv5te/binop.S */
4398    /*
4399     * Generic 32-bit binary operation.  Provide an "instr" line that
4400     * specifies an instruction that performs "result = r0 op r1".
4401     * This could be an ARM instruction or a function call.  (If the result
4402     * comes back in a register other than r0, you can override "result".)
4403     *
4404     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4405     * vCC (r1).  Useful for integer division and modulus.  Note that we
4406     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4407     * handles it correctly.
4408     *
4409     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4410     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4411     *      mul-float, div-float, rem-float
4412     */
4413    /* binop vAA, vBB, vCC */
4414    FETCH(r0, 1)                        @ r0<- CCBB
4415    mov     r9, rINST, lsr #8           @ r9<- AA
4416    mov     r3, r0, lsr #8              @ r3<- CC
4417    and     r2, r0, #255                @ r2<- BB
4418    GET_VREG(r1, r3)                    @ r1<- vCC
4419    GET_VREG(r0, r2)                    @ r0<- vBB
4420    .if 0
4421    cmp     r1, #0                      @ is second operand zero?
4422    beq     common_errDivideByZero
4423    .endif
4424
4425    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4426                               @ optional op; may set condition codes
4427    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
4428    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4429    SET_VREG(r0, r9)               @ vAA<- r0
4430    GOTO_OPCODE(ip)                     @ jump to next instruction
4431    /* 11-14 instructions */
4432
4433
4434/* ------------------------------ */
4435    .balign 64
4436.L_OP_XOR_INT: /* 0x97 */
4437/* File: armv5te/OP_XOR_INT.S */
4438/* File: armv5te/binop.S */
4439    /*
4440     * Generic 32-bit binary operation.  Provide an "instr" line that
4441     * specifies an instruction that performs "result = r0 op r1".
4442     * This could be an ARM instruction or a function call.  (If the result
4443     * comes back in a register other than r0, you can override "result".)
4444     *
4445     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4446     * vCC (r1).  Useful for integer division and modulus.  Note that we
4447     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4448     * handles it correctly.
4449     *
4450     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4451     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4452     *      mul-float, div-float, rem-float
4453     */
4454    /* binop vAA, vBB, vCC */
4455    FETCH(r0, 1)                        @ r0<- CCBB
4456    mov     r9, rINST, lsr #8           @ r9<- AA
4457    mov     r3, r0, lsr #8              @ r3<- CC
4458    and     r2, r0, #255                @ r2<- BB
4459    GET_VREG(r1, r3)                    @ r1<- vCC
4460    GET_VREG(r0, r2)                    @ r0<- vBB
4461    .if 0
4462    cmp     r1, #0                      @ is second operand zero?
4463    beq     common_errDivideByZero
4464    .endif
4465
4466    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4467                               @ optional op; may set condition codes
4468    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
4469    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4470    SET_VREG(r0, r9)               @ vAA<- r0
4471    GOTO_OPCODE(ip)                     @ jump to next instruction
4472    /* 11-14 instructions */
4473
4474
4475/* ------------------------------ */
4476    .balign 64
4477.L_OP_SHL_INT: /* 0x98 */
4478/* File: armv5te/OP_SHL_INT.S */
4479/* File: armv5te/binop.S */
4480    /*
4481     * Generic 32-bit binary operation.  Provide an "instr" line that
4482     * specifies an instruction that performs "result = r0 op r1".
4483     * This could be an ARM instruction or a function call.  (If the result
4484     * comes back in a register other than r0, you can override "result".)
4485     *
4486     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4487     * vCC (r1).  Useful for integer division and modulus.  Note that we
4488     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4489     * handles it correctly.
4490     *
4491     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4492     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4493     *      mul-float, div-float, rem-float
4494     */
4495    /* binop vAA, vBB, vCC */
4496    FETCH(r0, 1)                        @ r0<- CCBB
4497    mov     r9, rINST, lsr #8           @ r9<- AA
4498    mov     r3, r0, lsr #8              @ r3<- CC
4499    and     r2, r0, #255                @ r2<- BB
4500    GET_VREG(r1, r3)                    @ r1<- vCC
4501    GET_VREG(r0, r2)                    @ r0<- vBB
4502    .if 0
4503    cmp     r1, #0                      @ is second operand zero?
4504    beq     common_errDivideByZero
4505    .endif
4506
4507    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4508    and     r1, r1, #31                           @ optional op; may set condition codes
4509    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
4510    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4511    SET_VREG(r0, r9)               @ vAA<- r0
4512    GOTO_OPCODE(ip)                     @ jump to next instruction
4513    /* 11-14 instructions */
4514
4515
4516/* ------------------------------ */
4517    .balign 64
4518.L_OP_SHR_INT: /* 0x99 */
4519/* File: armv5te/OP_SHR_INT.S */
4520/* File: armv5te/binop.S */
4521    /*
4522     * Generic 32-bit binary operation.  Provide an "instr" line that
4523     * specifies an instruction that performs "result = r0 op r1".
4524     * This could be an ARM instruction or a function call.  (If the result
4525     * comes back in a register other than r0, you can override "result".)
4526     *
4527     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4528     * vCC (r1).  Useful for integer division and modulus.  Note that we
4529     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4530     * handles it correctly.
4531     *
4532     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4533     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4534     *      mul-float, div-float, rem-float
4535     */
4536    /* binop vAA, vBB, vCC */
4537    FETCH(r0, 1)                        @ r0<- CCBB
4538    mov     r9, rINST, lsr #8           @ r9<- AA
4539    mov     r3, r0, lsr #8              @ r3<- CC
4540    and     r2, r0, #255                @ r2<- BB
4541    GET_VREG(r1, r3)                    @ r1<- vCC
4542    GET_VREG(r0, r2)                    @ r0<- vBB
4543    .if 0
4544    cmp     r1, #0                      @ is second operand zero?
4545    beq     common_errDivideByZero
4546    .endif
4547
4548    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4549    and     r1, r1, #31                           @ optional op; may set condition codes
4550    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
4551    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4552    SET_VREG(r0, r9)               @ vAA<- r0
4553    GOTO_OPCODE(ip)                     @ jump to next instruction
4554    /* 11-14 instructions */
4555
4556
4557/* ------------------------------ */
4558    .balign 64
4559.L_OP_USHR_INT: /* 0x9a */
4560/* File: armv5te/OP_USHR_INT.S */
4561/* File: armv5te/binop.S */
4562    /*
4563     * Generic 32-bit binary operation.  Provide an "instr" line that
4564     * specifies an instruction that performs "result = r0 op r1".
4565     * This could be an ARM instruction or a function call.  (If the result
4566     * comes back in a register other than r0, you can override "result".)
4567     *
4568     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4569     * vCC (r1).  Useful for integer division and modulus.  Note that we
4570     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4571     * handles it correctly.
4572     *
4573     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4574     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4575     *      mul-float, div-float, rem-float
4576     */
4577    /* binop vAA, vBB, vCC */
4578    FETCH(r0, 1)                        @ r0<- CCBB
4579    mov     r9, rINST, lsr #8           @ r9<- AA
4580    mov     r3, r0, lsr #8              @ r3<- CC
4581    and     r2, r0, #255                @ r2<- BB
4582    GET_VREG(r1, r3)                    @ r1<- vCC
4583    GET_VREG(r0, r2)                    @ r0<- vBB
4584    .if 0
4585    cmp     r1, #0                      @ is second operand zero?
4586    beq     common_errDivideByZero
4587    .endif
4588
4589    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4590    and     r1, r1, #31                           @ optional op; may set condition codes
4591    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
4592    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4593    SET_VREG(r0, r9)               @ vAA<- r0
4594    GOTO_OPCODE(ip)                     @ jump to next instruction
4595    /* 11-14 instructions */
4596
4597
4598/* ------------------------------ */
4599    .balign 64
4600.L_OP_ADD_LONG: /* 0x9b */
4601/* File: armv5te/OP_ADD_LONG.S */
4602/* File: armv5te/binopWide.S */
4603    /*
4604     * Generic 64-bit binary operation.  Provide an "instr" line that
4605     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4606     * This could be an ARM instruction or a function call.  (If the result
4607     * comes back in a register other than r0, you can override "result".)
4608     *
4609     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4610     * vCC (r1).  Useful for integer division and modulus.
4611     *
4612     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4613     *      xor-long, add-double, sub-double, mul-double, div-double,
4614     *      rem-double
4615     *
4616     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4617     */
4618    /* binop vAA, vBB, vCC */
4619    FETCH(r0, 1)                        @ r0<- CCBB
4620    mov     r9, rINST, lsr #8           @ r9<- AA
4621    and     r2, r0, #255                @ r2<- BB
4622    mov     r3, r0, lsr #8              @ r3<- CC
4623    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4624    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4625    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4626    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4627    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4628    .if 0
4629    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4630    beq     common_errDivideByZero
4631    .endif
4632    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4633
4634    adds    r0, r0, r2                           @ optional op; may set condition codes
4635    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
4636    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4637    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4638    GOTO_OPCODE(ip)                     @ jump to next instruction
4639    /* 14-17 instructions */
4640
4641
4642/* ------------------------------ */
4643    .balign 64
4644.L_OP_SUB_LONG: /* 0x9c */
4645/* File: armv5te/OP_SUB_LONG.S */
4646/* File: armv5te/binopWide.S */
4647    /*
4648     * Generic 64-bit binary operation.  Provide an "instr" line that
4649     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4650     * This could be an ARM instruction or a function call.  (If the result
4651     * comes back in a register other than r0, you can override "result".)
4652     *
4653     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4654     * vCC (r1).  Useful for integer division and modulus.
4655     *
4656     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4657     *      xor-long, add-double, sub-double, mul-double, div-double,
4658     *      rem-double
4659     *
4660     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4661     */
4662    /* binop vAA, vBB, vCC */
4663    FETCH(r0, 1)                        @ r0<- CCBB
4664    mov     r9, rINST, lsr #8           @ r9<- AA
4665    and     r2, r0, #255                @ r2<- BB
4666    mov     r3, r0, lsr #8              @ r3<- CC
4667    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4668    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4669    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4670    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4671    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4672    .if 0
4673    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4674    beq     common_errDivideByZero
4675    .endif
4676    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4677
4678    subs    r0, r0, r2                           @ optional op; may set condition codes
4679    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
4680    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4681    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4682    GOTO_OPCODE(ip)                     @ jump to next instruction
4683    /* 14-17 instructions */
4684
4685
4686/* ------------------------------ */
4687    .balign 64
4688.L_OP_MUL_LONG: /* 0x9d */
4689/* File: armv5te/OP_MUL_LONG.S */
4690    /*
4691     * Signed 64-bit integer multiply.
4692     *
4693     * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
4694     *        WX
4695     *      x YZ
4696     *  --------
4697     *     ZW ZX
4698     *  YW YX
4699     *
4700     * The low word of the result holds ZX, the high word holds
4701     * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
4702     * it doesn't fit in the low 64 bits.
4703     *
4704     * Unlike most ARM math operations, multiply instructions have
4705     * restrictions on using the same register more than once (Rd and Rm
4706     * cannot be the same).
4707     */
4708    /* mul-long vAA, vBB, vCC */
4709    FETCH(r0, 1)                        @ r0<- CCBB
4710    and     r2, r0, #255                @ r2<- BB
4711    mov     r3, r0, lsr #8              @ r3<- CC
4712    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4713    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4714    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4715    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4716    mul     ip, r2, r1                  @  ip<- ZxW
4717    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
4718    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
4719    mov     r0, rINST, lsr #8           @ r0<- AA
4720    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
4721    add     r0, rFP, r0, lsl #2         @ r0<- &fp[AA]
4722    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4723    b       .LOP_MUL_LONG_finish
4724
4725/* ------------------------------ */
4726    .balign 64
4727.L_OP_DIV_LONG: /* 0x9e */
4728/* File: armv5te/OP_DIV_LONG.S */
4729/* File: armv5te/binopWide.S */
4730    /*
4731     * Generic 64-bit binary operation.  Provide an "instr" line that
4732     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4733     * This could be an ARM instruction or a function call.  (If the result
4734     * comes back in a register other than r0, you can override "result".)
4735     *
4736     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4737     * vCC (r1).  Useful for integer division and modulus.
4738     *
4739     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4740     *      xor-long, add-double, sub-double, mul-double, div-double,
4741     *      rem-double
4742     *
4743     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4744     */
4745    /* binop vAA, vBB, vCC */
4746    FETCH(r0, 1)                        @ r0<- CCBB
4747    mov     r9, rINST, lsr #8           @ r9<- AA
4748    and     r2, r0, #255                @ r2<- BB
4749    mov     r3, r0, lsr #8              @ r3<- CC
4750    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4751    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4752    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4753    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4754    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4755    .if 1
4756    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4757    beq     common_errDivideByZero
4758    .endif
4759    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4760
4761                               @ optional op; may set condition codes
4762    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4763    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4764    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4765    GOTO_OPCODE(ip)                     @ jump to next instruction
4766    /* 14-17 instructions */
4767
4768
4769/* ------------------------------ */
4770    .balign 64
4771.L_OP_REM_LONG: /* 0x9f */
4772/* File: armv5te/OP_REM_LONG.S */
4773/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
4774/* File: armv5te/binopWide.S */
4775    /*
4776     * Generic 64-bit binary operation.  Provide an "instr" line that
4777     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4778     * This could be an ARM instruction or a function call.  (If the result
4779     * comes back in a register other than r0, you can override "result".)
4780     *
4781     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4782     * vCC (r1).  Useful for integer division and modulus.
4783     *
4784     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4785     *      xor-long, add-double, sub-double, mul-double, div-double,
4786     *      rem-double
4787     *
4788     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4789     */
4790    /* binop vAA, vBB, vCC */
4791    FETCH(r0, 1)                        @ r0<- CCBB
4792    mov     r9, rINST, lsr #8           @ r9<- AA
4793    and     r2, r0, #255                @ r2<- BB
4794    mov     r3, r0, lsr #8              @ r3<- CC
4795    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4796    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4797    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4798    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4799    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4800    .if 1
4801    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4802    beq     common_errDivideByZero
4803    .endif
4804    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4805
4806                               @ optional op; may set condition codes
4807    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4808    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4809    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
4810    GOTO_OPCODE(ip)                     @ jump to next instruction
4811    /* 14-17 instructions */
4812
4813
4814/* ------------------------------ */
4815    .balign 64
4816.L_OP_AND_LONG: /* 0xa0 */
4817/* File: armv5te/OP_AND_LONG.S */
4818/* File: armv5te/binopWide.S */
4819    /*
4820     * Generic 64-bit binary operation.  Provide an "instr" line that
4821     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4822     * This could be an ARM instruction or a function call.  (If the result
4823     * comes back in a register other than r0, you can override "result".)
4824     *
4825     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4826     * vCC (r1).  Useful for integer division and modulus.
4827     *
4828     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4829     *      xor-long, add-double, sub-double, mul-double, div-double,
4830     *      rem-double
4831     *
4832     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4833     */
4834    /* binop vAA, vBB, vCC */
4835    FETCH(r0, 1)                        @ r0<- CCBB
4836    mov     r9, rINST, lsr #8           @ r9<- AA
4837    and     r2, r0, #255                @ r2<- BB
4838    mov     r3, r0, lsr #8              @ r3<- CC
4839    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4840    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4841    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4842    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4843    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4844    .if 0
4845    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4846    beq     common_errDivideByZero
4847    .endif
4848    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4849
4850    and     r0, r0, r2                           @ optional op; may set condition codes
4851    and     r1, r1, r3                              @ result<- op, r0-r3 changed
4852    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4853    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4854    GOTO_OPCODE(ip)                     @ jump to next instruction
4855    /* 14-17 instructions */
4856
4857
4858/* ------------------------------ */
4859    .balign 64
4860.L_OP_OR_LONG: /* 0xa1 */
4861/* File: armv5te/OP_OR_LONG.S */
4862/* File: armv5te/binopWide.S */
4863    /*
4864     * Generic 64-bit binary operation.  Provide an "instr" line that
4865     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4866     * This could be an ARM instruction or a function call.  (If the result
4867     * comes back in a register other than r0, you can override "result".)
4868     *
4869     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4870     * vCC (r1).  Useful for integer division and modulus.
4871     *
4872     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4873     *      xor-long, add-double, sub-double, mul-double, div-double,
4874     *      rem-double
4875     *
4876     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4877     */
4878    /* binop vAA, vBB, vCC */
4879    FETCH(r0, 1)                        @ r0<- CCBB
4880    mov     r9, rINST, lsr #8           @ r9<- AA
4881    and     r2, r0, #255                @ r2<- BB
4882    mov     r3, r0, lsr #8              @ r3<- CC
4883    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4884    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4885    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4886    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4887    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4888    .if 0
4889    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4890    beq     common_errDivideByZero
4891    .endif
4892    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4893
4894    orr     r0, r0, r2                           @ optional op; may set condition codes
4895    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
4896    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4897    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4898    GOTO_OPCODE(ip)                     @ jump to next instruction
4899    /* 14-17 instructions */
4900
4901
4902/* ------------------------------ */
4903    .balign 64
4904.L_OP_XOR_LONG: /* 0xa2 */
4905/* File: armv5te/OP_XOR_LONG.S */
4906/* File: armv5te/binopWide.S */
4907    /*
4908     * Generic 64-bit binary operation.  Provide an "instr" line that
4909     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4910     * This could be an ARM instruction or a function call.  (If the result
4911     * comes back in a register other than r0, you can override "result".)
4912     *
4913     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4914     * vCC (r1).  Useful for integer division and modulus.
4915     *
4916     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4917     *      xor-long, add-double, sub-double, mul-double, div-double,
4918     *      rem-double
4919     *
4920     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4921     */
4922    /* binop vAA, vBB, vCC */
4923    FETCH(r0, 1)                        @ r0<- CCBB
4924    mov     r9, rINST, lsr #8           @ r9<- AA
4925    and     r2, r0, #255                @ r2<- BB
4926    mov     r3, r0, lsr #8              @ r3<- CC
4927    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4928    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4929    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4930    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4931    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4932    .if 0
4933    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4934    beq     common_errDivideByZero
4935    .endif
4936    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4937
4938    eor     r0, r0, r2                           @ optional op; may set condition codes
4939    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
4940    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4941    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4942    GOTO_OPCODE(ip)                     @ jump to next instruction
4943    /* 14-17 instructions */
4944
4945
4946/* ------------------------------ */
4947    .balign 64
4948.L_OP_SHL_LONG: /* 0xa3 */
4949/* File: armv5te/OP_SHL_LONG.S */
4950    /*
4951     * Long integer shift.  This is different from the generic 32/64-bit
4952     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4953     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4954     * 6 bits of the shift distance.
4955     */
4956    /* shl-long vAA, vBB, vCC */
4957    FETCH(r0, 1)                        @ r0<- CCBB
4958    mov     r9, rINST, lsr #8           @ r9<- AA
4959    and     r3, r0, #255                @ r3<- BB
4960    mov     r0, r0, lsr #8              @ r0<- CC
4961    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4962    GET_VREG(r2, r0)                    @ r2<- vCC
4963    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4964    and     r2, r2, #63                 @ r2<- r2 & 0x3f
4965    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4966
4967    mov     r1, r1, asl r2              @  r1<- r1 << r2
4968    rsb     r3, r2, #32                 @  r3<- 32 - r2
4969    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
4970    subs    ip, r2, #32                 @  ip<- r2 - 32
4971    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
4972    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4973    b       .LOP_SHL_LONG_finish
4974
4975/* ------------------------------ */
4976    .balign 64
4977.L_OP_SHR_LONG: /* 0xa4 */
4978/* File: armv5te/OP_SHR_LONG.S */
4979    /*
4980     * Long integer shift.  This is different from the generic 32/64-bit
4981     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4982     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4983     * 6 bits of the shift distance.
4984     */
4985    /* shr-long vAA, vBB, vCC */
4986    FETCH(r0, 1)                        @ r0<- CCBB
4987    mov     r9, rINST, lsr #8           @ r9<- AA
4988    and     r3, r0, #255                @ r3<- BB
4989    mov     r0, r0, lsr #8              @ r0<- CC
4990    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4991    GET_VREG(r2, r0)                    @ r2<- vCC
4992    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4993    and     r2, r2, #63                 @ r0<- r0 & 0x3f
4994    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4995
4996    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
4997    rsb     r3, r2, #32                 @  r3<- 32 - r2
4998    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
4999    subs    ip, r2, #32                 @  ip<- r2 - 32
5000    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
5001    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5002    b       .LOP_SHR_LONG_finish
5003
5004/* ------------------------------ */
5005    .balign 64
5006.L_OP_USHR_LONG: /* 0xa5 */
5007/* File: armv5te/OP_USHR_LONG.S */
5008    /*
5009     * Long integer shift.  This is different from the generic 32/64-bit
5010     * binary operations because vAA/vBB are 64-bit but vCC (the shift
5011     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
5012     * 6 bits of the shift distance.
5013     */
5014    /* ushr-long vAA, vBB, vCC */
5015    FETCH(r0, 1)                        @ r0<- CCBB
5016    mov     r9, rINST, lsr #8           @ r9<- AA
5017    and     r3, r0, #255                @ r3<- BB
5018    mov     r0, r0, lsr #8              @ r0<- CC
5019    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
5020    GET_VREG(r2, r0)                    @ r2<- vCC
5021    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5022    and     r2, r2, #63                 @ r0<- r0 & 0x3f
5023    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5024
5025    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
5026    rsb     r3, r2, #32                 @  r3<- 32 - r2
5027    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
5028    subs    ip, r2, #32                 @  ip<- r2 - 32
5029    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
5030    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5031    b       .LOP_USHR_LONG_finish
5032
5033/* ------------------------------ */
5034    .balign 64
5035.L_OP_ADD_FLOAT: /* 0xa6 */
5036/* File: armv5te/OP_ADD_FLOAT.S */
5037/* File: armv5te/binop.S */
5038    /*
5039     * Generic 32-bit binary operation.  Provide an "instr" line that
5040     * specifies an instruction that performs "result = r0 op r1".
5041     * This could be an ARM instruction or a function call.  (If the result
5042     * comes back in a register other than r0, you can override "result".)
5043     *
5044     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5045     * vCC (r1).  Useful for integer division and modulus.  Note that we
5046     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
5047     * handles it correctly.
5048     *
5049     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
5050     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
5051     *      mul-float, div-float, rem-float
5052     */
5053    /* binop vAA, vBB, vCC */
5054    FETCH(r0, 1)                        @ r0<- CCBB
5055    mov     r9, rINST, lsr #8           @ r9<- AA
5056    mov     r3, r0, lsr #8              @ r3<- CC
5057    and     r2, r0, #255                @ r2<- BB
5058    GET_VREG(r1, r3)                    @ r1<- vCC
5059    GET_VREG(r0, r2)                    @ r0<- vBB
5060    .if 0
5061    cmp     r1, #0                      @ is second operand zero?
5062    beq     common_errDivideByZero
5063    .endif
5064
5065    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5066                               @ optional op; may set condition codes
5067    bl      __aeabi_fadd                              @ r0<- op, r0-r3 changed
5068    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5069    SET_VREG(r0, r9)               @ vAA<- r0
5070    GOTO_OPCODE(ip)                     @ jump to next instruction
5071    /* 11-14 instructions */
5072
5073
5074/* ------------------------------ */
5075    .balign 64
5076.L_OP_SUB_FLOAT: /* 0xa7 */
5077/* File: armv5te/OP_SUB_FLOAT.S */
5078/* File: armv5te/binop.S */
5079    /*
5080     * Generic 32-bit binary operation.  Provide an "instr" line that
5081     * specifies an instruction that performs "result = r0 op r1".
5082     * This could be an ARM instruction or a function call.  (If the result
5083     * comes back in a register other than r0, you can override "result".)
5084     *
5085     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5086     * vCC (r1).  Useful for integer division and modulus.  Note that we
5087     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
5088     * handles it correctly.
5089     *
5090     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
5091     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
5092     *      mul-float, div-float, rem-float
5093     */
5094    /* binop vAA, vBB, vCC */
5095    FETCH(r0, 1)                        @ r0<- CCBB
5096    mov     r9, rINST, lsr #8           @ r9<- AA
5097    mov     r3, r0, lsr #8              @ r3<- CC
5098    and     r2, r0, #255                @ r2<- BB
5099    GET_VREG(r1, r3)                    @ r1<- vCC
5100    GET_VREG(r0, r2)                    @ r0<- vBB
5101    .if 0
5102    cmp     r1, #0                      @ is second operand zero?
5103    beq     common_errDivideByZero
5104    .endif
5105
5106    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5107                               @ optional op; may set condition codes
5108    bl      __aeabi_fsub                              @ r0<- op, r0-r3 changed
5109    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5110    SET_VREG(r0, r9)               @ vAA<- r0
5111    GOTO_OPCODE(ip)                     @ jump to next instruction
5112    /* 11-14 instructions */
5113
5114
5115/* ------------------------------ */
5116    .balign 64
5117.L_OP_MUL_FLOAT: /* 0xa8 */
5118/* File: armv5te/OP_MUL_FLOAT.S */
5119/* File: armv5te/binop.S */
5120    /*
5121     * Generic 32-bit binary operation.  Provide an "instr" line that
5122     * specifies an instruction that performs "result = r0 op r1".
5123     * This could be an ARM instruction or a function call.  (If the result
5124     * comes back in a register other than r0, you can override "result".)
5125     *
5126     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5127     * vCC (r1).  Useful for integer division and modulus.  Note that we
5128     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
5129     * handles it correctly.
5130     *
5131     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
5132     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
5133     *      mul-float, div-float, rem-float
5134     */
5135    /* binop vAA, vBB, vCC */
5136    FETCH(r0, 1)                        @ r0<- CCBB
5137    mov     r9, rINST, lsr #8           @ r9<- AA
5138    mov     r3, r0, lsr #8              @ r3<- CC
5139    and     r2, r0, #255                @ r2<- BB
5140    GET_VREG(r1, r3)                    @ r1<- vCC
5141    GET_VREG(r0, r2)                    @ r0<- vBB
5142    .if 0
5143    cmp     r1, #0                      @ is second operand zero?
5144    beq     common_errDivideByZero
5145    .endif
5146
5147    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5148                               @ optional op; may set condition codes
5149    bl      __aeabi_fmul                              @ r0<- op, r0-r3 changed
5150    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5151    SET_VREG(r0, r9)               @ vAA<- r0
5152    GOTO_OPCODE(ip)                     @ jump to next instruction
5153    /* 11-14 instructions */
5154
5155
5156/* ------------------------------ */
5157    .balign 64
5158.L_OP_DIV_FLOAT: /* 0xa9 */
5159/* File: armv5te/OP_DIV_FLOAT.S */
5160/* File: armv5te/binop.S */
5161    /*
5162     * Generic 32-bit binary operation.  Provide an "instr" line that
5163     * specifies an instruction that performs "result = r0 op r1".
5164     * This could be an ARM instruction or a function call.  (If the result
5165     * comes back in a register other than r0, you can override "result".)
5166     *
5167     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5168     * vCC (r1).  Useful for integer division and modulus.  Note that we
5169     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
5170     * handles it correctly.
5171     *
5172     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
5173     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
5174     *      mul-float, div-float, rem-float
5175     */
5176    /* binop vAA, vBB, vCC */
5177    FETCH(r0, 1)                        @ r0<- CCBB
5178    mov     r9, rINST, lsr #8           @ r9<- AA
5179    mov     r3, r0, lsr #8              @ r3<- CC
5180    and     r2, r0, #255                @ r2<- BB
5181    GET_VREG(r1, r3)                    @ r1<- vCC
5182    GET_VREG(r0, r2)                    @ r0<- vBB
5183    .if 0
5184    cmp     r1, #0                      @ is second operand zero?
5185    beq     common_errDivideByZero
5186    .endif
5187
5188    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5189                               @ optional op; may set condition codes
5190    bl      __aeabi_fdiv                              @ r0<- op, r0-r3 changed
5191    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5192    SET_VREG(r0, r9)               @ vAA<- r0
5193    GOTO_OPCODE(ip)                     @ jump to next instruction
5194    /* 11-14 instructions */
5195
5196
5197/* ------------------------------ */
5198    .balign 64
5199.L_OP_REM_FLOAT: /* 0xaa */
5200/* File: armv5te/OP_REM_FLOAT.S */
5201/* EABI doesn't define a float remainder function, but libm does */
5202/* File: armv5te/binop.S */
5203    /*
5204     * Generic 32-bit binary operation.  Provide an "instr" line that
5205     * specifies an instruction that performs "result = r0 op r1".
5206     * This could be an ARM instruction or a function call.  (If the result
5207     * comes back in a register other than r0, you can override "result".)
5208     *
5209     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5210     * vCC (r1).  Useful for integer division and modulus.  Note that we
5211     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
5212     * handles it correctly.
5213     *
5214     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
5215     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
5216     *      mul-float, div-float, rem-float
5217     */
5218    /* binop vAA, vBB, vCC */
5219    FETCH(r0, 1)                        @ r0<- CCBB
5220    mov     r9, rINST, lsr #8           @ r9<- AA
5221    mov     r3, r0, lsr #8              @ r3<- CC
5222    and     r2, r0, #255                @ r2<- BB
5223    GET_VREG(r1, r3)                    @ r1<- vCC
5224    GET_VREG(r0, r2)                    @ r0<- vBB
5225    .if 0
5226    cmp     r1, #0                      @ is second operand zero?
5227    beq     common_errDivideByZero
5228    .endif
5229
5230    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5231                               @ optional op; may set condition codes
5232    bl      fmodf                              @ r0<- op, r0-r3 changed
5233    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5234    SET_VREG(r0, r9)               @ vAA<- r0
5235    GOTO_OPCODE(ip)                     @ jump to next instruction
5236    /* 11-14 instructions */
5237
5238
5239/* ------------------------------ */
5240    .balign 64
5241.L_OP_ADD_DOUBLE: /* 0xab */
5242/* File: armv5te/OP_ADD_DOUBLE.S */
5243/* File: armv5te/binopWide.S */
5244    /*
5245     * Generic 64-bit binary operation.  Provide an "instr" line that
5246     * specifies an instruction that performs "result = r0-r1 op r2-r3".
5247     * This could be an ARM instruction or a function call.  (If the result
5248     * comes back in a register other than r0, you can override "result".)
5249     *
5250     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5251     * vCC (r1).  Useful for integer division and modulus.
5252     *
5253     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
5254     *      xor-long, add-double, sub-double, mul-double, div-double,
5255     *      rem-double
5256     *
5257     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
5258     */
5259    /* binop vAA, vBB, vCC */
5260    FETCH(r0, 1)                        @ r0<- CCBB
5261    mov     r9, rINST, lsr #8           @ r9<- AA
5262    and     r2, r0, #255                @ r2<- BB
5263    mov     r3, r0, lsr #8              @ r3<- CC
5264    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5265    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
5266    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
5267    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5268    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
5269    .if 0
5270    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5271    beq     common_errDivideByZero
5272    .endif
5273    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5274
5275                               @ optional op; may set condition codes
5276    bl      __aeabi_dadd                              @ result<- op, r0-r3 changed
5277    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5278    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5279    GOTO_OPCODE(ip)                     @ jump to next instruction
5280    /* 14-17 instructions */
5281
5282
5283/* ------------------------------ */
5284    .balign 64
5285.L_OP_SUB_DOUBLE: /* 0xac */
5286/* File: armv5te/OP_SUB_DOUBLE.S */
5287/* File: armv5te/binopWide.S */
5288    /*
5289     * Generic 64-bit binary operation.  Provide an "instr" line that
5290     * specifies an instruction that performs "result = r0-r1 op r2-r3".
5291     * This could be an ARM instruction or a function call.  (If the result
5292     * comes back in a register other than r0, you can override "result".)
5293     *
5294     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5295     * vCC (r1).  Useful for integer division and modulus.
5296     *
5297     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
5298     *      xor-long, add-double, sub-double, mul-double, div-double,
5299     *      rem-double
5300     *
5301     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
5302     */
5303    /* binop vAA, vBB, vCC */
5304    FETCH(r0, 1)                        @ r0<- CCBB
5305    mov     r9, rINST, lsr #8           @ r9<- AA
5306    and     r2, r0, #255                @ r2<- BB
5307    mov     r3, r0, lsr #8              @ r3<- CC
5308    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5309    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
5310    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
5311    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5312    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
5313    .if 0
5314    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5315    beq     common_errDivideByZero
5316    .endif
5317    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5318
5319                               @ optional op; may set condition codes
5320    bl      __aeabi_dsub                              @ result<- op, r0-r3 changed
5321    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5322    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5323    GOTO_OPCODE(ip)                     @ jump to next instruction
5324    /* 14-17 instructions */
5325
5326
5327/* ------------------------------ */
5328    .balign 64
5329.L_OP_MUL_DOUBLE: /* 0xad */
5330/* File: armv5te/OP_MUL_DOUBLE.S */
5331/* File: armv5te/binopWide.S */
5332    /*
5333     * Generic 64-bit binary operation.  Provide an "instr" line that
5334     * specifies an instruction that performs "result = r0-r1 op r2-r3".
5335     * This could be an ARM instruction or a function call.  (If the result
5336     * comes back in a register other than r0, you can override "result".)
5337     *
5338     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5339     * vCC (r1).  Useful for integer division and modulus.
5340     *
5341     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
5342     *      xor-long, add-double, sub-double, mul-double, div-double,
5343     *      rem-double
5344     *
5345     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
5346     */
5347    /* binop vAA, vBB, vCC */
5348    FETCH(r0, 1)                        @ r0<- CCBB
5349    mov     r9, rINST, lsr #8           @ r9<- AA
5350    and     r2, r0, #255                @ r2<- BB
5351    mov     r3, r0, lsr #8              @ r3<- CC
5352    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5353    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
5354    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
5355    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5356    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
5357    .if 0
5358    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5359    beq     common_errDivideByZero
5360    .endif
5361    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5362
5363                               @ optional op; may set condition codes
5364    bl      __aeabi_dmul                              @ result<- op, r0-r3 changed
5365    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5366    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5367    GOTO_OPCODE(ip)                     @ jump to next instruction
5368    /* 14-17 instructions */
5369
5370
5371/* ------------------------------ */
5372    .balign 64
5373.L_OP_DIV_DOUBLE: /* 0xae */
5374/* File: armv5te/OP_DIV_DOUBLE.S */
5375/* File: armv5te/binopWide.S */
5376    /*
5377     * Generic 64-bit binary operation.  Provide an "instr" line that
5378     * specifies an instruction that performs "result = r0-r1 op r2-r3".
5379     * This could be an ARM instruction or a function call.  (If the result
5380     * comes back in a register other than r0, you can override "result".)
5381     *
5382     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5383     * vCC (r1).  Useful for integer division and modulus.
5384     *
5385     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
5386     *      xor-long, add-double, sub-double, mul-double, div-double,
5387     *      rem-double
5388     *
5389     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
5390     */
5391    /* binop vAA, vBB, vCC */
5392    FETCH(r0, 1)                        @ r0<- CCBB
5393    mov     r9, rINST, lsr #8           @ r9<- AA
5394    and     r2, r0, #255                @ r2<- BB
5395    mov     r3, r0, lsr #8              @ r3<- CC
5396    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5397    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
5398    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
5399    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5400    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
5401    .if 0
5402    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5403    beq     common_errDivideByZero
5404    .endif
5405    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5406
5407                               @ optional op; may set condition codes
5408    bl      __aeabi_ddiv                              @ result<- op, r0-r3 changed
5409    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5410    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5411    GOTO_OPCODE(ip)                     @ jump to next instruction
5412    /* 14-17 instructions */
5413
5414
5415/* ------------------------------ */
5416    .balign 64
5417.L_OP_REM_DOUBLE: /* 0xaf */
5418/* File: armv5te/OP_REM_DOUBLE.S */
5419/* EABI doesn't define a double remainder function, but libm does */
5420/* File: armv5te/binopWide.S */
5421    /*
5422     * Generic 64-bit binary operation.  Provide an "instr" line that
5423     * specifies an instruction that performs "result = r0-r1 op r2-r3".
5424     * This could be an ARM instruction or a function call.  (If the result
5425     * comes back in a register other than r0, you can override "result".)
5426     *
5427     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5428     * vCC (r1).  Useful for integer division and modulus.
5429     *
5430     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
5431     *      xor-long, add-double, sub-double, mul-double, div-double,
5432     *      rem-double
5433     *
5434     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
5435     */
5436    /* binop vAA, vBB, vCC */
5437    FETCH(r0, 1)                        @ r0<- CCBB
5438    mov     r9, rINST, lsr #8           @ r9<- AA
5439    and     r2, r0, #255                @ r2<- BB
5440    mov     r3, r0, lsr #8              @ r3<- CC
5441    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5442    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
5443    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
5444    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5445    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
5446    .if 0
5447    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5448    beq     common_errDivideByZero
5449    .endif
5450    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5451
5452                               @ optional op; may set condition codes
5453    bl      fmod                              @ result<- op, r0-r3 changed
5454    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5455    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5456    GOTO_OPCODE(ip)                     @ jump to next instruction
5457    /* 14-17 instructions */
5458
5459
5460/* ------------------------------ */
5461    .balign 64
5462.L_OP_ADD_INT_2ADDR: /* 0xb0 */
5463/* File: armv5te/OP_ADD_INT_2ADDR.S */
5464/* File: armv5te/binop2addr.S */
5465    /*
5466     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5467     * that specifies an instruction that performs "result = r0 op r1".
5468     * This could be an ARM instruction or a function call.  (If the result
5469     * comes back in a register other than r0, you can override "result".)
5470     *
5471     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5472     * vCC (r1).  Useful for integer division and modulus.
5473     *
5474     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5475     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5476     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5477     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5478     */
5479    /* binop/2addr vA, vB */
5480    mov     r9, rINST, lsr #8           @ r9<- A+
5481    mov     r3, rINST, lsr #12          @ r3<- B
5482    and     r9, r9, #15
5483    GET_VREG(r1, r3)                    @ r1<- vB
5484    GET_VREG(r0, r9)                    @ r0<- vA
5485    .if 0
5486    cmp     r1, #0                      @ is second operand zero?
5487    beq     common_errDivideByZero
5488    .endif
5489    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5490
5491                               @ optional op; may set condition codes
5492    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
5493    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5494    SET_VREG(r0, r9)               @ vAA<- r0
5495    GOTO_OPCODE(ip)                     @ jump to next instruction
5496    /* 10-13 instructions */
5497
5498
5499/* ------------------------------ */
5500    .balign 64
5501.L_OP_SUB_INT_2ADDR: /* 0xb1 */
5502/* File: armv5te/OP_SUB_INT_2ADDR.S */
5503/* File: armv5te/binop2addr.S */
5504    /*
5505     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5506     * that specifies an instruction that performs "result = r0 op r1".
5507     * This could be an ARM instruction or a function call.  (If the result
5508     * comes back in a register other than r0, you can override "result".)
5509     *
5510     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5511     * vCC (r1).  Useful for integer division and modulus.
5512     *
5513     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5514     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5515     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5516     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5517     */
5518    /* binop/2addr vA, vB */
5519    mov     r9, rINST, lsr #8           @ r9<- A+
5520    mov     r3, rINST, lsr #12          @ r3<- B
5521    and     r9, r9, #15
5522    GET_VREG(r1, r3)                    @ r1<- vB
5523    GET_VREG(r0, r9)                    @ r0<- vA
5524    .if 0
5525    cmp     r1, #0                      @ is second operand zero?
5526    beq     common_errDivideByZero
5527    .endif
5528    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5529
5530                               @ optional op; may set condition codes
5531    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
5532    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5533    SET_VREG(r0, r9)               @ vAA<- r0
5534    GOTO_OPCODE(ip)                     @ jump to next instruction
5535    /* 10-13 instructions */
5536
5537
5538/* ------------------------------ */
5539    .balign 64
5540.L_OP_MUL_INT_2ADDR: /* 0xb2 */
5541/* File: armv5te/OP_MUL_INT_2ADDR.S */
5542/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
5543/* File: armv5te/binop2addr.S */
5544    /*
5545     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5546     * that specifies an instruction that performs "result = r0 op r1".
5547     * This could be an ARM instruction or a function call.  (If the result
5548     * comes back in a register other than r0, you can override "result".)
5549     *
5550     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5551     * vCC (r1).  Useful for integer division and modulus.
5552     *
5553     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5554     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5555     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5556     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5557     */
5558    /* binop/2addr vA, vB */
5559    mov     r9, rINST, lsr #8           @ r9<- A+
5560    mov     r3, rINST, lsr #12          @ r3<- B
5561    and     r9, r9, #15
5562    GET_VREG(r1, r3)                    @ r1<- vB
5563    GET_VREG(r0, r9)                    @ r0<- vA
5564    .if 0
5565    cmp     r1, #0                      @ is second operand zero?
5566    beq     common_errDivideByZero
5567    .endif
5568    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5569
5570                               @ optional op; may set condition codes
5571    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
5572    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5573    SET_VREG(r0, r9)               @ vAA<- r0
5574    GOTO_OPCODE(ip)                     @ jump to next instruction
5575    /* 10-13 instructions */
5576
5577
5578/* ------------------------------ */
5579    .balign 64
5580.L_OP_DIV_INT_2ADDR: /* 0xb3 */
5581/* File: armv5te/OP_DIV_INT_2ADDR.S */
5582/* File: armv5te/binop2addr.S */
5583    /*
5584     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5585     * that specifies an instruction that performs "result = r0 op r1".
5586     * This could be an ARM instruction or a function call.  (If the result
5587     * comes back in a register other than r0, you can override "result".)
5588     *
5589     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5590     * vCC (r1).  Useful for integer division and modulus.
5591     *
5592     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5593     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5594     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5595     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5596     */
5597    /* binop/2addr vA, vB */
5598    mov     r9, rINST, lsr #8           @ r9<- A+
5599    mov     r3, rINST, lsr #12          @ r3<- B
5600    and     r9, r9, #15
5601    GET_VREG(r1, r3)                    @ r1<- vB
5602    GET_VREG(r0, r9)                    @ r0<- vA
5603    .if 1
5604    cmp     r1, #0                      @ is second operand zero?
5605    beq     common_errDivideByZero
5606    .endif
5607    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5608
5609                               @ optional op; may set condition codes
5610    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
5611    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5612    SET_VREG(r0, r9)               @ vAA<- r0
5613    GOTO_OPCODE(ip)                     @ jump to next instruction
5614    /* 10-13 instructions */
5615
5616
5617/* ------------------------------ */
5618    .balign 64
5619.L_OP_REM_INT_2ADDR: /* 0xb4 */
5620/* File: armv5te/OP_REM_INT_2ADDR.S */
5621/* idivmod returns quotient in r0 and remainder in r1 */
5622/* File: armv5te/binop2addr.S */
5623    /*
5624     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5625     * that specifies an instruction that performs "result = r0 op r1".
5626     * This could be an ARM instruction or a function call.  (If the result
5627     * comes back in a register other than r0, you can override "result".)
5628     *
5629     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5630     * vCC (r1).  Useful for integer division and modulus.
5631     *
5632     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5633     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5634     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5635     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5636     */
5637    /* binop/2addr vA, vB */
5638    mov     r9, rINST, lsr #8           @ r9<- A+
5639    mov     r3, rINST, lsr #12          @ r3<- B
5640    and     r9, r9, #15
5641    GET_VREG(r1, r3)                    @ r1<- vB
5642    GET_VREG(r0, r9)                    @ r0<- vA
5643    .if 1
5644    cmp     r1, #0                      @ is second operand zero?
5645    beq     common_errDivideByZero
5646    .endif
5647    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5648
5649                               @ optional op; may set condition codes
5650    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
5651    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5652    SET_VREG(r1, r9)               @ vAA<- r1
5653    GOTO_OPCODE(ip)                     @ jump to next instruction
5654    /* 10-13 instructions */
5655
5656
5657/* ------------------------------ */
5658    .balign 64
5659.L_OP_AND_INT_2ADDR: /* 0xb5 */
5660/* File: armv5te/OP_AND_INT_2ADDR.S */
5661/* File: armv5te/binop2addr.S */
5662    /*
5663     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5664     * that specifies an instruction that performs "result = r0 op r1".
5665     * This could be an ARM instruction or a function call.  (If the result
5666     * comes back in a register other than r0, you can override "result".)
5667     *
5668     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5669     * vCC (r1).  Useful for integer division and modulus.
5670     *
5671     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5672     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5673     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5674     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5675     */
5676    /* binop/2addr vA, vB */
5677    mov     r9, rINST, lsr #8           @ r9<- A+
5678    mov     r3, rINST, lsr #12          @ r3<- B
5679    and     r9, r9, #15
5680    GET_VREG(r1, r3)                    @ r1<- vB
5681    GET_VREG(r0, r9)                    @ r0<- vA
5682    .if 0
5683    cmp     r1, #0                      @ is second operand zero?
5684    beq     common_errDivideByZero
5685    .endif
5686    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5687
5688                               @ optional op; may set condition codes
5689    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
5690    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5691    SET_VREG(r0, r9)               @ vAA<- r0
5692    GOTO_OPCODE(ip)                     @ jump to next instruction
5693    /* 10-13 instructions */
5694
5695
5696/* ------------------------------ */
5697    .balign 64
5698.L_OP_OR_INT_2ADDR: /* 0xb6 */
5699/* File: armv5te/OP_OR_INT_2ADDR.S */
5700/* File: armv5te/binop2addr.S */
5701    /*
5702     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5703     * that specifies an instruction that performs "result = r0 op r1".
5704     * This could be an ARM instruction or a function call.  (If the result
5705     * comes back in a register other than r0, you can override "result".)
5706     *
5707     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5708     * vCC (r1).  Useful for integer division and modulus.
5709     *
5710     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5711     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5712     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5713     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5714     */
5715    /* binop/2addr vA, vB */
5716    mov     r9, rINST, lsr #8           @ r9<- A+
5717    mov     r3, rINST, lsr #12          @ r3<- B
5718    and     r9, r9, #15
5719    GET_VREG(r1, r3)                    @ r1<- vB
5720    GET_VREG(r0, r9)                    @ r0<- vA
5721    .if 0
5722    cmp     r1, #0                      @ is second operand zero?
5723    beq     common_errDivideByZero
5724    .endif
5725    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5726
5727                               @ optional op; may set condition codes
5728    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
5729    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5730    SET_VREG(r0, r9)               @ vAA<- r0
5731    GOTO_OPCODE(ip)                     @ jump to next instruction
5732    /* 10-13 instructions */
5733
5734
5735/* ------------------------------ */
5736    .balign 64
5737.L_OP_XOR_INT_2ADDR: /* 0xb7 */
5738/* File: armv5te/OP_XOR_INT_2ADDR.S */
5739/* File: armv5te/binop2addr.S */
5740    /*
5741     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5742     * that specifies an instruction that performs "result = r0 op r1".
5743     * This could be an ARM instruction or a function call.  (If the result
5744     * comes back in a register other than r0, you can override "result".)
5745     *
5746     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5747     * vCC (r1).  Useful for integer division and modulus.
5748     *
5749     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5750     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5751     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5752     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5753     */
5754    /* binop/2addr vA, vB */
5755    mov     r9, rINST, lsr #8           @ r9<- A+
5756    mov     r3, rINST, lsr #12          @ r3<- B
5757    and     r9, r9, #15
5758    GET_VREG(r1, r3)                    @ r1<- vB
5759    GET_VREG(r0, r9)                    @ r0<- vA
5760    .if 0
5761    cmp     r1, #0                      @ is second operand zero?
5762    beq     common_errDivideByZero
5763    .endif
5764    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5765
5766                               @ optional op; may set condition codes
5767    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
5768    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5769    SET_VREG(r0, r9)               @ vAA<- r0
5770    GOTO_OPCODE(ip)                     @ jump to next instruction
5771    /* 10-13 instructions */
5772
5773
5774/* ------------------------------ */
5775    .balign 64
5776.L_OP_SHL_INT_2ADDR: /* 0xb8 */
5777/* File: armv5te/OP_SHL_INT_2ADDR.S */
5778/* File: armv5te/binop2addr.S */
5779    /*
5780     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5781     * that specifies an instruction that performs "result = r0 op r1".
5782     * This could be an ARM instruction or a function call.  (If the result
5783     * comes back in a register other than r0, you can override "result".)
5784     *
5785     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5786     * vCC (r1).  Useful for integer division and modulus.
5787     *
5788     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5789     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5790     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5791     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5792     */
5793    /* binop/2addr vA, vB */
5794    mov     r9, rINST, lsr #8           @ r9<- A+
5795    mov     r3, rINST, lsr #12          @ r3<- B
5796    and     r9, r9, #15
5797    GET_VREG(r1, r3)                    @ r1<- vB
5798    GET_VREG(r0, r9)                    @ r0<- vA
5799    .if 0
5800    cmp     r1, #0                      @ is second operand zero?
5801    beq     common_errDivideByZero
5802    .endif
5803    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5804
5805    and     r1, r1, #31                           @ optional op; may set condition codes
5806    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
5807    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5808    SET_VREG(r0, r9)               @ vAA<- r0
5809    GOTO_OPCODE(ip)                     @ jump to next instruction
5810    /* 10-13 instructions */
5811
5812
5813/* ------------------------------ */
5814    .balign 64
5815.L_OP_SHR_INT_2ADDR: /* 0xb9 */
5816/* File: armv5te/OP_SHR_INT_2ADDR.S */
5817/* File: armv5te/binop2addr.S */
5818    /*
5819     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5820     * that specifies an instruction that performs "result = r0 op r1".
5821     * This could be an ARM instruction or a function call.  (If the result
5822     * comes back in a register other than r0, you can override "result".)
5823     *
5824     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5825     * vCC (r1).  Useful for integer division and modulus.
5826     *
5827     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5828     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5829     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5830     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5831     */
5832    /* binop/2addr vA, vB */
5833    mov     r9, rINST, lsr #8           @ r9<- A+
5834    mov     r3, rINST, lsr #12          @ r3<- B
5835    and     r9, r9, #15
5836    GET_VREG(r1, r3)                    @ r1<- vB
5837    GET_VREG(r0, r9)                    @ r0<- vA
5838    .if 0
5839    cmp     r1, #0                      @ is second operand zero?
5840    beq     common_errDivideByZero
5841    .endif
5842    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5843
5844    and     r1, r1, #31                           @ optional op; may set condition codes
5845    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
5846    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5847    SET_VREG(r0, r9)               @ vAA<- r0
5848    GOTO_OPCODE(ip)                     @ jump to next instruction
5849    /* 10-13 instructions */
5850
5851
5852/* ------------------------------ */
5853    .balign 64
5854.L_OP_USHR_INT_2ADDR: /* 0xba */
5855/* File: armv5te/OP_USHR_INT_2ADDR.S */
5856/* File: armv5te/binop2addr.S */
5857    /*
5858     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5859     * that specifies an instruction that performs "result = r0 op r1".
5860     * This could be an ARM instruction or a function call.  (If the result
5861     * comes back in a register other than r0, you can override "result".)
5862     *
5863     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5864     * vCC (r1).  Useful for integer division and modulus.
5865     *
5866     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5867     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5868     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5869     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5870     */
5871    /* binop/2addr vA, vB */
5872    mov     r9, rINST, lsr #8           @ r9<- A+
5873    mov     r3, rINST, lsr #12          @ r3<- B
5874    and     r9, r9, #15
5875    GET_VREG(r1, r3)                    @ r1<- vB
5876    GET_VREG(r0, r9)                    @ r0<- vA
5877    .if 0
5878    cmp     r1, #0                      @ is second operand zero?
5879    beq     common_errDivideByZero
5880    .endif
5881    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5882
5883    and     r1, r1, #31                           @ optional op; may set condition codes
5884    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
5885    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5886    SET_VREG(r0, r9)               @ vAA<- r0
5887    GOTO_OPCODE(ip)                     @ jump to next instruction
5888    /* 10-13 instructions */
5889
5890
5891/* ------------------------------ */
5892    .balign 64
5893.L_OP_ADD_LONG_2ADDR: /* 0xbb */
5894/* File: armv5te/OP_ADD_LONG_2ADDR.S */
5895/* File: armv5te/binopWide2addr.S */
5896    /*
5897     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5898     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5899     * This could be an ARM instruction or a function call.  (If the result
5900     * comes back in a register other than r0, you can override "result".)
5901     *
5902     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5903     * vCC (r1).  Useful for integer division and modulus.
5904     *
5905     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5906     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5907     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5908     *      rem-double/2addr
5909     */
5910    /* binop/2addr vA, vB */
5911    mov     r9, rINST, lsr #8           @ r9<- A+
5912    mov     r1, rINST, lsr #12          @ r1<- B
5913    and     r9, r9, #15
5914    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5915    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5916    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5917    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5918    .if 0
5919    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5920    beq     common_errDivideByZero
5921    .endif
5922    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5923
5924    adds    r0, r0, r2                           @ optional op; may set condition codes
5925    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
5926    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5927    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5928    GOTO_OPCODE(ip)                     @ jump to next instruction
5929    /* 12-15 instructions */
5930
5931
5932/* ------------------------------ */
5933    .balign 64
5934.L_OP_SUB_LONG_2ADDR: /* 0xbc */
5935/* File: armv5te/OP_SUB_LONG_2ADDR.S */
5936/* File: armv5te/binopWide2addr.S */
5937    /*
5938     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5939     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5940     * This could be an ARM instruction or a function call.  (If the result
5941     * comes back in a register other than r0, you can override "result".)
5942     *
5943     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5944     * vCC (r1).  Useful for integer division and modulus.
5945     *
5946     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5947     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5948     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5949     *      rem-double/2addr
5950     */
5951    /* binop/2addr vA, vB */
5952    mov     r9, rINST, lsr #8           @ r9<- A+
5953    mov     r1, rINST, lsr #12          @ r1<- B
5954    and     r9, r9, #15
5955    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5956    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5957    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5958    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5959    .if 0
5960    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5961    beq     common_errDivideByZero
5962    .endif
5963    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5964
5965    subs    r0, r0, r2                           @ optional op; may set condition codes
5966    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
5967    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5968    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5969    GOTO_OPCODE(ip)                     @ jump to next instruction
5970    /* 12-15 instructions */
5971
5972
5973/* ------------------------------ */
5974    .balign 64
5975.L_OP_MUL_LONG_2ADDR: /* 0xbd */
5976/* File: armv5te/OP_MUL_LONG_2ADDR.S */
5977    /*
5978     * Signed 64-bit integer multiply, "/2addr" version.
5979     *
5980     * See OP_MUL_LONG for an explanation.
5981     *
5982     * We get a little tight on registers, so to avoid looking up &fp[A]
5983     * again we stuff it into rINST.
5984     */
5985    /* mul-long/2addr vA, vB */
5986    mov     r9, rINST, lsr #8           @ r9<- A+
5987    mov     r1, rINST, lsr #12          @ r1<- B
5988    and     r9, r9, #15
5989    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5990    add     rINST, rFP, r9, lsl #2      @ rINST<- &fp[A]
5991    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5992    ldmia   rINST, {r0-r1}              @ r0/r1<- vAA/vAA+1
5993    mul     ip, r2, r1                  @  ip<- ZxW
5994    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
5995    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
5996    mov     r0, rINST                   @ r0<- &fp[A] (free up rINST)
5997    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5998    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
5999    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6000    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
6001    GOTO_OPCODE(ip)                     @ jump to next instruction
6002
6003/* ------------------------------ */
6004    .balign 64
6005.L_OP_DIV_LONG_2ADDR: /* 0xbe */
6006/* File: armv5te/OP_DIV_LONG_2ADDR.S */
6007/* File: armv5te/binopWide2addr.S */
6008    /*
6009     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6010     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6011     * This could be an ARM instruction or a function call.  (If the result
6012     * comes back in a register other than r0, you can override "result".)
6013     *
6014     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6015     * vCC (r1).  Useful for integer division and modulus.
6016     *
6017     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6018     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6019     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6020     *      rem-double/2addr
6021     */
6022    /* binop/2addr vA, vB */
6023    mov     r9, rINST, lsr #8           @ r9<- A+
6024    mov     r1, rINST, lsr #12          @ r1<- B
6025    and     r9, r9, #15
6026    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6027    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6028    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6029    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6030    .if 1
6031    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6032    beq     common_errDivideByZero
6033    .endif
6034    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6035
6036                               @ optional op; may set condition codes
6037    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
6038    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6039    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6040    GOTO_OPCODE(ip)                     @ jump to next instruction
6041    /* 12-15 instructions */
6042
6043
6044/* ------------------------------ */
6045    .balign 64
6046.L_OP_REM_LONG_2ADDR: /* 0xbf */
6047/* File: armv5te/OP_REM_LONG_2ADDR.S */
6048/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
6049/* File: armv5te/binopWide2addr.S */
6050    /*
6051     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6052     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6053     * This could be an ARM instruction or a function call.  (If the result
6054     * comes back in a register other than r0, you can override "result".)
6055     *
6056     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6057     * vCC (r1).  Useful for integer division and modulus.
6058     *
6059     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6060     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6061     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6062     *      rem-double/2addr
6063     */
6064    /* binop/2addr vA, vB */
6065    mov     r9, rINST, lsr #8           @ r9<- A+
6066    mov     r1, rINST, lsr #12          @ r1<- B
6067    and     r9, r9, #15
6068    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6069    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6070    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6071    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6072    .if 1
6073    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6074    beq     common_errDivideByZero
6075    .endif
6076    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6077
6078                               @ optional op; may set condition codes
6079    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
6080    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6081    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
6082    GOTO_OPCODE(ip)                     @ jump to next instruction
6083    /* 12-15 instructions */
6084
6085
6086/* ------------------------------ */
6087    .balign 64
6088.L_OP_AND_LONG_2ADDR: /* 0xc0 */
6089/* File: armv5te/OP_AND_LONG_2ADDR.S */
6090/* File: armv5te/binopWide2addr.S */
6091    /*
6092     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6093     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6094     * This could be an ARM instruction or a function call.  (If the result
6095     * comes back in a register other than r0, you can override "result".)
6096     *
6097     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6098     * vCC (r1).  Useful for integer division and modulus.
6099     *
6100     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6101     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6102     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6103     *      rem-double/2addr
6104     */
6105    /* binop/2addr vA, vB */
6106    mov     r9, rINST, lsr #8           @ r9<- A+
6107    mov     r1, rINST, lsr #12          @ r1<- B
6108    and     r9, r9, #15
6109    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6110    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6111    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6112    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6113    .if 0
6114    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6115    beq     common_errDivideByZero
6116    .endif
6117    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6118
6119    and     r0, r0, r2                           @ optional op; may set condition codes
6120    and     r1, r1, r3                              @ result<- op, r0-r3 changed
6121    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6122    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6123    GOTO_OPCODE(ip)                     @ jump to next instruction
6124    /* 12-15 instructions */
6125
6126
6127/* ------------------------------ */
6128    .balign 64
6129.L_OP_OR_LONG_2ADDR: /* 0xc1 */
6130/* File: armv5te/OP_OR_LONG_2ADDR.S */
6131/* File: armv5te/binopWide2addr.S */
6132    /*
6133     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6134     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6135     * This could be an ARM instruction or a function call.  (If the result
6136     * comes back in a register other than r0, you can override "result".)
6137     *
6138     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6139     * vCC (r1).  Useful for integer division and modulus.
6140     *
6141     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6142     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6143     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6144     *      rem-double/2addr
6145     */
6146    /* binop/2addr vA, vB */
6147    mov     r9, rINST, lsr #8           @ r9<- A+
6148    mov     r1, rINST, lsr #12          @ r1<- B
6149    and     r9, r9, #15
6150    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6151    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6152    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6153    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6154    .if 0
6155    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6156    beq     common_errDivideByZero
6157    .endif
6158    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6159
6160    orr     r0, r0, r2                           @ optional op; may set condition codes
6161    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
6162    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6163    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6164    GOTO_OPCODE(ip)                     @ jump to next instruction
6165    /* 12-15 instructions */
6166
6167
6168/* ------------------------------ */
6169    .balign 64
6170.L_OP_XOR_LONG_2ADDR: /* 0xc2 */
6171/* File: armv5te/OP_XOR_LONG_2ADDR.S */
6172/* File: armv5te/binopWide2addr.S */
6173    /*
6174     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6175     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6176     * This could be an ARM instruction or a function call.  (If the result
6177     * comes back in a register other than r0, you can override "result".)
6178     *
6179     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6180     * vCC (r1).  Useful for integer division and modulus.
6181     *
6182     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6183     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6184     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6185     *      rem-double/2addr
6186     */
6187    /* binop/2addr vA, vB */
6188    mov     r9, rINST, lsr #8           @ r9<- A+
6189    mov     r1, rINST, lsr #12          @ r1<- B
6190    and     r9, r9, #15
6191    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6192    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6193    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6194    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6195    .if 0
6196    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6197    beq     common_errDivideByZero
6198    .endif
6199    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6200
6201    eor     r0, r0, r2                           @ optional op; may set condition codes
6202    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
6203    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6204    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6205    GOTO_OPCODE(ip)                     @ jump to next instruction
6206    /* 12-15 instructions */
6207
6208
6209/* ------------------------------ */
6210    .balign 64
6211.L_OP_SHL_LONG_2ADDR: /* 0xc3 */
6212/* File: armv5te/OP_SHL_LONG_2ADDR.S */
6213    /*
6214     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6215     * 32-bit shift distance.
6216     */
6217    /* shl-long/2addr vA, vB */
6218    mov     r9, rINST, lsr #8           @ r9<- A+
6219    mov     r3, rINST, lsr #12          @ r3<- B
6220    and     r9, r9, #15
6221    GET_VREG(r2, r3)                    @ r2<- vB
6222    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6223    and     r2, r2, #63                 @ r2<- r2 & 0x3f
6224    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6225
6226    mov     r1, r1, asl r2              @  r1<- r1 << r2
6227    rsb     r3, r2, #32                 @  r3<- 32 - r2
6228    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
6229    subs    ip, r2, #32                 @  ip<- r2 - 32
6230    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6231    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
6232    mov     r0, r0, asl r2              @  r0<- r0 << r2
6233    b       .LOP_SHL_LONG_2ADDR_finish
6234
6235/* ------------------------------ */
6236    .balign 64
6237.L_OP_SHR_LONG_2ADDR: /* 0xc4 */
6238/* File: armv5te/OP_SHR_LONG_2ADDR.S */
6239    /*
6240     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6241     * 32-bit shift distance.
6242     */
6243    /* shr-long/2addr vA, vB */
6244    mov     r9, rINST, lsr #8           @ r9<- A+
6245    mov     r3, rINST, lsr #12          @ r3<- B
6246    and     r9, r9, #15
6247    GET_VREG(r2, r3)                    @ r2<- vB
6248    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6249    and     r2, r2, #63                 @ r2<- r2 & 0x3f
6250    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6251
6252    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
6253    rsb     r3, r2, #32                 @  r3<- 32 - r2
6254    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
6255    subs    ip, r2, #32                 @  ip<- r2 - 32
6256    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6257    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
6258    mov     r1, r1, asr r2              @  r1<- r1 >> r2
6259    b       .LOP_SHR_LONG_2ADDR_finish
6260
6261/* ------------------------------ */
6262    .balign 64
6263.L_OP_USHR_LONG_2ADDR: /* 0xc5 */
6264/* File: armv5te/OP_USHR_LONG_2ADDR.S */
6265    /*
6266     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6267     * 32-bit shift distance.
6268     */
6269    /* ushr-long/2addr vA, vB */
6270    mov     r9, rINST, lsr #8           @ r9<- A+
6271    mov     r3, rINST, lsr #12          @ r3<- B
6272    and     r9, r9, #15
6273    GET_VREG(r2, r3)                    @ r2<- vB
6274    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6275    and     r2, r2, #63                 @ r2<- r2 & 0x3f
6276    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6277
6278    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
6279    rsb     r3, r2, #32                 @  r3<- 32 - r2
6280    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
6281    subs    ip, r2, #32                 @  ip<- r2 - 32
6282    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6283    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
6284    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
6285    b       .LOP_USHR_LONG_2ADDR_finish
6286
6287/* ------------------------------ */
6288    .balign 64
6289.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
6290/* File: armv5te/OP_ADD_FLOAT_2ADDR.S */
6291/* File: armv5te/binop2addr.S */
6292    /*
6293     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6294     * that specifies an instruction that performs "result = r0 op r1".
6295     * This could be an ARM instruction or a function call.  (If the result
6296     * comes back in a register other than r0, you can override "result".)
6297     *
6298     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6299     * vCC (r1).  Useful for integer division and modulus.
6300     *
6301     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6302     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6303     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6304     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6305     */
6306    /* binop/2addr vA, vB */
6307    mov     r9, rINST, lsr #8           @ r9<- A+
6308    mov     r3, rINST, lsr #12          @ r3<- B
6309    and     r9, r9, #15
6310    GET_VREG(r1, r3)                    @ r1<- vB
6311    GET_VREG(r0, r9)                    @ r0<- vA
6312    .if 0
6313    cmp     r1, #0                      @ is second operand zero?
6314    beq     common_errDivideByZero
6315    .endif
6316    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6317
6318                               @ optional op; may set condition codes
6319    bl      __aeabi_fadd                              @ r0<- op, r0-r3 changed
6320    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6321    SET_VREG(r0, r9)               @ vAA<- r0
6322    GOTO_OPCODE(ip)                     @ jump to next instruction
6323    /* 10-13 instructions */
6324
6325
6326/* ------------------------------ */
6327    .balign 64
6328.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
6329/* File: armv5te/OP_SUB_FLOAT_2ADDR.S */
6330/* File: armv5te/binop2addr.S */
6331    /*
6332     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6333     * that specifies an instruction that performs "result = r0 op r1".
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-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6341     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6342     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6343     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6344     */
6345    /* binop/2addr vA, vB */
6346    mov     r9, rINST, lsr #8           @ r9<- A+
6347    mov     r3, rINST, lsr #12          @ r3<- B
6348    and     r9, r9, #15
6349    GET_VREG(r1, r3)                    @ r1<- vB
6350    GET_VREG(r0, r9)                    @ r0<- vA
6351    .if 0
6352    cmp     r1, #0                      @ is second operand zero?
6353    beq     common_errDivideByZero
6354    .endif
6355    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6356
6357                               @ optional op; may set condition codes
6358    bl      __aeabi_fsub                              @ r0<- op, r0-r3 changed
6359    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6360    SET_VREG(r0, r9)               @ vAA<- r0
6361    GOTO_OPCODE(ip)                     @ jump to next instruction
6362    /* 10-13 instructions */
6363
6364
6365/* ------------------------------ */
6366    .balign 64
6367.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
6368/* File: armv5te/OP_MUL_FLOAT_2ADDR.S */
6369/* File: armv5te/binop2addr.S */
6370    /*
6371     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6372     * that specifies an instruction that performs "result = r0 op r1".
6373     * This could be an ARM instruction or a function call.  (If the result
6374     * comes back in a register other than r0, you can override "result".)
6375     *
6376     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6377     * vCC (r1).  Useful for integer division and modulus.
6378     *
6379     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6380     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6381     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6382     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6383     */
6384    /* binop/2addr vA, vB */
6385    mov     r9, rINST, lsr #8           @ r9<- A+
6386    mov     r3, rINST, lsr #12          @ r3<- B
6387    and     r9, r9, #15
6388    GET_VREG(r1, r3)                    @ r1<- vB
6389    GET_VREG(r0, r9)                    @ r0<- vA
6390    .if 0
6391    cmp     r1, #0                      @ is second operand zero?
6392    beq     common_errDivideByZero
6393    .endif
6394    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6395
6396                               @ optional op; may set condition codes
6397    bl      __aeabi_fmul                              @ r0<- op, r0-r3 changed
6398    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6399    SET_VREG(r0, r9)               @ vAA<- r0
6400    GOTO_OPCODE(ip)                     @ jump to next instruction
6401    /* 10-13 instructions */
6402
6403
6404/* ------------------------------ */
6405    .balign 64
6406.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
6407/* File: armv5te/OP_DIV_FLOAT_2ADDR.S */
6408/* File: armv5te/binop2addr.S */
6409    /*
6410     * Generic 32-bit "/2addr" 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/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6419     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6420     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6421     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6422     */
6423    /* binop/2addr vA, vB */
6424    mov     r9, rINST, lsr #8           @ r9<- A+
6425    mov     r3, rINST, lsr #12          @ r3<- B
6426    and     r9, r9, #15
6427    GET_VREG(r1, r3)                    @ r1<- vB
6428    GET_VREG(r0, r9)                    @ r0<- vA
6429    .if 0
6430    cmp     r1, #0                      @ is second operand zero?
6431    beq     common_errDivideByZero
6432    .endif
6433    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6434
6435                               @ optional op; may set condition codes
6436    bl      __aeabi_fdiv                              @ r0<- op, r0-r3 changed
6437    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6438    SET_VREG(r0, r9)               @ vAA<- r0
6439    GOTO_OPCODE(ip)                     @ jump to next instruction
6440    /* 10-13 instructions */
6441
6442
6443/* ------------------------------ */
6444    .balign 64
6445.L_OP_REM_FLOAT_2ADDR: /* 0xca */
6446/* File: armv5te/OP_REM_FLOAT_2ADDR.S */
6447/* EABI doesn't define a float remainder function, but libm does */
6448/* File: armv5te/binop2addr.S */
6449    /*
6450     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6451     * that specifies an instruction that performs "result = r0 op r1".
6452     * This could be an ARM instruction or a function call.  (If the result
6453     * comes back in a register other than r0, you can override "result".)
6454     *
6455     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6456     * vCC (r1).  Useful for integer division and modulus.
6457     *
6458     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6459     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6460     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6461     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6462     */
6463    /* binop/2addr vA, vB */
6464    mov     r9, rINST, lsr #8           @ r9<- A+
6465    mov     r3, rINST, lsr #12          @ r3<- B
6466    and     r9, r9, #15
6467    GET_VREG(r1, r3)                    @ r1<- vB
6468    GET_VREG(r0, r9)                    @ r0<- vA
6469    .if 0
6470    cmp     r1, #0                      @ is second operand zero?
6471    beq     common_errDivideByZero
6472    .endif
6473    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6474
6475                               @ optional op; may set condition codes
6476    bl      fmodf                              @ r0<- op, r0-r3 changed
6477    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6478    SET_VREG(r0, r9)               @ vAA<- r0
6479    GOTO_OPCODE(ip)                     @ jump to next instruction
6480    /* 10-13 instructions */
6481
6482
6483/* ------------------------------ */
6484    .balign 64
6485.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
6486/* File: armv5te/OP_ADD_DOUBLE_2ADDR.S */
6487/* File: armv5te/binopWide2addr.S */
6488    /*
6489     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6490     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6491     * This could be an ARM instruction or a function call.  (If the result
6492     * comes back in a register other than r0, you can override "result".)
6493     *
6494     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6495     * vCC (r1).  Useful for integer division and modulus.
6496     *
6497     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6498     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6499     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6500     *      rem-double/2addr
6501     */
6502    /* binop/2addr vA, vB */
6503    mov     r9, rINST, lsr #8           @ r9<- A+
6504    mov     r1, rINST, lsr #12          @ r1<- B
6505    and     r9, r9, #15
6506    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6507    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6508    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6509    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6510    .if 0
6511    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6512    beq     common_errDivideByZero
6513    .endif
6514    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6515
6516                               @ optional op; may set condition codes
6517    bl      __aeabi_dadd                              @ result<- op, r0-r3 changed
6518    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6519    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6520    GOTO_OPCODE(ip)                     @ jump to next instruction
6521    /* 12-15 instructions */
6522
6523
6524/* ------------------------------ */
6525    .balign 64
6526.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
6527/* File: armv5te/OP_SUB_DOUBLE_2ADDR.S */
6528/* File: armv5te/binopWide2addr.S */
6529    /*
6530     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6531     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6532     * This could be an ARM instruction or a function call.  (If the result
6533     * comes back in a register other than r0, you can override "result".)
6534     *
6535     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6536     * vCC (r1).  Useful for integer division and modulus.
6537     *
6538     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6539     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6540     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6541     *      rem-double/2addr
6542     */
6543    /* binop/2addr vA, vB */
6544    mov     r9, rINST, lsr #8           @ r9<- A+
6545    mov     r1, rINST, lsr #12          @ r1<- B
6546    and     r9, r9, #15
6547    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6548    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6549    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6550    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6551    .if 0
6552    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6553    beq     common_errDivideByZero
6554    .endif
6555    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6556
6557                               @ optional op; may set condition codes
6558    bl      __aeabi_dsub                              @ result<- op, r0-r3 changed
6559    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6560    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6561    GOTO_OPCODE(ip)                     @ jump to next instruction
6562    /* 12-15 instructions */
6563
6564
6565/* ------------------------------ */
6566    .balign 64
6567.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
6568/* File: armv5te/OP_MUL_DOUBLE_2ADDR.S */
6569/* File: armv5te/binopWide2addr.S */
6570    /*
6571     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6572     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6573     * This could be an ARM instruction or a function call.  (If the result
6574     * comes back in a register other than r0, you can override "result".)
6575     *
6576     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6577     * vCC (r1).  Useful for integer division and modulus.
6578     *
6579     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6580     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6581     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6582     *      rem-double/2addr
6583     */
6584    /* binop/2addr vA, vB */
6585    mov     r9, rINST, lsr #8           @ r9<- A+
6586    mov     r1, rINST, lsr #12          @ r1<- B
6587    and     r9, r9, #15
6588    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6589    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6590    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6591    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6592    .if 0
6593    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6594    beq     common_errDivideByZero
6595    .endif
6596    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6597
6598                               @ optional op; may set condition codes
6599    bl      __aeabi_dmul                              @ result<- op, r0-r3 changed
6600    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6601    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6602    GOTO_OPCODE(ip)                     @ jump to next instruction
6603    /* 12-15 instructions */
6604
6605
6606/* ------------------------------ */
6607    .balign 64
6608.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */
6609/* File: armv5te/OP_DIV_DOUBLE_2ADDR.S */
6610/* File: armv5te/binopWide2addr.S */
6611    /*
6612     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6613     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6614     * This could be an ARM instruction or a function call.  (If the result
6615     * comes back in a register other than r0, you can override "result".)
6616     *
6617     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6618     * vCC (r1).  Useful for integer division and modulus.
6619     *
6620     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6621     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6622     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6623     *      rem-double/2addr
6624     */
6625    /* binop/2addr vA, vB */
6626    mov     r9, rINST, lsr #8           @ r9<- A+
6627    mov     r1, rINST, lsr #12          @ r1<- B
6628    and     r9, r9, #15
6629    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6630    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6631    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6632    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6633    .if 0
6634    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6635    beq     common_errDivideByZero
6636    .endif
6637    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6638
6639                               @ optional op; may set condition codes
6640    bl      __aeabi_ddiv                              @ result<- op, r0-r3 changed
6641    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6642    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6643    GOTO_OPCODE(ip)                     @ jump to next instruction
6644    /* 12-15 instructions */
6645
6646
6647/* ------------------------------ */
6648    .balign 64
6649.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */
6650/* File: armv5te/OP_REM_DOUBLE_2ADDR.S */
6651/* EABI doesn't define a double remainder function, but libm does */
6652/* File: armv5te/binopWide2addr.S */
6653    /*
6654     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6655     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6656     * This could be an ARM instruction or a function call.  (If the result
6657     * comes back in a register other than r0, you can override "result".)
6658     *
6659     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6660     * vCC (r1).  Useful for integer division and modulus.
6661     *
6662     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6663     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6664     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6665     *      rem-double/2addr
6666     */
6667    /* binop/2addr vA, vB */
6668    mov     r9, rINST, lsr #8           @ r9<- A+
6669    mov     r1, rINST, lsr #12          @ r1<- B
6670    and     r9, r9, #15
6671    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6672    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6673    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6674    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6675    .if 0
6676    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6677    beq     common_errDivideByZero
6678    .endif
6679    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6680
6681                               @ optional op; may set condition codes
6682    bl      fmod                              @ result<- op, r0-r3 changed
6683    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6684    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6685    GOTO_OPCODE(ip)                     @ jump to next instruction
6686    /* 12-15 instructions */
6687
6688
6689/* ------------------------------ */
6690    .balign 64
6691.L_OP_ADD_INT_LIT16: /* 0xd0 */
6692/* File: armv5te/OP_ADD_INT_LIT16.S */
6693/* File: armv5te/binopLit16.S */
6694    /*
6695     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6696     * that specifies an instruction that performs "result = r0 op r1".
6697     * This could be an ARM instruction or a function call.  (If the result
6698     * comes back in a register other than r0, you can override "result".)
6699     *
6700     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6701     * vCC (r1).  Useful for integer division and modulus.
6702     *
6703     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6704     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6705     */
6706    /* binop/lit16 vA, vB, #+CCCC */
6707    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6708    mov     r2, rINST, lsr #12          @ r2<- B
6709    mov     r9, rINST, lsr #8           @ r9<- A+
6710    GET_VREG(r0, r2)                    @ r0<- vB
6711    and     r9, r9, #15
6712    .if 0
6713    cmp     r1, #0                      @ is second operand zero?
6714    beq     common_errDivideByZero
6715    .endif
6716    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6717
6718    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
6719    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6720    SET_VREG(r0, r9)               @ vAA<- r0
6721    GOTO_OPCODE(ip)                     @ jump to next instruction
6722    /* 10-13 instructions */
6723
6724
6725/* ------------------------------ */
6726    .balign 64
6727.L_OP_RSUB_INT: /* 0xd1 */
6728/* File: armv5te/OP_RSUB_INT.S */
6729/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
6730/* File: armv5te/binopLit16.S */
6731    /*
6732     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6733     * that specifies an instruction that performs "result = r0 op r1".
6734     * This could be an ARM instruction or a function call.  (If the result
6735     * comes back in a register other than r0, you can override "result".)
6736     *
6737     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6738     * vCC (r1).  Useful for integer division and modulus.
6739     *
6740     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6741     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6742     */
6743    /* binop/lit16 vA, vB, #+CCCC */
6744    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6745    mov     r2, rINST, lsr #12          @ r2<- B
6746    mov     r9, rINST, lsr #8           @ r9<- A+
6747    GET_VREG(r0, r2)                    @ r0<- vB
6748    and     r9, r9, #15
6749    .if 0
6750    cmp     r1, #0                      @ is second operand zero?
6751    beq     common_errDivideByZero
6752    .endif
6753    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6754
6755    rsb     r0, r0, r1                              @ r0<- op, r0-r3 changed
6756    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6757    SET_VREG(r0, r9)               @ vAA<- r0
6758    GOTO_OPCODE(ip)                     @ jump to next instruction
6759    /* 10-13 instructions */
6760
6761
6762/* ------------------------------ */
6763    .balign 64
6764.L_OP_MUL_INT_LIT16: /* 0xd2 */
6765/* File: armv5te/OP_MUL_INT_LIT16.S */
6766/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
6767/* File: armv5te/binopLit16.S */
6768    /*
6769     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6770     * that specifies an instruction that performs "result = r0 op r1".
6771     * This could be an ARM instruction or a function call.  (If the result
6772     * comes back in a register other than r0, you can override "result".)
6773     *
6774     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6775     * vCC (r1).  Useful for integer division and modulus.
6776     *
6777     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6778     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6779     */
6780    /* binop/lit16 vA, vB, #+CCCC */
6781    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6782    mov     r2, rINST, lsr #12          @ r2<- B
6783    mov     r9, rINST, lsr #8           @ r9<- A+
6784    GET_VREG(r0, r2)                    @ r0<- vB
6785    and     r9, r9, #15
6786    .if 0
6787    cmp     r1, #0                      @ is second operand zero?
6788    beq     common_errDivideByZero
6789    .endif
6790    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6791
6792    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
6793    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6794    SET_VREG(r0, r9)               @ vAA<- r0
6795    GOTO_OPCODE(ip)                     @ jump to next instruction
6796    /* 10-13 instructions */
6797
6798
6799/* ------------------------------ */
6800    .balign 64
6801.L_OP_DIV_INT_LIT16: /* 0xd3 */
6802/* File: armv5te/OP_DIV_INT_LIT16.S */
6803/* File: armv5te/binopLit16.S */
6804    /*
6805     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6806     * that specifies an instruction that performs "result = r0 op r1".
6807     * This could be an ARM instruction or a function call.  (If the result
6808     * comes back in a register other than r0, you can override "result".)
6809     *
6810     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6811     * vCC (r1).  Useful for integer division and modulus.
6812     *
6813     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6814     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6815     */
6816    /* binop/lit16 vA, vB, #+CCCC */
6817    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6818    mov     r2, rINST, lsr #12          @ r2<- B
6819    mov     r9, rINST, lsr #8           @ r9<- A+
6820    GET_VREG(r0, r2)                    @ r0<- vB
6821    and     r9, r9, #15
6822    .if 1
6823    cmp     r1, #0                      @ is second operand zero?
6824    beq     common_errDivideByZero
6825    .endif
6826    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6827
6828    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
6829    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6830    SET_VREG(r0, r9)               @ vAA<- r0
6831    GOTO_OPCODE(ip)                     @ jump to next instruction
6832    /* 10-13 instructions */
6833
6834
6835/* ------------------------------ */
6836    .balign 64
6837.L_OP_REM_INT_LIT16: /* 0xd4 */
6838/* File: armv5te/OP_REM_INT_LIT16.S */
6839/* idivmod returns quotient in r0 and remainder in r1 */
6840/* File: armv5te/binopLit16.S */
6841    /*
6842     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6843     * that specifies an instruction that performs "result = r0 op r1".
6844     * This could be an ARM instruction or a function call.  (If the result
6845     * comes back in a register other than r0, you can override "result".)
6846     *
6847     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6848     * vCC (r1).  Useful for integer division and modulus.
6849     *
6850     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6851     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6852     */
6853    /* binop/lit16 vA, vB, #+CCCC */
6854    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6855    mov     r2, rINST, lsr #12          @ r2<- B
6856    mov     r9, rINST, lsr #8           @ r9<- A+
6857    GET_VREG(r0, r2)                    @ r0<- vB
6858    and     r9, r9, #15
6859    .if 1
6860    cmp     r1, #0                      @ is second operand zero?
6861    beq     common_errDivideByZero
6862    .endif
6863    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6864
6865    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
6866    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6867    SET_VREG(r1, r9)               @ vAA<- r1
6868    GOTO_OPCODE(ip)                     @ jump to next instruction
6869    /* 10-13 instructions */
6870
6871
6872/* ------------------------------ */
6873    .balign 64
6874.L_OP_AND_INT_LIT16: /* 0xd5 */
6875/* File: armv5te/OP_AND_INT_LIT16.S */
6876/* File: armv5te/binopLit16.S */
6877    /*
6878     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6879     * that specifies an instruction that performs "result = r0 op r1".
6880     * This could be an ARM instruction or a function call.  (If the result
6881     * comes back in a register other than r0, you can override "result".)
6882     *
6883     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6884     * vCC (r1).  Useful for integer division and modulus.
6885     *
6886     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6887     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6888     */
6889    /* binop/lit16 vA, vB, #+CCCC */
6890    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6891    mov     r2, rINST, lsr #12          @ r2<- B
6892    mov     r9, rINST, lsr #8           @ r9<- A+
6893    GET_VREG(r0, r2)                    @ r0<- vB
6894    and     r9, r9, #15
6895    .if 0
6896    cmp     r1, #0                      @ is second operand zero?
6897    beq     common_errDivideByZero
6898    .endif
6899    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6900
6901    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
6902    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6903    SET_VREG(r0, r9)               @ vAA<- r0
6904    GOTO_OPCODE(ip)                     @ jump to next instruction
6905    /* 10-13 instructions */
6906
6907
6908/* ------------------------------ */
6909    .balign 64
6910.L_OP_OR_INT_LIT16: /* 0xd6 */
6911/* File: armv5te/OP_OR_INT_LIT16.S */
6912/* File: armv5te/binopLit16.S */
6913    /*
6914     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6915     * that specifies an instruction that performs "result = r0 op r1".
6916     * This could be an ARM instruction or a function call.  (If the result
6917     * comes back in a register other than r0, you can override "result".)
6918     *
6919     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6920     * vCC (r1).  Useful for integer division and modulus.
6921     *
6922     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6923     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6924     */
6925    /* binop/lit16 vA, vB, #+CCCC */
6926    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6927    mov     r2, rINST, lsr #12          @ r2<- B
6928    mov     r9, rINST, lsr #8           @ r9<- A+
6929    GET_VREG(r0, r2)                    @ r0<- vB
6930    and     r9, r9, #15
6931    .if 0
6932    cmp     r1, #0                      @ is second operand zero?
6933    beq     common_errDivideByZero
6934    .endif
6935    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6936
6937    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
6938    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6939    SET_VREG(r0, r9)               @ vAA<- r0
6940    GOTO_OPCODE(ip)                     @ jump to next instruction
6941    /* 10-13 instructions */
6942
6943
6944/* ------------------------------ */
6945    .balign 64
6946.L_OP_XOR_INT_LIT16: /* 0xd7 */
6947/* File: armv5te/OP_XOR_INT_LIT16.S */
6948/* File: armv5te/binopLit16.S */
6949    /*
6950     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6951     * that specifies an instruction that performs "result = r0 op r1".
6952     * This could be an ARM instruction or a function call.  (If the result
6953     * comes back in a register other than r0, you can override "result".)
6954     *
6955     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6956     * vCC (r1).  Useful for integer division and modulus.
6957     *
6958     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6959     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6960     */
6961    /* binop/lit16 vA, vB, #+CCCC */
6962    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6963    mov     r2, rINST, lsr #12          @ r2<- B
6964    mov     r9, rINST, lsr #8           @ r9<- A+
6965    GET_VREG(r0, r2)                    @ r0<- vB
6966    and     r9, r9, #15
6967    .if 0
6968    cmp     r1, #0                      @ is second operand zero?
6969    beq     common_errDivideByZero
6970    .endif
6971    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6972
6973    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
6974    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6975    SET_VREG(r0, r9)               @ vAA<- r0
6976    GOTO_OPCODE(ip)                     @ jump to next instruction
6977    /* 10-13 instructions */
6978
6979
6980/* ------------------------------ */
6981    .balign 64
6982.L_OP_ADD_INT_LIT8: /* 0xd8 */
6983/* File: armv5te/OP_ADD_INT_LIT8.S */
6984/* File: armv5te/binopLit8.S */
6985    /*
6986     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6987     * that specifies an instruction that performs "result = r0 op r1".
6988     * This could be an ARM instruction or a function call.  (If the result
6989     * comes back in a register other than r0, you can override "result".)
6990     *
6991     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6992     * vCC (r1).  Useful for integer division and modulus.
6993     *
6994     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6995     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6996     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6997     */
6998    /* binop/lit8 vAA, vBB, #+CC */
6999    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7000    mov     r9, rINST, lsr #8           @ r9<- AA
7001    and     r2, r3, #255                @ r2<- BB
7002    GET_VREG(r0, r2)                    @ r0<- vBB
7003    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7004    .if 0
7005    @cmp     r1, #0                      @ is second operand zero?
7006    beq     common_errDivideByZero
7007    .endif
7008    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7009
7010                               @ optional op; may set condition codes
7011    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
7012    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7013    SET_VREG(r0, r9)               @ vAA<- r0
7014    GOTO_OPCODE(ip)                     @ jump to next instruction
7015    /* 10-12 instructions */
7016
7017
7018/* ------------------------------ */
7019    .balign 64
7020.L_OP_RSUB_INT_LIT8: /* 0xd9 */
7021/* File: armv5te/OP_RSUB_INT_LIT8.S */
7022/* File: armv5te/binopLit8.S */
7023    /*
7024     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7025     * that specifies an instruction that performs "result = r0 op r1".
7026     * This could be an ARM instruction or a function call.  (If the result
7027     * comes back in a register other than r0, you can override "result".)
7028     *
7029     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7030     * vCC (r1).  Useful for integer division and modulus.
7031     *
7032     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7033     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7034     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7035     */
7036    /* binop/lit8 vAA, vBB, #+CC */
7037    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7038    mov     r9, rINST, lsr #8           @ r9<- AA
7039    and     r2, r3, #255                @ r2<- BB
7040    GET_VREG(r0, r2)                    @ r0<- vBB
7041    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7042    .if 0
7043    @cmp     r1, #0                      @ is second operand zero?
7044    beq     common_errDivideByZero
7045    .endif
7046    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7047
7048                               @ optional op; may set condition codes
7049    rsb     r0, r0, r1                              @ r0<- op, r0-r3 changed
7050    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7051    SET_VREG(r0, r9)               @ vAA<- r0
7052    GOTO_OPCODE(ip)                     @ jump to next instruction
7053    /* 10-12 instructions */
7054
7055
7056/* ------------------------------ */
7057    .balign 64
7058.L_OP_MUL_INT_LIT8: /* 0xda */
7059/* File: armv5te/OP_MUL_INT_LIT8.S */
7060/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
7061/* File: armv5te/binopLit8.S */
7062    /*
7063     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7064     * that specifies an instruction that performs "result = r0 op r1".
7065     * This could be an ARM instruction or a function call.  (If the result
7066     * comes back in a register other than r0, you can override "result".)
7067     *
7068     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7069     * vCC (r1).  Useful for integer division and modulus.
7070     *
7071     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7072     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7073     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7074     */
7075    /* binop/lit8 vAA, vBB, #+CC */
7076    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7077    mov     r9, rINST, lsr #8           @ r9<- AA
7078    and     r2, r3, #255                @ r2<- BB
7079    GET_VREG(r0, r2)                    @ r0<- vBB
7080    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7081    .if 0
7082    @cmp     r1, #0                      @ is second operand zero?
7083    beq     common_errDivideByZero
7084    .endif
7085    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7086
7087                               @ optional op; may set condition codes
7088    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
7089    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7090    SET_VREG(r0, r9)               @ vAA<- r0
7091    GOTO_OPCODE(ip)                     @ jump to next instruction
7092    /* 10-12 instructions */
7093
7094
7095/* ------------------------------ */
7096    .balign 64
7097.L_OP_DIV_INT_LIT8: /* 0xdb */
7098/* File: armv5te/OP_DIV_INT_LIT8.S */
7099/* File: armv5te/binopLit8.S */
7100    /*
7101     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7102     * that specifies an instruction that performs "result = r0 op r1".
7103     * This could be an ARM instruction or a function call.  (If the result
7104     * comes back in a register other than r0, you can override "result".)
7105     *
7106     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7107     * vCC (r1).  Useful for integer division and modulus.
7108     *
7109     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7110     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7111     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7112     */
7113    /* binop/lit8 vAA, vBB, #+CC */
7114    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7115    mov     r9, rINST, lsr #8           @ r9<- AA
7116    and     r2, r3, #255                @ r2<- BB
7117    GET_VREG(r0, r2)                    @ r0<- vBB
7118    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7119    .if 1
7120    @cmp     r1, #0                      @ is second operand zero?
7121    beq     common_errDivideByZero
7122    .endif
7123    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7124
7125                               @ optional op; may set condition codes
7126    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
7127    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7128    SET_VREG(r0, r9)               @ vAA<- r0
7129    GOTO_OPCODE(ip)                     @ jump to next instruction
7130    /* 10-12 instructions */
7131
7132
7133/* ------------------------------ */
7134    .balign 64
7135.L_OP_REM_INT_LIT8: /* 0xdc */
7136/* File: armv5te/OP_REM_INT_LIT8.S */
7137/* idivmod returns quotient in r0 and remainder in r1 */
7138/* File: armv5te/binopLit8.S */
7139    /*
7140     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7141     * that specifies an instruction that performs "result = r0 op r1".
7142     * This could be an ARM instruction or a function call.  (If the result
7143     * comes back in a register other than r0, you can override "result".)
7144     *
7145     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7146     * vCC (r1).  Useful for integer division and modulus.
7147     *
7148     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7149     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7150     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7151     */
7152    /* binop/lit8 vAA, vBB, #+CC */
7153    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7154    mov     r9, rINST, lsr #8           @ r9<- AA
7155    and     r2, r3, #255                @ r2<- BB
7156    GET_VREG(r0, r2)                    @ r0<- vBB
7157    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7158    .if 1
7159    @cmp     r1, #0                      @ is second operand zero?
7160    beq     common_errDivideByZero
7161    .endif
7162    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7163
7164                               @ optional op; may set condition codes
7165    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
7166    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7167    SET_VREG(r1, r9)               @ vAA<- r1
7168    GOTO_OPCODE(ip)                     @ jump to next instruction
7169    /* 10-12 instructions */
7170
7171
7172/* ------------------------------ */
7173    .balign 64
7174.L_OP_AND_INT_LIT8: /* 0xdd */
7175/* File: armv5te/OP_AND_INT_LIT8.S */
7176/* File: armv5te/binopLit8.S */
7177    /*
7178     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7179     * that specifies an instruction that performs "result = r0 op r1".
7180     * This could be an ARM instruction or a function call.  (If the result
7181     * comes back in a register other than r0, you can override "result".)
7182     *
7183     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7184     * vCC (r1).  Useful for integer division and modulus.
7185     *
7186     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7187     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7188     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7189     */
7190    /* binop/lit8 vAA, vBB, #+CC */
7191    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7192    mov     r9, rINST, lsr #8           @ r9<- AA
7193    and     r2, r3, #255                @ r2<- BB
7194    GET_VREG(r0, r2)                    @ r0<- vBB
7195    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7196    .if 0
7197    @cmp     r1, #0                      @ is second operand zero?
7198    beq     common_errDivideByZero
7199    .endif
7200    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7201
7202                               @ optional op; may set condition codes
7203    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
7204    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7205    SET_VREG(r0, r9)               @ vAA<- r0
7206    GOTO_OPCODE(ip)                     @ jump to next instruction
7207    /* 10-12 instructions */
7208
7209
7210/* ------------------------------ */
7211    .balign 64
7212.L_OP_OR_INT_LIT8: /* 0xde */
7213/* File: armv5te/OP_OR_INT_LIT8.S */
7214/* File: armv5te/binopLit8.S */
7215    /*
7216     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7217     * that specifies an instruction that performs "result = r0 op r1".
7218     * This could be an ARM instruction or a function call.  (If the result
7219     * comes back in a register other than r0, you can override "result".)
7220     *
7221     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7222     * vCC (r1).  Useful for integer division and modulus.
7223     *
7224     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7225     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7226     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7227     */
7228    /* binop/lit8 vAA, vBB, #+CC */
7229    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7230    mov     r9, rINST, lsr #8           @ r9<- AA
7231    and     r2, r3, #255                @ r2<- BB
7232    GET_VREG(r0, r2)                    @ r0<- vBB
7233    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7234    .if 0
7235    @cmp     r1, #0                      @ is second operand zero?
7236    beq     common_errDivideByZero
7237    .endif
7238    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7239
7240                               @ optional op; may set condition codes
7241    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
7242    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7243    SET_VREG(r0, r9)               @ vAA<- r0
7244    GOTO_OPCODE(ip)                     @ jump to next instruction
7245    /* 10-12 instructions */
7246
7247
7248/* ------------------------------ */
7249    .balign 64
7250.L_OP_XOR_INT_LIT8: /* 0xdf */
7251/* File: armv5te/OP_XOR_INT_LIT8.S */
7252/* File: armv5te/binopLit8.S */
7253    /*
7254     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7255     * that specifies an instruction that performs "result = r0 op r1".
7256     * This could be an ARM instruction or a function call.  (If the result
7257     * comes back in a register other than r0, you can override "result".)
7258     *
7259     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7260     * vCC (r1).  Useful for integer division and modulus.
7261     *
7262     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7263     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7264     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7265     */
7266    /* binop/lit8 vAA, vBB, #+CC */
7267    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7268    mov     r9, rINST, lsr #8           @ r9<- AA
7269    and     r2, r3, #255                @ r2<- BB
7270    GET_VREG(r0, r2)                    @ r0<- vBB
7271    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7272    .if 0
7273    @cmp     r1, #0                      @ is second operand zero?
7274    beq     common_errDivideByZero
7275    .endif
7276    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7277
7278                               @ optional op; may set condition codes
7279    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
7280    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7281    SET_VREG(r0, r9)               @ vAA<- r0
7282    GOTO_OPCODE(ip)                     @ jump to next instruction
7283    /* 10-12 instructions */
7284
7285
7286/* ------------------------------ */
7287    .balign 64
7288.L_OP_SHL_INT_LIT8: /* 0xe0 */
7289/* File: armv5te/OP_SHL_INT_LIT8.S */
7290/* File: armv5te/binopLit8.S */
7291    /*
7292     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7293     * that specifies an instruction that performs "result = r0 op r1".
7294     * This could be an ARM instruction or a function call.  (If the result
7295     * comes back in a register other than r0, you can override "result".)
7296     *
7297     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7298     * vCC (r1).  Useful for integer division and modulus.
7299     *
7300     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7301     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7302     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7303     */
7304    /* binop/lit8 vAA, vBB, #+CC */
7305    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7306    mov     r9, rINST, lsr #8           @ r9<- AA
7307    and     r2, r3, #255                @ r2<- BB
7308    GET_VREG(r0, r2)                    @ r0<- vBB
7309    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7310    .if 0
7311    @cmp     r1, #0                      @ is second operand zero?
7312    beq     common_errDivideByZero
7313    .endif
7314    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7315
7316    and     r1, r1, #31                           @ optional op; may set condition codes
7317    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
7318    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7319    SET_VREG(r0, r9)               @ vAA<- r0
7320    GOTO_OPCODE(ip)                     @ jump to next instruction
7321    /* 10-12 instructions */
7322
7323
7324/* ------------------------------ */
7325    .balign 64
7326.L_OP_SHR_INT_LIT8: /* 0xe1 */
7327/* File: armv5te/OP_SHR_INT_LIT8.S */
7328/* File: armv5te/binopLit8.S */
7329    /*
7330     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7331     * that specifies an instruction that performs "result = r0 op r1".
7332     * This could be an ARM instruction or a function call.  (If the result
7333     * comes back in a register other than r0, you can override "result".)
7334     *
7335     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7336     * vCC (r1).  Useful for integer division and modulus.
7337     *
7338     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7339     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7340     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7341     */
7342    /* binop/lit8 vAA, vBB, #+CC */
7343    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7344    mov     r9, rINST, lsr #8           @ r9<- AA
7345    and     r2, r3, #255                @ r2<- BB
7346    GET_VREG(r0, r2)                    @ r0<- vBB
7347    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7348    .if 0
7349    @cmp     r1, #0                      @ is second operand zero?
7350    beq     common_errDivideByZero
7351    .endif
7352    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7353
7354    and     r1, r1, #31                           @ optional op; may set condition codes
7355    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
7356    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7357    SET_VREG(r0, r9)               @ vAA<- r0
7358    GOTO_OPCODE(ip)                     @ jump to next instruction
7359    /* 10-12 instructions */
7360
7361
7362/* ------------------------------ */
7363    .balign 64
7364.L_OP_USHR_INT_LIT8: /* 0xe2 */
7365/* File: armv5te/OP_USHR_INT_LIT8.S */
7366/* File: armv5te/binopLit8.S */
7367    /*
7368     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7369     * that specifies an instruction that performs "result = r0 op r1".
7370     * This could be an ARM instruction or a function call.  (If the result
7371     * comes back in a register other than r0, you can override "result".)
7372     *
7373     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7374     * vCC (r1).  Useful for integer division and modulus.
7375     *
7376     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7377     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7378     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7379     */
7380    /* binop/lit8 vAA, vBB, #+CC */
7381    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7382    mov     r9, rINST, lsr #8           @ r9<- AA
7383    and     r2, r3, #255                @ r2<- BB
7384    GET_VREG(r0, r2)                    @ r0<- vBB
7385    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7386    .if 0
7387    @cmp     r1, #0                      @ is second operand zero?
7388    beq     common_errDivideByZero
7389    .endif
7390    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7391
7392    and     r1, r1, #31                           @ optional op; may set condition codes
7393    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
7394    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7395    SET_VREG(r0, r9)               @ vAA<- r0
7396    GOTO_OPCODE(ip)                     @ jump to next instruction
7397    /* 10-12 instructions */
7398
7399
7400/* ------------------------------ */
7401    .balign 64
7402.L_OP_IGET_VOLATILE: /* 0xe3 */
7403/* File: armv5te/OP_IGET_VOLATILE.S */
7404/* File: armv5te/OP_IGET.S */
7405    /*
7406     * General 32-bit instance field get.
7407     *
7408     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7409     */
7410    /* op vA, vB, field@CCCC */
7411    mov     r0, rINST, lsr #12          @ r0<- B
7412    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7413    FETCH(r1, 1)                        @ r1<- field ref CCCC
7414    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7415    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7416    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7417    cmp     r0, #0                      @ is resolved entry null?
7418    bne     .LOP_IGET_VOLATILE_finish          @ no, already resolved
74198:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7420    EXPORT_PC()                         @ resolve() could throw
7421    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7422    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7423    cmp     r0, #0
7424    bne     .LOP_IGET_VOLATILE_finish
7425    b       common_exceptionThrown
7426
7427
7428/* ------------------------------ */
7429    .balign 64
7430.L_OP_IPUT_VOLATILE: /* 0xe4 */
7431/* File: armv5te/OP_IPUT_VOLATILE.S */
7432/* File: armv5te/OP_IPUT.S */
7433    /*
7434     * General 32-bit instance field put.
7435     *
7436     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
7437     */
7438    /* op vA, vB, field@CCCC */
7439    mov     r0, rINST, lsr #12          @ r0<- B
7440    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7441    FETCH(r1, 1)                        @ r1<- field ref CCCC
7442    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7443    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7444    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7445    cmp     r0, #0                      @ is resolved entry null?
7446    bne     .LOP_IPUT_VOLATILE_finish          @ no, already resolved
74478:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7448    EXPORT_PC()                         @ resolve() could throw
7449    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7450    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7451    cmp     r0, #0                      @ success?
7452    bne     .LOP_IPUT_VOLATILE_finish          @ yes, finish up
7453    b       common_exceptionThrown
7454
7455
7456/* ------------------------------ */
7457    .balign 64
7458.L_OP_SGET_VOLATILE: /* 0xe5 */
7459/* File: armv5te/OP_SGET_VOLATILE.S */
7460/* File: armv5te/OP_SGET.S */
7461    /*
7462     * General 32-bit SGET handler.
7463     *
7464     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7465     */
7466    /* op vAA, field@BBBB */
7467    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7468    FETCH(r1, 1)                        @ r1<- field ref BBBB
7469    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7470    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7471    cmp     r0, #0                      @ is resolved entry null?
7472    beq     .LOP_SGET_VOLATILE_resolve         @ yes, do resolve
7473.LOP_SGET_VOLATILE_finish: @ field ptr in r0
7474    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7475    SMP_DMB                            @ acquiring load
7476    mov     r2, rINST, lsr #8           @ r2<- AA
7477    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7478    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7479    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7480    GOTO_OPCODE(ip)                     @ jump to next instruction
7481
7482
7483/* ------------------------------ */
7484    .balign 64
7485.L_OP_SPUT_VOLATILE: /* 0xe6 */
7486/* File: armv5te/OP_SPUT_VOLATILE.S */
7487/* File: armv5te/OP_SPUT.S */
7488    /*
7489     * General 32-bit SPUT handler.
7490     *
7491     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
7492     */
7493    /* op vAA, field@BBBB */
7494    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7495    FETCH(r1, 1)                        @ r1<- field ref BBBB
7496    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7497    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7498    cmp     r0, #0                      @ is resolved entry null?
7499    beq     .LOP_SPUT_VOLATILE_resolve         @ yes, do resolve
7500.LOP_SPUT_VOLATILE_finish:   @ field ptr in r0
7501    mov     r2, rINST, lsr #8           @ r2<- AA
7502    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7503    GET_VREG(r1, r2)                    @ r1<- fp[AA]
7504    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7505    SMP_DMB                            @ releasing store
7506    str     r1, [r0, #offStaticField_value] @ field<- vAA
7507    GOTO_OPCODE(ip)                     @ jump to next instruction
7508
7509
7510/* ------------------------------ */
7511    .balign 64
7512.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
7513/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */
7514/* File: armv5te/OP_IGET.S */
7515    /*
7516     * General 32-bit instance field get.
7517     *
7518     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7519     */
7520    /* op vA, vB, field@CCCC */
7521    mov     r0, rINST, lsr #12          @ r0<- B
7522    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7523    FETCH(r1, 1)                        @ r1<- field ref CCCC
7524    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7525    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7526    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7527    cmp     r0, #0                      @ is resolved entry null?
7528    bne     .LOP_IGET_OBJECT_VOLATILE_finish          @ no, already resolved
75298:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7530    EXPORT_PC()                         @ resolve() could throw
7531    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7532    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7533    cmp     r0, #0
7534    bne     .LOP_IGET_OBJECT_VOLATILE_finish
7535    b       common_exceptionThrown
7536
7537
7538/* ------------------------------ */
7539    .balign 64
7540.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
7541/* File: armv5te/OP_IGET_WIDE_VOLATILE.S */
7542/* File: armv5te/OP_IGET_WIDE.S */
7543    /*
7544     * Wide 32-bit instance field get.
7545     */
7546    /* iget-wide vA, vB, field@CCCC */
7547    mov     r0, rINST, lsr #12          @ r0<- B
7548    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7549    FETCH(r1, 1)                        @ r1<- field ref CCCC
7550    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7551    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7552    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7553    cmp     r0, #0                      @ is resolved entry null?
7554    bne     .LOP_IGET_WIDE_VOLATILE_finish          @ no, already resolved
75558:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
7556    EXPORT_PC()                         @ resolve() could throw
7557    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7558    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7559    cmp     r0, #0
7560    bne     .LOP_IGET_WIDE_VOLATILE_finish
7561    b       common_exceptionThrown
7562
7563
7564/* ------------------------------ */
7565    .balign 64
7566.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
7567/* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */
7568/* File: armv5te/OP_IPUT_WIDE.S */
7569    /* iput-wide vA, vB, field@CCCC */
7570    mov     r0, rINST, lsr #12          @ r0<- B
7571    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7572    FETCH(r1, 1)                        @ r1<- field ref CCCC
7573    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7574    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7575    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7576    cmp     r0, #0                      @ is resolved entry null?
7577    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ no, already resolved
75788:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
7579    EXPORT_PC()                         @ resolve() could throw
7580    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7581    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7582    cmp     r0, #0                      @ success?
7583    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ yes, finish up
7584    b       common_exceptionThrown
7585
7586
7587/* ------------------------------ */
7588    .balign 64
7589.L_OP_SGET_WIDE_VOLATILE: /* 0xea */
7590/* File: armv5te/OP_SGET_WIDE_VOLATILE.S */
7591/* File: armv5te/OP_SGET_WIDE.S */
7592    /*
7593     * 64-bit SGET handler.
7594     */
7595    /* sget-wide vAA, field@BBBB */
7596    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7597    FETCH(r1, 1)                        @ r1<- field ref BBBB
7598    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7599    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7600    cmp     r0, #0                      @ is resolved entry null?
7601    beq     .LOP_SGET_WIDE_VOLATILE_resolve         @ yes, do resolve
7602.LOP_SGET_WIDE_VOLATILE_finish:
7603    mov     r9, rINST, lsr #8           @ r9<- AA
7604    .if 1
7605    add     r0, r0, #offStaticField_value @ r0<- pointer to data
7606    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
7607    .else
7608    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
7609    .endif
7610    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7611    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7612    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
7613    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7614    GOTO_OPCODE(ip)                     @ jump to next instruction
7615
7616
7617/* ------------------------------ */
7618    .balign 64
7619.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
7620/* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */
7621/* File: armv5te/OP_SPUT_WIDE.S */
7622    /*
7623     * 64-bit SPUT handler.
7624     */
7625    /* sput-wide vAA, field@BBBB */
7626    ldr     r0, [rGLUE, #offGlue_methodClassDex]  @ r0<- DvmDex
7627    FETCH(r1, 1)                        @ r1<- field ref BBBB
7628    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
7629    mov     r9, rINST, lsr #8           @ r9<- AA
7630    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
7631    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7632    cmp     r2, #0                      @ is resolved entry null?
7633    beq     .LOP_SPUT_WIDE_VOLATILE_resolve         @ yes, do resolve
7634.LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9
7635    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7636    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
7637    GET_INST_OPCODE(r10)                @ extract opcode from rINST
7638    .if 1
7639    add     r2, r2, #offStaticField_value @ r2<- pointer to data
7640    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
7641    .else
7642    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
7643    .endif
7644    GOTO_OPCODE(r10)                    @ jump to next instruction
7645
7646
7647/* ------------------------------ */
7648    .balign 64
7649.L_OP_BREAKPOINT: /* 0xec */
7650/* File: armv5te/OP_BREAKPOINT.S */
7651/* File: armv5te/unused.S */
7652    bl      common_abort
7653
7654
7655/* ------------------------------ */
7656    .balign 64
7657.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
7658/* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */
7659    /*
7660     * Handle a throw-verification-error instruction.  This throws an
7661     * exception for an error discovered during verification.  The
7662     * exception is indicated by AA, with some detail provided by BBBB.
7663     */
7664    /* op AA, ref@BBBB */
7665    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
7666    FETCH(r2, 1)                        @ r2<- BBBB
7667    EXPORT_PC()                         @ export the PC
7668    mov     r1, rINST, lsr #8           @ r1<- AA
7669    bl      dvmThrowVerificationError   @ always throws
7670    b       common_exceptionThrown      @ handle exception
7671
7672/* ------------------------------ */
7673    .balign 64
7674.L_OP_EXECUTE_INLINE: /* 0xee */
7675/* File: armv5te/OP_EXECUTE_INLINE.S */
7676    /*
7677     * Execute a "native inline" instruction.
7678     *
7679     * We need to call an InlineOp4Func:
7680     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7681     *
7682     * The first four args are in r0-r3, pointer to return value storage
7683     * is on the stack.  The function's return value is a flag that tells
7684     * us if an exception was thrown.
7685     */
7686    /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
7687    FETCH(r10, 1)                       @ r10<- BBBB
7688    add     r1, rGLUE, #offGlue_retval  @ r1<- &glue->retval
7689    EXPORT_PC()                         @ can throw
7690    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7691    mov     r0, rINST, lsr #12          @ r0<- B
7692    str     r1, [sp]                    @ push &glue->retval
7693    bl      .LOP_EXECUTE_INLINE_continue        @ make call; will return after
7694    add     sp, sp, #8                  @ pop stack
7695    cmp     r0, #0                      @ test boolean result of inline
7696    beq     common_exceptionThrown      @ returned false, handle exception
7697    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7698    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7699    GOTO_OPCODE(ip)                     @ jump to next instruction
7700
7701/* ------------------------------ */
7702    .balign 64
7703.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
7704/* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */
7705    /*
7706     * Execute a "native inline" instruction, using "/range" semantics.
7707     * Same idea as execute-inline, but we get the args differently.
7708     *
7709     * We need to call an InlineOp4Func:
7710     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7711     *
7712     * The first four args are in r0-r3, pointer to return value storage
7713     * is on the stack.  The function's return value is a flag that tells
7714     * us if an exception was thrown.
7715     */
7716    /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */
7717    FETCH(r10, 1)                       @ r10<- BBBB
7718    add     r1, rGLUE, #offGlue_retval  @ r1<- &glue->retval
7719    EXPORT_PC()                         @ can throw
7720    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7721    mov     r0, rINST, lsr #8           @ r0<- AA
7722    str     r1, [sp]                    @ push &glue->retval
7723    bl      .LOP_EXECUTE_INLINE_RANGE_continue        @ make call; will return after
7724    add     sp, sp, #8                  @ pop stack
7725    cmp     r0, #0                      @ test boolean result of inline
7726    beq     common_exceptionThrown      @ returned false, handle exception
7727    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7728    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7729    GOTO_OPCODE(ip)                     @ jump to next instruction
7730
7731/* ------------------------------ */
7732    .balign 64
7733.L_OP_INVOKE_OBJECT_INIT: /* 0xf0 */
7734/* File: armv5te/OP_INVOKE_OBJECT_INIT.S */
7735    /*
7736     * invoke-object-init is a no-op in a "standard" interpreter.
7737     */
7738    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
7739    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
7740    GOTO_OPCODE(ip)                     @ execute it
7741
7742/* ------------------------------ */
7743    .balign 64
7744.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */
7745/* File: armv5te/OP_RETURN_VOID_BARRIER.S */
7746    SMP_DMB_ST
7747    b       common_returnFromMethod
7748
7749/* ------------------------------ */
7750    .balign 64
7751.L_OP_IGET_QUICK: /* 0xf2 */
7752/* File: armv5te/OP_IGET_QUICK.S */
7753    /* For: iget-quick, iget-object-quick */
7754    /* op vA, vB, offset@CCCC */
7755    mov     r2, rINST, lsr #12          @ r2<- B
7756    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7757    FETCH(r1, 1)                        @ r1<- field byte offset
7758    cmp     r3, #0                      @ check object for null
7759    mov     r2, rINST, lsr #8           @ r2<- A(+)
7760    beq     common_errNullObject        @ object was null
7761    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7762    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7763    and     r2, r2, #15
7764    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7765    SET_VREG(r0, r2)                    @ fp[A]<- r0
7766    GOTO_OPCODE(ip)                     @ jump to next instruction
7767
7768/* ------------------------------ */
7769    .balign 64
7770.L_OP_IGET_WIDE_QUICK: /* 0xf3 */
7771/* File: armv5te/OP_IGET_WIDE_QUICK.S */
7772    /* iget-wide-quick vA, vB, offset@CCCC */
7773    mov     r2, rINST, lsr #12          @ r2<- B
7774    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7775    FETCH(ip, 1)                        @ ip<- field byte offset
7776    cmp     r3, #0                      @ check object for null
7777    mov     r2, rINST, lsr #8           @ r2<- A(+)
7778    beq     common_errNullObject        @ object was null
7779    ldrd    r0, [r3, ip]                @ r0<- obj.field (64 bits, aligned)
7780    and     r2, r2, #15
7781    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7782    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
7783    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7784    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
7785    GOTO_OPCODE(ip)                     @ jump to next instruction
7786
7787/* ------------------------------ */
7788    .balign 64
7789.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */
7790/* File: armv5te/OP_IGET_OBJECT_QUICK.S */
7791/* File: armv5te/OP_IGET_QUICK.S */
7792    /* For: iget-quick, iget-object-quick */
7793    /* op vA, vB, offset@CCCC */
7794    mov     r2, rINST, lsr #12          @ r2<- B
7795    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7796    FETCH(r1, 1)                        @ r1<- field byte offset
7797    cmp     r3, #0                      @ check object for null
7798    mov     r2, rINST, lsr #8           @ r2<- A(+)
7799    beq     common_errNullObject        @ object was null
7800    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7801    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7802    and     r2, r2, #15
7803    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7804    SET_VREG(r0, r2)                    @ fp[A]<- r0
7805    GOTO_OPCODE(ip)                     @ jump to next instruction
7806
7807
7808/* ------------------------------ */
7809    .balign 64
7810.L_OP_IPUT_QUICK: /* 0xf5 */
7811/* File: armv5te/OP_IPUT_QUICK.S */
7812    /* For: iput-quick */
7813    /* op vA, vB, offset@CCCC */
7814    mov     r2, rINST, lsr #12          @ r2<- B
7815    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7816    FETCH(r1, 1)                        @ r1<- field byte offset
7817    cmp     r3, #0                      @ check object for null
7818    mov     r2, rINST, lsr #8           @ r2<- A(+)
7819    beq     common_errNullObject        @ object was null
7820    and     r2, r2, #15
7821    GET_VREG(r0, r2)                    @ r0<- fp[A]
7822    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7823    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7824    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7825    GOTO_OPCODE(ip)                     @ jump to next instruction
7826
7827/* ------------------------------ */
7828    .balign 64
7829.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */
7830/* File: armv5te/OP_IPUT_WIDE_QUICK.S */
7831    /* iput-wide-quick vA, vB, offset@CCCC */
7832    mov     r0, rINST, lsr #8           @ r0<- A(+)
7833    mov     r1, rINST, lsr #12          @ r1<- B
7834    and     r0, r0, #15
7835    GET_VREG(r2, r1)                    @ r2<- fp[B], the object pointer
7836    add     r3, rFP, r0, lsl #2         @ r3<- &fp[A]
7837    cmp     r2, #0                      @ check object for null
7838    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[A]
7839    beq     common_errNullObject        @ object was null
7840    FETCH(r3, 1)                        @ r3<- field byte offset
7841    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7842    strd    r0, [r2, r3]                @ obj.field (64 bits, aligned)<- r0/r1
7843    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7844    GOTO_OPCODE(ip)                     @ jump to next instruction
7845
7846/* ------------------------------ */
7847    .balign 64
7848.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
7849/* File: armv5te/OP_IPUT_OBJECT_QUICK.S */
7850    /* For: iput-object-quick */
7851    /* op vA, vB, offset@CCCC */
7852    mov     r2, rINST, lsr #12          @ r2<- B
7853    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7854    FETCH(r1, 1)                        @ r1<- field byte offset
7855    cmp     r3, #0                      @ check object for null
7856    mov     r2, rINST, lsr #8           @ r2<- A(+)
7857    beq     common_errNullObject        @ object was null
7858    and     r2, r2, #15
7859    GET_VREG(r0, r2)                    @ r0<- fp[A]
7860    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
7861    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7862    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7863    cmp     r0, #0
7864    strneb  r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head
7865    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7866    GOTO_OPCODE(ip)                     @ jump to next instruction
7867
7868/* ------------------------------ */
7869    .balign 64
7870.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
7871/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7872    /*
7873     * Handle an optimized virtual method call.
7874     *
7875     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7876     */
7877    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7878    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7879    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7880    FETCH(r1, 1)                        @ r1<- BBBB
7881    .if     (!0)
7882    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7883    .endif
7884    GET_VREG(r2, r3)                    @ r2<- vC ("this" ptr)
7885    cmp     r2, #0                      @ is "this" null?
7886    beq     common_errNullObject        @ null "this", throw exception
7887    ldr     r2, [r2, #offObject_clazz]  @ r2<- thisPtr->clazz
7888    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7889    EXPORT_PC()                         @ invoke must export
7890    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7891    bl      common_invokeMethodNoRange @ continue on
7892
7893/* ------------------------------ */
7894    .balign 64
7895.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
7896/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */
7897/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7898    /*
7899     * Handle an optimized virtual method call.
7900     *
7901     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7902     */
7903    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7904    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7905    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7906    FETCH(r1, 1)                        @ r1<- BBBB
7907    .if     (!1)
7908    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7909    .endif
7910    GET_VREG(r2, r3)                    @ r2<- vC ("this" ptr)
7911    cmp     r2, #0                      @ is "this" null?
7912    beq     common_errNullObject        @ null "this", throw exception
7913    ldr     r2, [r2, #offObject_clazz]  @ r2<- thisPtr->clazz
7914    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7915    EXPORT_PC()                         @ invoke must export
7916    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7917    bl      common_invokeMethodRange @ continue on
7918
7919
7920/* ------------------------------ */
7921    .balign 64
7922.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */
7923/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7924    /*
7925     * Handle an optimized "super" method call.
7926     *
7927     * for: [opt] invoke-super-quick, invoke-super-quick/range
7928     */
7929    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7930    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7931    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7932    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7933    .if     (!0)
7934    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7935    .endif
7936    FETCH(r1, 1)                        @ r1<- BBBB
7937    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7938    EXPORT_PC()                         @ must export for invoke
7939    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7940    GET_VREG(r3, r10)                   @ r3<- "this"
7941    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7942    cmp     r3, #0                      @ null "this" ref?
7943    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7944    beq     common_errNullObject        @ "this" is null, throw exception
7945    bl      common_invokeMethodNoRange @ continue on
7946
7947/* ------------------------------ */
7948    .balign 64
7949.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
7950/* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */
7951/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7952    /*
7953     * Handle an optimized "super" method call.
7954     *
7955     * for: [opt] invoke-super-quick, invoke-super-quick/range
7956     */
7957    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7958    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7959    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7960    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7961    .if     (!1)
7962    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7963    .endif
7964    FETCH(r1, 1)                        @ r1<- BBBB
7965    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7966    EXPORT_PC()                         @ must export for invoke
7967    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7968    GET_VREG(r3, r10)                   @ r3<- "this"
7969    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7970    cmp     r3, #0                      @ null "this" ref?
7971    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7972    beq     common_errNullObject        @ "this" is null, throw exception
7973    bl      common_invokeMethodRange @ continue on
7974
7975
7976/* ------------------------------ */
7977    .balign 64
7978.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
7979/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */
7980/* File: armv5te/OP_IPUT_OBJECT.S */
7981    /*
7982     * 32-bit instance field put.
7983     *
7984     * for: iput-object, iput-object-volatile
7985     */
7986    /* op vA, vB, field@CCCC */
7987    mov     r0, rINST, lsr #12          @ r0<- B
7988    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7989    FETCH(r1, 1)                        @ r1<- field ref CCCC
7990    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7991    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7992    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7993    cmp     r0, #0                      @ is resolved entry null?
7994    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ no, already resolved
79958:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7996    EXPORT_PC()                         @ resolve() could throw
7997    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7998    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7999    cmp     r0, #0                      @ success?
8000    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ yes, finish up
8001    b       common_exceptionThrown
8002
8003
8004/* ------------------------------ */
8005    .balign 64
8006.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
8007/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */
8008/* File: armv5te/OP_SGET.S */
8009    /*
8010     * General 32-bit SGET handler.
8011     *
8012     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
8013     */
8014    /* op vAA, field@BBBB */
8015    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8016    FETCH(r1, 1)                        @ r1<- field ref BBBB
8017    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8018    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8019    cmp     r0, #0                      @ is resolved entry null?
8020    beq     .LOP_SGET_OBJECT_VOLATILE_resolve         @ yes, do resolve
8021.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0
8022    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8023    SMP_DMB                            @ acquiring load
8024    mov     r2, rINST, lsr #8           @ r2<- AA
8025    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8026    SET_VREG(r1, r2)                    @ fp[AA]<- r1
8027    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8028    GOTO_OPCODE(ip)                     @ jump to next instruction
8029
8030
8031/* ------------------------------ */
8032    .balign 64
8033.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
8034/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */
8035/* File: armv5te/OP_SPUT_OBJECT.S */
8036    /*
8037     * 32-bit SPUT handler for objects
8038     *
8039     * for: sput-object, sput-object-volatile
8040     */
8041    /* op vAA, field@BBBB */
8042    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8043    FETCH(r1, 1)                        @ r1<- field ref BBBB
8044    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8045    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8046    cmp     r0, #0                      @ is resolved entry null?
8047    bne     .LOP_SPUT_OBJECT_VOLATILE_finish          @ no, continue
8048    ldr     r9, [rGLUE, #offGlue_method]    @ r9<- current method
8049    EXPORT_PC()                         @ resolve() could throw, so export now
8050    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
8051    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8052    cmp     r0, #0                      @ success?
8053    bne     .LOP_SPUT_OBJECT_VOLATILE_finish          @ yes, finish
8054    b       common_exceptionThrown      @ no, handle exception
8055
8056
8057
8058/* ------------------------------ */
8059    .balign 64
8060.L_OP_DISPATCH_FF: /* 0xff */
8061/* File: armv5te/OP_DISPATCH_FF.S */
8062    mov     ip, rINST, lsr #8           @ r9<- extended opcode
8063    add     ip, ip, #256                @ add offset for extended opcodes
8064    GOTO_OPCODE(ip)                     @ go to proper extended handler
8065
8066
8067/* ------------------------------ */
8068    .balign 64
8069.L_OP_CONST_CLASS_JUMBO: /* 0x100 */
8070/* File: armv5te/OP_CONST_CLASS_JUMBO.S */
8071    /* const-class/jumbo vBBBB, Class@AAAAAAAA */
8072    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8073    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- glue->methodClassDex
8074    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8075    ldr     r2, [r2, #offDvmDex_pResClasses]   @ r2<- dvmDex->pResClasses
8076    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8077    FETCH(r9, 3)                        @ r9<- BBBB
8078    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResClasses[AAAAaaaa]
8079    cmp     r0, #0                      @ not yet resolved?
8080    beq     .LOP_CONST_CLASS_JUMBO_resolve
8081    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8082    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8083    SET_VREG(r0, r9)                    @ vBBBB<- r0
8084    GOTO_OPCODE(ip)                     @ jump to next instruction
8085
8086/* ------------------------------ */
8087    .balign 64
8088.L_OP_CHECK_CAST_JUMBO: /* 0x101 */
8089/* File: armv5te/OP_CHECK_CAST_JUMBO.S */
8090    /*
8091     * Check to see if a cast from one class to another is allowed.
8092     */
8093    /* check-cast/jumbo vBBBB, class@AAAAAAAA */
8094    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8095    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8096    FETCH(r3, 3)                        @ r3<- BBBB
8097    orr     r2, r0, r2, lsl #16         @ r2<- AAAAaaaa
8098    GET_VREG(r9, r3)                    @ r9<- object
8099    ldr     r0, [rGLUE, #offGlue_methodClassDex]    @ r0<- pDvmDex
8100    cmp     r9, #0                      @ is object null?
8101    ldr     r0, [r0, #offDvmDex_pResClasses]    @ r0<- pDvmDex->pResClasses
8102    beq     .LOP_CHECK_CAST_JUMBO_okay            @ null obj, cast always succeeds
8103    ldr     r1, [r0, r2, lsl #2]        @ r1<- resolved class
8104    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
8105    cmp     r1, #0                      @ have we resolved this before?
8106    beq     .LOP_CHECK_CAST_JUMBO_resolve         @ not resolved, do it now
8107.LOP_CHECK_CAST_JUMBO_resolved:
8108    cmp     r0, r1                      @ same class (trivial success)?
8109    bne     .LOP_CHECK_CAST_JUMBO_fullcheck       @ no, do full check
8110    b       .LOP_CHECK_CAST_JUMBO_okay            @ yes, finish up
8111
8112/* ------------------------------ */
8113    .balign 64
8114.L_OP_INSTANCE_OF_JUMBO: /* 0x102 */
8115/* File: armv5te/OP_INSTANCE_OF_JUMBO.S */
8116    /*
8117     * Check to see if an object reference is an instance of a class.
8118     *
8119     * Most common situation is a non-null object, being compared against
8120     * an already-resolved class.
8121     *
8122     * TODO: convert most of this into a common subroutine, shared with
8123     *       OP_INSTANCE_OF.S.
8124     */
8125    /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */
8126    FETCH(r3, 4)                        @ r3<- vCCCC
8127    FETCH(r9, 3)                        @ r9<- vBBBB
8128    GET_VREG(r0, r3)                    @ r0<- vCCCC (object)
8129    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- pDvmDex
8130    cmp     r0, #0                      @ is object null?
8131    beq     .LOP_INSTANCE_OF_JUMBO_store           @ null obj, not an instance, store r0
8132    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8133    FETCH(r3, 2)                        @ r3<- AAAA (hi)
8134    ldr     r2, [r2, #offDvmDex_pResClasses]    @ r2<- pDvmDex->pResClasses
8135    orr     r3, r1, r3, lsl #16         @ r3<- AAAAaaaa
8136    ldr     r1, [r2, r3, lsl #2]        @ r1<- resolved class
8137    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
8138    cmp     r1, #0                      @ have we resolved this before?
8139    beq     .LOP_INSTANCE_OF_JUMBO_resolve         @ not resolved, do it now
8140    b       .LOP_INSTANCE_OF_JUMBO_resolved        @ resolved, continue
8141
8142/* ------------------------------ */
8143    .balign 64
8144.L_OP_NEW_INSTANCE_JUMBO: /* 0x103 */
8145/* File: armv5te/OP_NEW_INSTANCE_JUMBO.S */
8146    /*
8147     * Create a new instance of a class.
8148     */
8149    /* new-instance/jumbo vBBBB, class@AAAAAAAA */
8150    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8151    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8152    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8153    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8154    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
8155    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
8156    EXPORT_PC()                         @ req'd for init, resolve, alloc
8157    cmp     r0, #0                      @ already resolved?
8158    beq     .LOP_NEW_INSTANCE_JUMBO_resolve         @ no, resolve it now
8159.LOP_NEW_INSTANCE_JUMBO_resolved:   @ r0=class
8160    ldrb    r1, [r0, #offClassObject_status]    @ r1<- ClassStatus enum
8161    cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
8162    bne     .LOP_NEW_INSTANCE_JUMBO_needinit        @ no, init class now
8163.LOP_NEW_INSTANCE_JUMBO_initialized: @ r0=class
8164    mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
8165    bl      dvmAllocObject              @ r0<- new object
8166    b       .LOP_NEW_INSTANCE_JUMBO_finish          @ continue
8167
8168/* ------------------------------ */
8169    .balign 64
8170.L_OP_NEW_ARRAY_JUMBO: /* 0x104 */
8171/* File: armv5te/OP_NEW_ARRAY_JUMBO.S */
8172    /*
8173     * Allocate an array of objects, specified with the array class
8174     * and a count.
8175     *
8176     * The verifier guarantees that this is an array class, so we don't
8177     * check for it here.
8178     */
8179    /* new-array/jumbo vBBBB, vCCCC, class@AAAAAAAA */
8180    FETCH(r2, 1)                        @ r2<- aaaa (lo)
8181    FETCH(r3, 2)                        @ r3<- AAAA (hi)
8182    FETCH(r0, 4)                        @ r0<- vCCCC
8183    orr     r2, r2, r3, lsl #16         @ r2<- AAAAaaaa
8184    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8185    GET_VREG(r1, r0)                    @ r1<- vCCCC (array length)
8186    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
8187    cmp     r1, #0                      @ check length
8188    ldr     r0, [r3, r2, lsl #2]        @ r0<- resolved class
8189    bmi     common_errNegativeArraySize @ negative length, bail
8190    cmp     r0, #0                      @ already resolved?
8191    EXPORT_PC()                         @ req'd for resolve, alloc
8192    bne     .LOP_NEW_ARRAY_JUMBO_finish          @ resolved, continue
8193    b       .LOP_NEW_ARRAY_JUMBO_resolve         @ do resolve now
8194
8195/* ------------------------------ */
8196    .balign 64
8197.L_OP_FILLED_NEW_ARRAY_JUMBO: /* 0x105 */
8198/* File: armv5te/OP_FILLED_NEW_ARRAY_JUMBO.S */
8199    /*
8200     * Create a new array with elements filled from registers.
8201     *
8202     * TODO: convert most of this into a common subroutine, shared with
8203     *       OP_FILLED_NEW_ARRAY.S.
8204     */
8205    /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */
8206    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8207    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8208    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8209    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
8210    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8211    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
8212    EXPORT_PC()                         @ need for resolve and alloc
8213    cmp     r0, #0                      @ already resolved?
8214    bne     .LOP_FILLED_NEW_ARRAY_JUMBO_continue        @ yes, continue on
82158:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
8216    mov     r2, #0                      @ r2<- false
8217    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8218    bl      dvmResolveClass             @ r0<- call(clazz, ref)
8219    cmp     r0, #0                      @ got null?
8220    beq     common_exceptionThrown      @ yes, handle exception
8221    b       .LOP_FILLED_NEW_ARRAY_JUMBO_continue
8222
8223/* ------------------------------ */
8224    .balign 64
8225.L_OP_IGET_JUMBO: /* 0x106 */
8226/* File: armv5te/OP_IGET_JUMBO.S */
8227    /*
8228     * Jumbo 32-bit instance field get.
8229     *
8230     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8231     *      iget-char/jumbo, iget-short/jumbo
8232     */
8233    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8234    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8235    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8236    FETCH(r0, 4)                        @ r0<- CCCC
8237    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8238    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8239    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8240    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8241    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8242    cmp     r0, #0                      @ is resolved entry null?
8243    bne     .LOP_IGET_JUMBO_finish          @ no, already resolved
82448:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8245    EXPORT_PC()                         @ resolve() could throw
8246    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8247    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8248    b       .LOP_IGET_JUMBO_resolved        @ resolved, continue
8249
8250/* ------------------------------ */
8251    .balign 64
8252.L_OP_IGET_WIDE_JUMBO: /* 0x107 */
8253/* File: armv5te/OP_IGET_WIDE_JUMBO.S */
8254    /*
8255     * Jumbo 64-bit instance field get.
8256     */
8257    /* iget-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
8258    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8259    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8260    FETCH(r0, 4)                        @ r0<- CCCC
8261    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8262    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8263    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
8264    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8265    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8266    cmp     r0, #0                      @ is resolved entry null?
8267    bne     .LOP_IGET_WIDE_JUMBO_finish          @ no, already resolved
82688:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
8269    EXPORT_PC()                         @ resolve() could throw
8270    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8271    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8272    b       .LOP_IGET_WIDE_JUMBO_resolved        @ resolved, continue
8273
8274/* ------------------------------ */
8275    .balign 64
8276.L_OP_IGET_OBJECT_JUMBO: /* 0x108 */
8277/* File: armv5te/OP_IGET_OBJECT_JUMBO.S */
8278/* File: armv5te/OP_IGET_JUMBO.S */
8279    /*
8280     * Jumbo 32-bit instance field get.
8281     *
8282     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8283     *      iget-char/jumbo, iget-short/jumbo
8284     */
8285    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8286    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8287    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8288    FETCH(r0, 4)                        @ r0<- CCCC
8289    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8290    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8291    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8292    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8293    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8294    cmp     r0, #0                      @ is resolved entry null?
8295    bne     .LOP_IGET_OBJECT_JUMBO_finish          @ no, already resolved
82968:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8297    EXPORT_PC()                         @ resolve() could throw
8298    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8299    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8300    b       .LOP_IGET_OBJECT_JUMBO_resolved        @ resolved, continue
8301
8302
8303/* ------------------------------ */
8304    .balign 64
8305.L_OP_IGET_BOOLEAN_JUMBO: /* 0x109 */
8306/* File: armv5te/OP_IGET_BOOLEAN_JUMBO.S */
8307@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrb", "sqnum":"1" }
8308/* File: armv5te/OP_IGET_JUMBO.S */
8309    /*
8310     * Jumbo 32-bit instance field get.
8311     *
8312     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8313     *      iget-char/jumbo, iget-short/jumbo
8314     */
8315    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8316    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8317    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8318    FETCH(r0, 4)                        @ r0<- CCCC
8319    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8320    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8321    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8322    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8323    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8324    cmp     r0, #0                      @ is resolved entry null?
8325    bne     .LOP_IGET_BOOLEAN_JUMBO_finish          @ no, already resolved
83268:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8327    EXPORT_PC()                         @ resolve() could throw
8328    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8329    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8330    b       .LOP_IGET_BOOLEAN_JUMBO_resolved        @ resolved, continue
8331
8332
8333/* ------------------------------ */
8334    .balign 64
8335.L_OP_IGET_BYTE_JUMBO: /* 0x10a */
8336/* File: armv5te/OP_IGET_BYTE_JUMBO.S */
8337@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsb", "sqnum":"2" }
8338/* File: armv5te/OP_IGET_JUMBO.S */
8339    /*
8340     * Jumbo 32-bit instance field get.
8341     *
8342     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8343     *      iget-char/jumbo, iget-short/jumbo
8344     */
8345    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8346    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8347    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8348    FETCH(r0, 4)                        @ r0<- CCCC
8349    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8350    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8351    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8352    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8353    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8354    cmp     r0, #0                      @ is resolved entry null?
8355    bne     .LOP_IGET_BYTE_JUMBO_finish          @ no, already resolved
83568:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8357    EXPORT_PC()                         @ resolve() could throw
8358    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8359    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8360    b       .LOP_IGET_BYTE_JUMBO_resolved        @ resolved, continue
8361
8362
8363/* ------------------------------ */
8364    .balign 64
8365.L_OP_IGET_CHAR_JUMBO: /* 0x10b */
8366/* File: armv5te/OP_IGET_CHAR_JUMBO.S */
8367@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrh", "sqnum":"3" }
8368/* File: armv5te/OP_IGET_JUMBO.S */
8369    /*
8370     * Jumbo 32-bit instance field get.
8371     *
8372     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8373     *      iget-char/jumbo, iget-short/jumbo
8374     */
8375    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8376    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8377    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8378    FETCH(r0, 4)                        @ r0<- CCCC
8379    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8380    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8381    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8382    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8383    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8384    cmp     r0, #0                      @ is resolved entry null?
8385    bne     .LOP_IGET_CHAR_JUMBO_finish          @ no, already resolved
83868:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8387    EXPORT_PC()                         @ resolve() could throw
8388    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8389    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8390    b       .LOP_IGET_CHAR_JUMBO_resolved        @ resolved, continue
8391
8392
8393/* ------------------------------ */
8394    .balign 64
8395.L_OP_IGET_SHORT_JUMBO: /* 0x10c */
8396/* File: armv5te/OP_IGET_SHORT_JUMBO.S */
8397@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsh", "sqnum":"4" }
8398/* File: armv5te/OP_IGET_JUMBO.S */
8399    /*
8400     * Jumbo 32-bit instance field get.
8401     *
8402     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8403     *      iget-char/jumbo, iget-short/jumbo
8404     */
8405    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8406    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8407    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8408    FETCH(r0, 4)                        @ r0<- CCCC
8409    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8410    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8411    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8412    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8413    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8414    cmp     r0, #0                      @ is resolved entry null?
8415    bne     .LOP_IGET_SHORT_JUMBO_finish          @ no, already resolved
84168:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8417    EXPORT_PC()                         @ resolve() could throw
8418    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8419    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8420    b       .LOP_IGET_SHORT_JUMBO_resolved        @ resolved, continue
8421
8422
8423/* ------------------------------ */
8424    .balign 64
8425.L_OP_IPUT_JUMBO: /* 0x10d */
8426/* File: armv5te/OP_IPUT_JUMBO.S */
8427    /*
8428     * Jumbo 32-bit instance field put.
8429     *
8430     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8431     *      iput-short/jumbo
8432     */
8433    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8434    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8435    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8436    FETCH(r0, 4)                        @ r0<- CCCC
8437    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8438    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8439    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8440    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8441    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8442    cmp     r0, #0                      @ is resolved entry null?
8443    bne     .LOP_IPUT_JUMBO_finish          @ no, already resolved
84448:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8445    EXPORT_PC()                         @ resolve() could throw
8446    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8447    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8448    b       .LOP_IPUT_JUMBO_resolved        @ resolved, continue
8449
8450/* ------------------------------ */
8451    .balign 64
8452.L_OP_IPUT_WIDE_JUMBO: /* 0x10e */
8453/* File: armv5te/OP_IPUT_WIDE_JUMBO.S */
8454    /* iput-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
8455    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8456    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8457    FETCH(r0, 4)                        @ r0<- CCCC
8458    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8459    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8460    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
8461    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
8462    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8463    cmp     r0, #0                      @ is resolved entry null?
8464    bne     .LOP_IPUT_WIDE_JUMBO_finish          @ no, already resolved
84658:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
8466    EXPORT_PC()                         @ resolve() could throw
8467    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8468    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8469    b       .LOP_IPUT_WIDE_JUMBO_resolved        @ resolved, continue
8470
8471/* ------------------------------ */
8472    .balign 64
8473.L_OP_IPUT_OBJECT_JUMBO: /* 0x10f */
8474/* File: armv5te/OP_IPUT_OBJECT_JUMBO.S */
8475    /*
8476     * Jumbo 32-bit instance field put.
8477     */
8478    /* iput-object/jumbo vBBBB, vCCCC, field@AAAAAAAA */
8479    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8480    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8481    FETCH(r0, 4)                        @ r0<- CCCC
8482    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8483    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8484    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8485    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8486    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8487    cmp     r0, #0                      @ is resolved entry null?
8488    bne     .LOP_IPUT_OBJECT_JUMBO_finish          @ no, already resolved
84898:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8490    EXPORT_PC()                         @ resolve() could throw
8491    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8492    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8493    b       .LOP_IPUT_OBJECT_JUMBO_resolved        @ resolved, continue
8494
8495/* ------------------------------ */
8496    .balign 64
8497.L_OP_IPUT_BOOLEAN_JUMBO: /* 0x110 */
8498/* File: armv5te/OP_IPUT_BOOLEAN_JUMBO.S */
8499@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"1" }
8500/* File: armv5te/OP_IPUT_JUMBO.S */
8501    /*
8502     * Jumbo 32-bit instance field put.
8503     *
8504     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8505     *      iput-short/jumbo
8506     */
8507    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8508    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8509    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8510    FETCH(r0, 4)                        @ r0<- CCCC
8511    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8512    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8513    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8514    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8515    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8516    cmp     r0, #0                      @ is resolved entry null?
8517    bne     .LOP_IPUT_BOOLEAN_JUMBO_finish          @ no, already resolved
85188:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8519    EXPORT_PC()                         @ resolve() could throw
8520    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8521    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8522    b       .LOP_IPUT_BOOLEAN_JUMBO_resolved        @ resolved, continue
8523
8524
8525/* ------------------------------ */
8526    .balign 64
8527.L_OP_IPUT_BYTE_JUMBO: /* 0x111 */
8528/* File: armv5te/OP_IPUT_BYTE_JUMBO.S */
8529@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"2" }
8530/* File: armv5te/OP_IPUT_JUMBO.S */
8531    /*
8532     * Jumbo 32-bit instance field put.
8533     *
8534     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8535     *      iput-short/jumbo
8536     */
8537    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8538    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8539    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8540    FETCH(r0, 4)                        @ r0<- CCCC
8541    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8542    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8543    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8544    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8545    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8546    cmp     r0, #0                      @ is resolved entry null?
8547    bne     .LOP_IPUT_BYTE_JUMBO_finish          @ no, already resolved
85488:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8549    EXPORT_PC()                         @ resolve() could throw
8550    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8551    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8552    b       .LOP_IPUT_BYTE_JUMBO_resolved        @ resolved, continue
8553
8554
8555/* ------------------------------ */
8556    .balign 64
8557.L_OP_IPUT_CHAR_JUMBO: /* 0x112 */
8558/* File: armv5te/OP_IPUT_CHAR_JUMBO.S */
8559@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"3" }
8560/* File: armv5te/OP_IPUT_JUMBO.S */
8561    /*
8562     * Jumbo 32-bit instance field put.
8563     *
8564     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8565     *      iput-short/jumbo
8566     */
8567    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8568    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8569    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8570    FETCH(r0, 4)                        @ r0<- CCCC
8571    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8572    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8573    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8574    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8575    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8576    cmp     r0, #0                      @ is resolved entry null?
8577    bne     .LOP_IPUT_CHAR_JUMBO_finish          @ no, already resolved
85788:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8579    EXPORT_PC()                         @ resolve() could throw
8580    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8581    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8582    b       .LOP_IPUT_CHAR_JUMBO_resolved        @ resolved, continue
8583
8584
8585/* ------------------------------ */
8586    .balign 64
8587.L_OP_IPUT_SHORT_JUMBO: /* 0x113 */
8588/* File: armv5te/OP_IPUT_SHORT_JUMBO.S */
8589@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"4" }
8590/* File: armv5te/OP_IPUT_JUMBO.S */
8591    /*
8592     * Jumbo 32-bit instance field put.
8593     *
8594     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8595     *      iput-short/jumbo
8596     */
8597    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8598    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8599    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8600    FETCH(r0, 4)                        @ r0<- CCCC
8601    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8602    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8603    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8604    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8605    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8606    cmp     r0, #0                      @ is resolved entry null?
8607    bne     .LOP_IPUT_SHORT_JUMBO_finish          @ no, already resolved
86088:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8609    EXPORT_PC()                         @ resolve() could throw
8610    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8611    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8612    b       .LOP_IPUT_SHORT_JUMBO_resolved        @ resolved, continue
8613
8614
8615/* ------------------------------ */
8616    .balign 64
8617.L_OP_SGET_JUMBO: /* 0x114 */
8618/* File: armv5te/OP_SGET_JUMBO.S */
8619    /*
8620     * Jumbo 32-bit SGET handler.
8621     *
8622     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8623     *      sget-char/jumbo, sget-short/jumbo
8624     */
8625    /* exop vBBBB, field@AAAAAAAA */
8626    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8627    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8628    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8629    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8630    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8631    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8632    cmp     r0, #0                      @ is resolved entry null?
8633    beq     .LOP_SGET_JUMBO_resolve         @ yes, do resolve
8634.LOP_SGET_JUMBO_finish: @ field ptr in r0
8635    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8636    @ no-op                             @ acquiring load
8637    FETCH(r2, 3)                        @ r2<- BBBB
8638    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8639    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8640    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8641    GOTO_OPCODE(ip)                     @ jump to next instruction
8642
8643/* ------------------------------ */
8644    .balign 64
8645.L_OP_SGET_WIDE_JUMBO: /* 0x115 */
8646/* File: armv5te/OP_SGET_WIDE_JUMBO.S */
8647    /*
8648     * Jumbo 64-bit SGET handler.
8649     */
8650    /* sget-wide/jumbo vBBBB, field@AAAAAAAA */
8651    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8652    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8653    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8654    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8655    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8656    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8657    cmp     r0, #0                      @ is resolved entry null?
8658    beq     .LOP_SGET_WIDE_JUMBO_resolve         @ yes, do resolve
8659.LOP_SGET_WIDE_JUMBO_finish:
8660    FETCH(r9, 3)                        @ r9<- BBBB
8661    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
8662    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BBBB]
8663    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8664    stmia   r9, {r0-r1}                 @ vBBBB/vBBBB+1<- r0/r1
8665    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8666    GOTO_OPCODE(ip)                     @ jump to next instruction
8667
8668/* ------------------------------ */
8669    .balign 64
8670.L_OP_SGET_OBJECT_JUMBO: /* 0x116 */
8671/* File: armv5te/OP_SGET_OBJECT_JUMBO.S */
8672/* File: armv5te/OP_SGET_JUMBO.S */
8673    /*
8674     * Jumbo 32-bit SGET handler.
8675     *
8676     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8677     *      sget-char/jumbo, sget-short/jumbo
8678     */
8679    /* exop vBBBB, field@AAAAAAAA */
8680    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8681    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8682    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8683    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8684    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8685    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8686    cmp     r0, #0                      @ is resolved entry null?
8687    beq     .LOP_SGET_OBJECT_JUMBO_resolve         @ yes, do resolve
8688.LOP_SGET_OBJECT_JUMBO_finish: @ field ptr in r0
8689    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8690    @ no-op                             @ acquiring load
8691    FETCH(r2, 3)                        @ r2<- BBBB
8692    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8693    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8694    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8695    GOTO_OPCODE(ip)                     @ jump to next instruction
8696
8697
8698/* ------------------------------ */
8699    .balign 64
8700.L_OP_SGET_BOOLEAN_JUMBO: /* 0x117 */
8701/* File: armv5te/OP_SGET_BOOLEAN_JUMBO.S */
8702/* File: armv5te/OP_SGET_JUMBO.S */
8703    /*
8704     * Jumbo 32-bit SGET handler.
8705     *
8706     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8707     *      sget-char/jumbo, sget-short/jumbo
8708     */
8709    /* exop vBBBB, field@AAAAAAAA */
8710    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8711    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8712    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8713    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8714    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8715    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8716    cmp     r0, #0                      @ is resolved entry null?
8717    beq     .LOP_SGET_BOOLEAN_JUMBO_resolve         @ yes, do resolve
8718.LOP_SGET_BOOLEAN_JUMBO_finish: @ field ptr in r0
8719    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8720    @ no-op                             @ acquiring load
8721    FETCH(r2, 3)                        @ r2<- BBBB
8722    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8723    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8724    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8725    GOTO_OPCODE(ip)                     @ jump to next instruction
8726
8727
8728/* ------------------------------ */
8729    .balign 64
8730.L_OP_SGET_BYTE_JUMBO: /* 0x118 */
8731/* File: armv5te/OP_SGET_BYTE_JUMBO.S */
8732/* File: armv5te/OP_SGET_JUMBO.S */
8733    /*
8734     * Jumbo 32-bit SGET handler.
8735     *
8736     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8737     *      sget-char/jumbo, sget-short/jumbo
8738     */
8739    /* exop vBBBB, field@AAAAAAAA */
8740    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8741    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8742    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8743    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8744    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8745    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8746    cmp     r0, #0                      @ is resolved entry null?
8747    beq     .LOP_SGET_BYTE_JUMBO_resolve         @ yes, do resolve
8748.LOP_SGET_BYTE_JUMBO_finish: @ field ptr in r0
8749    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8750    @ no-op                             @ acquiring load
8751    FETCH(r2, 3)                        @ r2<- BBBB
8752    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8753    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8754    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8755    GOTO_OPCODE(ip)                     @ jump to next instruction
8756
8757
8758/* ------------------------------ */
8759    .balign 64
8760.L_OP_SGET_CHAR_JUMBO: /* 0x119 */
8761/* File: armv5te/OP_SGET_CHAR_JUMBO.S */
8762/* File: armv5te/OP_SGET_JUMBO.S */
8763    /*
8764     * Jumbo 32-bit SGET handler.
8765     *
8766     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8767     *      sget-char/jumbo, sget-short/jumbo
8768     */
8769    /* exop vBBBB, field@AAAAAAAA */
8770    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8771    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8772    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8773    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8774    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8775    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8776    cmp     r0, #0                      @ is resolved entry null?
8777    beq     .LOP_SGET_CHAR_JUMBO_resolve         @ yes, do resolve
8778.LOP_SGET_CHAR_JUMBO_finish: @ field ptr in r0
8779    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8780    @ no-op                             @ acquiring load
8781    FETCH(r2, 3)                        @ r2<- BBBB
8782    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8783    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8784    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8785    GOTO_OPCODE(ip)                     @ jump to next instruction
8786
8787
8788/* ------------------------------ */
8789    .balign 64
8790.L_OP_SGET_SHORT_JUMBO: /* 0x11a */
8791/* File: armv5te/OP_SGET_SHORT_JUMBO.S */
8792/* File: armv5te/OP_SGET_JUMBO.S */
8793    /*
8794     * Jumbo 32-bit SGET handler.
8795     *
8796     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8797     *      sget-char/jumbo, sget-short/jumbo
8798     */
8799    /* exop vBBBB, field@AAAAAAAA */
8800    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8801    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8802    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8803    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8804    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8805    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8806    cmp     r0, #0                      @ is resolved entry null?
8807    beq     .LOP_SGET_SHORT_JUMBO_resolve         @ yes, do resolve
8808.LOP_SGET_SHORT_JUMBO_finish: @ field ptr in r0
8809    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8810    @ no-op                             @ acquiring load
8811    FETCH(r2, 3)                        @ r2<- BBBB
8812    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8813    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8814    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8815    GOTO_OPCODE(ip)                     @ jump to next instruction
8816
8817
8818/* ------------------------------ */
8819    .balign 64
8820.L_OP_SPUT_JUMBO: /* 0x11b */
8821/* File: armv5te/OP_SPUT_JUMBO.S */
8822    /*
8823     * Jumbo 32-bit SPUT handler.
8824     *
8825     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8826     *      sput-short/jumbo
8827     */
8828    /* exop vBBBB, field@AAAAAAAA */
8829    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8830    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8831    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8832    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8833    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8834    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8835    cmp     r0, #0                      @ is resolved entry null?
8836    beq     .LOP_SPUT_JUMBO_resolve         @ yes, do resolve
8837.LOP_SPUT_JUMBO_finish:   @ field ptr in r0
8838    FETCH(r2, 3)                        @ r2<- BBBB
8839    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8840    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8841    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8842    @ no-op                             @ releasing store
8843    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8844    GOTO_OPCODE(ip)                     @ jump to next instruction
8845
8846/* ------------------------------ */
8847    .balign 64
8848.L_OP_SPUT_WIDE_JUMBO: /* 0x11c */
8849/* File: armv5te/OP_SPUT_WIDE_JUMBO.S */
8850    /*
8851     * Jumbo 64-bit SPUT handler.
8852     */
8853    /* sput-wide/jumbo vBBBB, field@AAAAAAAA */
8854    ldr     r0, [rGLUE, #offGlue_methodClassDex]  @ r0<- DvmDex
8855    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8856    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8857    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
8858    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8859    FETCH(r9, 3)                        @ r9<- BBBB
8860    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
8861    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BBBB]
8862    cmp     r2, #0                      @ is resolved entry null?
8863    beq     .LOP_SPUT_WIDE_JUMBO_resolve         @ yes, do resolve
8864.LOP_SPUT_WIDE_JUMBO_finish: @ field ptr in r2, BBBB in r9
8865    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8866    ldmia   r9, {r0-r1}                 @ r0/r1<- vBBBB/vBBBB+1
8867    GET_INST_OPCODE(r10)                @ extract opcode from rINST
8868    strd    r0, [r2, #offStaticField_value] @ field<- vBBBB/vBBBB+1
8869    GOTO_OPCODE(r10)                    @ jump to next instruction
8870
8871/* ------------------------------ */
8872    .balign 64
8873.L_OP_SPUT_OBJECT_JUMBO: /* 0x11d */
8874/* File: armv5te/OP_SPUT_OBJECT_JUMBO.S */
8875    /*
8876     * Jumbo 32-bit SPUT handler for objects
8877     */
8878    /* sput-object/jumbo vBBBB, field@AAAAAAAA */
8879    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8880    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8881    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8882    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8883    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8884    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8885    cmp     r0, #0                      @ is resolved entry null?
8886    bne     .LOP_SPUT_OBJECT_JUMBO_finish          @ no, continue
8887    ldr     r9, [rGLUE, #offGlue_method]    @ r9<- current method
8888    EXPORT_PC()                         @ resolve() could throw, so export now
8889    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
8890    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8891    cmp     r0, #0                      @ success?
8892    bne     .LOP_SPUT_OBJECT_JUMBO_finish          @ yes, finish
8893    b       common_exceptionThrown      @ no, handle exception
8894
8895/* ------------------------------ */
8896    .balign 64
8897.L_OP_SPUT_BOOLEAN_JUMBO: /* 0x11e */
8898/* File: armv5te/OP_SPUT_BOOLEAN_JUMBO.S */
8899/* File: armv5te/OP_SPUT_JUMBO.S */
8900    /*
8901     * Jumbo 32-bit SPUT handler.
8902     *
8903     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8904     *      sput-short/jumbo
8905     */
8906    /* exop vBBBB, field@AAAAAAAA */
8907    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8908    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8909    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8910    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8911    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8912    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8913    cmp     r0, #0                      @ is resolved entry null?
8914    beq     .LOP_SPUT_BOOLEAN_JUMBO_resolve         @ yes, do resolve
8915.LOP_SPUT_BOOLEAN_JUMBO_finish:   @ field ptr in r0
8916    FETCH(r2, 3)                        @ r2<- BBBB
8917    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8918    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8919    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8920    @ no-op                             @ releasing store
8921    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8922    GOTO_OPCODE(ip)                     @ jump to next instruction
8923
8924
8925/* ------------------------------ */
8926    .balign 64
8927.L_OP_SPUT_BYTE_JUMBO: /* 0x11f */
8928/* File: armv5te/OP_SPUT_BYTE_JUMBO.S */
8929/* File: armv5te/OP_SPUT_JUMBO.S */
8930    /*
8931     * Jumbo 32-bit SPUT handler.
8932     *
8933     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8934     *      sput-short/jumbo
8935     */
8936    /* exop vBBBB, field@AAAAAAAA */
8937    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8938    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8939    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8940    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8941    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8942    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8943    cmp     r0, #0                      @ is resolved entry null?
8944    beq     .LOP_SPUT_BYTE_JUMBO_resolve         @ yes, do resolve
8945.LOP_SPUT_BYTE_JUMBO_finish:   @ field ptr in r0
8946    FETCH(r2, 3)                        @ r2<- BBBB
8947    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8948    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8949    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8950    @ no-op                             @ releasing store
8951    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8952    GOTO_OPCODE(ip)                     @ jump to next instruction
8953
8954
8955/* ------------------------------ */
8956    .balign 64
8957.L_OP_SPUT_CHAR_JUMBO: /* 0x120 */
8958/* File: armv5te/OP_SPUT_CHAR_JUMBO.S */
8959/* File: armv5te/OP_SPUT_JUMBO.S */
8960    /*
8961     * Jumbo 32-bit SPUT handler.
8962     *
8963     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8964     *      sput-short/jumbo
8965     */
8966    /* exop vBBBB, field@AAAAAAAA */
8967    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8968    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8969    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8970    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8971    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8972    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8973    cmp     r0, #0                      @ is resolved entry null?
8974    beq     .LOP_SPUT_CHAR_JUMBO_resolve         @ yes, do resolve
8975.LOP_SPUT_CHAR_JUMBO_finish:   @ field ptr in r0
8976    FETCH(r2, 3)                        @ r2<- BBBB
8977    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8978    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8979    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8980    @ no-op                             @ releasing store
8981    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8982    GOTO_OPCODE(ip)                     @ jump to next instruction
8983
8984
8985/* ------------------------------ */
8986    .balign 64
8987.L_OP_SPUT_SHORT_JUMBO: /* 0x121 */
8988/* File: armv5te/OP_SPUT_SHORT_JUMBO.S */
8989/* File: armv5te/OP_SPUT_JUMBO.S */
8990    /*
8991     * Jumbo 32-bit SPUT handler.
8992     *
8993     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8994     *      sput-short/jumbo
8995     */
8996    /* exop vBBBB, field@AAAAAAAA */
8997    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8998    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8999    FETCH(r1, 2)                        @ r1<- AAAA (hi)
9000    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
9001    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
9002    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
9003    cmp     r0, #0                      @ is resolved entry null?
9004    beq     .LOP_SPUT_SHORT_JUMBO_resolve         @ yes, do resolve
9005.LOP_SPUT_SHORT_JUMBO_finish:   @ field ptr in r0
9006    FETCH(r2, 3)                        @ r2<- BBBB
9007    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
9008    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
9009    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9010    @ no-op                             @ releasing store
9011    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
9012    GOTO_OPCODE(ip)                     @ jump to next instruction
9013
9014
9015/* ------------------------------ */
9016    .balign 64
9017.L_OP_INVOKE_VIRTUAL_JUMBO: /* 0x122 */
9018/* File: armv5te/OP_INVOKE_VIRTUAL_JUMBO.S */
9019    /*
9020     * Handle a virtual method call.
9021     */
9022    /* invoke-virtual/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
9023    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
9024    FETCH(r0, 1)                        @ r1<- aaaa (lo)
9025    FETCH(r1, 2)                        @ r1<- AAAA (hi)
9026    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
9027    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
9028    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
9029    cmp     r0, #0                      @ already resolved?
9030    EXPORT_PC()                         @ must export for invoke
9031    bne     .LOP_INVOKE_VIRTUAL_JUMBO_continue        @ yes, continue on
9032    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
9033    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
9034    mov     r2, #METHOD_VIRTUAL         @ resolver method type
9035    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
9036    cmp     r0, #0                      @ got null?
9037    bne     .LOP_INVOKE_VIRTUAL_JUMBO_continue        @ no, continue
9038    b       common_exceptionThrown      @ yes, handle exception
9039
9040/* ------------------------------ */
9041    .balign 64
9042.L_OP_INVOKE_SUPER_JUMBO: /* 0x123 */
9043/* File: armv5te/OP_INVOKE_SUPER_JUMBO.S */
9044    /*
9045     * Handle a "super" method call.
9046     */
9047    /* invoke-super/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
9048    FETCH(r10, 4)                       @ r10<- CCCC
9049    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
9050    FETCH(r0, 1)                        @ r1<- aaaa (lo)
9051    FETCH(r1, 2)                        @ r1<- AAAA (hi)
9052    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
9053    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
9054    GET_VREG(r2, r10)                   @ r2<- "this" ptr
9055    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
9056    cmp     r2, #0                      @ null "this"?
9057    ldr     r9, [rGLUE, #offGlue_method] @ r9<- current method
9058    beq     common_errNullObject        @ null "this", throw exception
9059    cmp     r0, #0                      @ already resolved?
9060    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
9061    EXPORT_PC()                         @ must export for invoke
9062    bne     .LOP_INVOKE_SUPER_JUMBO_continue        @ resolved, continue on
9063    b       .LOP_INVOKE_SUPER_JUMBO_resolve         @ do resolve now
9064
9065/* ------------------------------ */
9066    .balign 64
9067.L_OP_INVOKE_DIRECT_JUMBO: /* 0x124 */
9068/* File: armv5te/OP_INVOKE_DIRECT_JUMBO.S */
9069    /*
9070     * Handle a direct method call.
9071     *
9072     * (We could defer the "is 'this' pointer null" test to the common
9073     * method invocation code, and use a flag to indicate that static
9074     * calls don't count.  If we do this as part of copying the arguments
9075     * out we could avoiding loading the first arg twice.)
9076     *
9077     */
9078    /* invoke-direct/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
9079    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
9080    FETCH(r0, 1)                        @ r1<- aaaa (lo)
9081    FETCH(r1, 2)                        @ r1<- AAAA (hi)
9082    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
9083    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
9084    FETCH(r10, 4)                       @ r10<- CCCC
9085    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
9086    cmp     r0, #0                      @ already resolved?
9087    EXPORT_PC()                         @ must export for invoke
9088    GET_VREG(r2, r10)                   @ r2<- "this" ptr
9089    beq     .LOP_INVOKE_DIRECT_JUMBO_resolve         @ not resolved, do it now
9090.LOP_INVOKE_DIRECT_JUMBO_finish:
9091    cmp     r2, #0                      @ null "this" ref?
9092    bne     common_invokeMethodJumbo    @ no, continue on
9093    b       common_errNullObject        @ yes, throw exception
9094
9095/* ------------------------------ */
9096    .balign 64
9097.L_OP_INVOKE_STATIC_JUMBO: /* 0x125 */
9098/* File: armv5te/OP_INVOKE_STATIC_JUMBO.S */
9099    /*
9100     * Handle a static method call.
9101     */
9102    /* invoke-static/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
9103    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
9104    FETCH(r0, 1)                        @ r1<- aaaa (lo)
9105    FETCH(r1, 2)                        @ r1<- AAAA (hi)
9106    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
9107    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
9108    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
9109    cmp     r0, #0                      @ already resolved?
9110    EXPORT_PC()                         @ must export for invoke
9111    bne     common_invokeMethodJumbo    @ yes, continue on
91120:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
9113    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
9114    mov     r2, #METHOD_STATIC          @ resolver method type
9115    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
9116    cmp     r0, #0                      @ got null?
9117    bne     common_invokeMethodJumbo    @ no, continue
9118    b       common_exceptionThrown      @ yes, handle exception
9119
9120/* ------------------------------ */
9121    .balign 64
9122.L_OP_INVOKE_INTERFACE_JUMBO: /* 0x126 */
9123/* File: armv5te/OP_INVOKE_INTERFACE_JUMBO.S */
9124    /*
9125     * Handle an interface method call.
9126     */
9127    /* invoke-interface/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
9128    FETCH(r2, 4)                        @ r2<- CCCC
9129    FETCH(r0, 1)                        @ r0<- aaaa (lo)
9130    FETCH(r1, 2)                        @ r1<- AAAA (hi)
9131    EXPORT_PC()                         @ must export for invoke
9132    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
9133    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
9134    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- methodClassDex
9135    cmp     r0, #0                      @ null obj?
9136    ldr     r2, [rGLUE, #offGlue_method]  @ r2<- method
9137    beq     common_errNullObject        @ yes, fail
9138    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
9139    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
9140    cmp     r0, #0                      @ failed?
9141    beq     common_exceptionThrown      @ yes, handle exception
9142    b       common_invokeMethodJumbo    @ jump to common handler
9143
9144/* ------------------------------ */
9145    .balign 64
9146.L_OP_UNUSED_27FF: /* 0x127 */
9147/* File: armv5te/OP_UNUSED_27FF.S */
9148/* File: armv5te/unused.S */
9149    bl      common_abort
9150
9151
9152/* ------------------------------ */
9153    .balign 64
9154.L_OP_UNUSED_28FF: /* 0x128 */
9155/* File: armv5te/OP_UNUSED_28FF.S */
9156/* File: armv5te/unused.S */
9157    bl      common_abort
9158
9159
9160/* ------------------------------ */
9161    .balign 64
9162.L_OP_UNUSED_29FF: /* 0x129 */
9163/* File: armv5te/OP_UNUSED_29FF.S */
9164/* File: armv5te/unused.S */
9165    bl      common_abort
9166
9167
9168/* ------------------------------ */
9169    .balign 64
9170.L_OP_UNUSED_2AFF: /* 0x12a */
9171/* File: armv5te/OP_UNUSED_2AFF.S */
9172/* File: armv5te/unused.S */
9173    bl      common_abort
9174
9175
9176/* ------------------------------ */
9177    .balign 64
9178.L_OP_UNUSED_2BFF: /* 0x12b */
9179/* File: armv5te/OP_UNUSED_2BFF.S */
9180/* File: armv5te/unused.S */
9181    bl      common_abort
9182
9183
9184/* ------------------------------ */
9185    .balign 64
9186.L_OP_UNUSED_2CFF: /* 0x12c */
9187/* File: armv5te/OP_UNUSED_2CFF.S */
9188/* File: armv5te/unused.S */
9189    bl      common_abort
9190
9191
9192/* ------------------------------ */
9193    .balign 64
9194.L_OP_UNUSED_2DFF: /* 0x12d */
9195/* File: armv5te/OP_UNUSED_2DFF.S */
9196/* File: armv5te/unused.S */
9197    bl      common_abort
9198
9199
9200/* ------------------------------ */
9201    .balign 64
9202.L_OP_UNUSED_2EFF: /* 0x12e */
9203/* File: armv5te/OP_UNUSED_2EFF.S */
9204/* File: armv5te/unused.S */
9205    bl      common_abort
9206
9207
9208/* ------------------------------ */
9209    .balign 64
9210.L_OP_UNUSED_2FFF: /* 0x12f */
9211/* File: armv5te/OP_UNUSED_2FFF.S */
9212/* File: armv5te/unused.S */
9213    bl      common_abort
9214
9215
9216/* ------------------------------ */
9217    .balign 64
9218.L_OP_UNUSED_30FF: /* 0x130 */
9219/* File: armv5te/OP_UNUSED_30FF.S */
9220/* File: armv5te/unused.S */
9221    bl      common_abort
9222
9223
9224/* ------------------------------ */
9225    .balign 64
9226.L_OP_UNUSED_31FF: /* 0x131 */
9227/* File: armv5te/OP_UNUSED_31FF.S */
9228/* File: armv5te/unused.S */
9229    bl      common_abort
9230
9231
9232/* ------------------------------ */
9233    .balign 64
9234.L_OP_UNUSED_32FF: /* 0x132 */
9235/* File: armv5te/OP_UNUSED_32FF.S */
9236/* File: armv5te/unused.S */
9237    bl      common_abort
9238
9239
9240/* ------------------------------ */
9241    .balign 64
9242.L_OP_UNUSED_33FF: /* 0x133 */
9243/* File: armv5te/OP_UNUSED_33FF.S */
9244/* File: armv5te/unused.S */
9245    bl      common_abort
9246
9247
9248/* ------------------------------ */
9249    .balign 64
9250.L_OP_UNUSED_34FF: /* 0x134 */
9251/* File: armv5te/OP_UNUSED_34FF.S */
9252/* File: armv5te/unused.S */
9253    bl      common_abort
9254
9255
9256/* ------------------------------ */
9257    .balign 64
9258.L_OP_UNUSED_35FF: /* 0x135 */
9259/* File: armv5te/OP_UNUSED_35FF.S */
9260/* File: armv5te/unused.S */
9261    bl      common_abort
9262
9263
9264/* ------------------------------ */
9265    .balign 64
9266.L_OP_UNUSED_36FF: /* 0x136 */
9267/* File: armv5te/OP_UNUSED_36FF.S */
9268/* File: armv5te/unused.S */
9269    bl      common_abort
9270
9271
9272/* ------------------------------ */
9273    .balign 64
9274.L_OP_UNUSED_37FF: /* 0x137 */
9275/* File: armv5te/OP_UNUSED_37FF.S */
9276/* File: armv5te/unused.S */
9277    bl      common_abort
9278
9279
9280/* ------------------------------ */
9281    .balign 64
9282.L_OP_UNUSED_38FF: /* 0x138 */
9283/* File: armv5te/OP_UNUSED_38FF.S */
9284/* File: armv5te/unused.S */
9285    bl      common_abort
9286
9287
9288/* ------------------------------ */
9289    .balign 64
9290.L_OP_UNUSED_39FF: /* 0x139 */
9291/* File: armv5te/OP_UNUSED_39FF.S */
9292/* File: armv5te/unused.S */
9293    bl      common_abort
9294
9295
9296/* ------------------------------ */
9297    .balign 64
9298.L_OP_UNUSED_3AFF: /* 0x13a */
9299/* File: armv5te/OP_UNUSED_3AFF.S */
9300/* File: armv5te/unused.S */
9301    bl      common_abort
9302
9303
9304/* ------------------------------ */
9305    .balign 64
9306.L_OP_UNUSED_3BFF: /* 0x13b */
9307/* File: armv5te/OP_UNUSED_3BFF.S */
9308/* File: armv5te/unused.S */
9309    bl      common_abort
9310
9311
9312/* ------------------------------ */
9313    .balign 64
9314.L_OP_UNUSED_3CFF: /* 0x13c */
9315/* File: armv5te/OP_UNUSED_3CFF.S */
9316/* File: armv5te/unused.S */
9317    bl      common_abort
9318
9319
9320/* ------------------------------ */
9321    .balign 64
9322.L_OP_UNUSED_3DFF: /* 0x13d */
9323/* File: armv5te/OP_UNUSED_3DFF.S */
9324/* File: armv5te/unused.S */
9325    bl      common_abort
9326
9327
9328/* ------------------------------ */
9329    .balign 64
9330.L_OP_UNUSED_3EFF: /* 0x13e */
9331/* File: armv5te/OP_UNUSED_3EFF.S */
9332/* File: armv5te/unused.S */
9333    bl      common_abort
9334
9335
9336/* ------------------------------ */
9337    .balign 64
9338.L_OP_UNUSED_3FFF: /* 0x13f */
9339/* File: armv5te/OP_UNUSED_3FFF.S */
9340/* File: armv5te/unused.S */
9341    bl      common_abort
9342
9343
9344/* ------------------------------ */
9345    .balign 64
9346.L_OP_UNUSED_40FF: /* 0x140 */
9347/* File: armv5te/OP_UNUSED_40FF.S */
9348/* File: armv5te/unused.S */
9349    bl      common_abort
9350
9351
9352/* ------------------------------ */
9353    .balign 64
9354.L_OP_UNUSED_41FF: /* 0x141 */
9355/* File: armv5te/OP_UNUSED_41FF.S */
9356/* File: armv5te/unused.S */
9357    bl      common_abort
9358
9359
9360/* ------------------------------ */
9361    .balign 64
9362.L_OP_UNUSED_42FF: /* 0x142 */
9363/* File: armv5te/OP_UNUSED_42FF.S */
9364/* File: armv5te/unused.S */
9365    bl      common_abort
9366
9367
9368/* ------------------------------ */
9369    .balign 64
9370.L_OP_UNUSED_43FF: /* 0x143 */
9371/* File: armv5te/OP_UNUSED_43FF.S */
9372/* File: armv5te/unused.S */
9373    bl      common_abort
9374
9375
9376/* ------------------------------ */
9377    .balign 64
9378.L_OP_UNUSED_44FF: /* 0x144 */
9379/* File: armv5te/OP_UNUSED_44FF.S */
9380/* File: armv5te/unused.S */
9381    bl      common_abort
9382
9383
9384/* ------------------------------ */
9385    .balign 64
9386.L_OP_UNUSED_45FF: /* 0x145 */
9387/* File: armv5te/OP_UNUSED_45FF.S */
9388/* File: armv5te/unused.S */
9389    bl      common_abort
9390
9391
9392/* ------------------------------ */
9393    .balign 64
9394.L_OP_UNUSED_46FF: /* 0x146 */
9395/* File: armv5te/OP_UNUSED_46FF.S */
9396/* File: armv5te/unused.S */
9397    bl      common_abort
9398
9399
9400/* ------------------------------ */
9401    .balign 64
9402.L_OP_UNUSED_47FF: /* 0x147 */
9403/* File: armv5te/OP_UNUSED_47FF.S */
9404/* File: armv5te/unused.S */
9405    bl      common_abort
9406
9407
9408/* ------------------------------ */
9409    .balign 64
9410.L_OP_UNUSED_48FF: /* 0x148 */
9411/* File: armv5te/OP_UNUSED_48FF.S */
9412/* File: armv5te/unused.S */
9413    bl      common_abort
9414
9415
9416/* ------------------------------ */
9417    .balign 64
9418.L_OP_UNUSED_49FF: /* 0x149 */
9419/* File: armv5te/OP_UNUSED_49FF.S */
9420/* File: armv5te/unused.S */
9421    bl      common_abort
9422
9423
9424/* ------------------------------ */
9425    .balign 64
9426.L_OP_UNUSED_4AFF: /* 0x14a */
9427/* File: armv5te/OP_UNUSED_4AFF.S */
9428/* File: armv5te/unused.S */
9429    bl      common_abort
9430
9431
9432/* ------------------------------ */
9433    .balign 64
9434.L_OP_UNUSED_4BFF: /* 0x14b */
9435/* File: armv5te/OP_UNUSED_4BFF.S */
9436/* File: armv5te/unused.S */
9437    bl      common_abort
9438
9439
9440/* ------------------------------ */
9441    .balign 64
9442.L_OP_UNUSED_4CFF: /* 0x14c */
9443/* File: armv5te/OP_UNUSED_4CFF.S */
9444/* File: armv5te/unused.S */
9445    bl      common_abort
9446
9447
9448/* ------------------------------ */
9449    .balign 64
9450.L_OP_UNUSED_4DFF: /* 0x14d */
9451/* File: armv5te/OP_UNUSED_4DFF.S */
9452/* File: armv5te/unused.S */
9453    bl      common_abort
9454
9455
9456/* ------------------------------ */
9457    .balign 64
9458.L_OP_UNUSED_4EFF: /* 0x14e */
9459/* File: armv5te/OP_UNUSED_4EFF.S */
9460/* File: armv5te/unused.S */
9461    bl      common_abort
9462
9463
9464/* ------------------------------ */
9465    .balign 64
9466.L_OP_UNUSED_4FFF: /* 0x14f */
9467/* File: armv5te/OP_UNUSED_4FFF.S */
9468/* File: armv5te/unused.S */
9469    bl      common_abort
9470
9471
9472/* ------------------------------ */
9473    .balign 64
9474.L_OP_UNUSED_50FF: /* 0x150 */
9475/* File: armv5te/OP_UNUSED_50FF.S */
9476/* File: armv5te/unused.S */
9477    bl      common_abort
9478
9479
9480/* ------------------------------ */
9481    .balign 64
9482.L_OP_UNUSED_51FF: /* 0x151 */
9483/* File: armv5te/OP_UNUSED_51FF.S */
9484/* File: armv5te/unused.S */
9485    bl      common_abort
9486
9487
9488/* ------------------------------ */
9489    .balign 64
9490.L_OP_UNUSED_52FF: /* 0x152 */
9491/* File: armv5te/OP_UNUSED_52FF.S */
9492/* File: armv5te/unused.S */
9493    bl      common_abort
9494
9495
9496/* ------------------------------ */
9497    .balign 64
9498.L_OP_UNUSED_53FF: /* 0x153 */
9499/* File: armv5te/OP_UNUSED_53FF.S */
9500/* File: armv5te/unused.S */
9501    bl      common_abort
9502
9503
9504/* ------------------------------ */
9505    .balign 64
9506.L_OP_UNUSED_54FF: /* 0x154 */
9507/* File: armv5te/OP_UNUSED_54FF.S */
9508/* File: armv5te/unused.S */
9509    bl      common_abort
9510
9511
9512/* ------------------------------ */
9513    .balign 64
9514.L_OP_UNUSED_55FF: /* 0x155 */
9515/* File: armv5te/OP_UNUSED_55FF.S */
9516/* File: armv5te/unused.S */
9517    bl      common_abort
9518
9519
9520/* ------------------------------ */
9521    .balign 64
9522.L_OP_UNUSED_56FF: /* 0x156 */
9523/* File: armv5te/OP_UNUSED_56FF.S */
9524/* File: armv5te/unused.S */
9525    bl      common_abort
9526
9527
9528/* ------------------------------ */
9529    .balign 64
9530.L_OP_UNUSED_57FF: /* 0x157 */
9531/* File: armv5te/OP_UNUSED_57FF.S */
9532/* File: armv5te/unused.S */
9533    bl      common_abort
9534
9535
9536/* ------------------------------ */
9537    .balign 64
9538.L_OP_UNUSED_58FF: /* 0x158 */
9539/* File: armv5te/OP_UNUSED_58FF.S */
9540/* File: armv5te/unused.S */
9541    bl      common_abort
9542
9543
9544/* ------------------------------ */
9545    .balign 64
9546.L_OP_UNUSED_59FF: /* 0x159 */
9547/* File: armv5te/OP_UNUSED_59FF.S */
9548/* File: armv5te/unused.S */
9549    bl      common_abort
9550
9551
9552/* ------------------------------ */
9553    .balign 64
9554.L_OP_UNUSED_5AFF: /* 0x15a */
9555/* File: armv5te/OP_UNUSED_5AFF.S */
9556/* File: armv5te/unused.S */
9557    bl      common_abort
9558
9559
9560/* ------------------------------ */
9561    .balign 64
9562.L_OP_UNUSED_5BFF: /* 0x15b */
9563/* File: armv5te/OP_UNUSED_5BFF.S */
9564/* File: armv5te/unused.S */
9565    bl      common_abort
9566
9567
9568/* ------------------------------ */
9569    .balign 64
9570.L_OP_UNUSED_5CFF: /* 0x15c */
9571/* File: armv5te/OP_UNUSED_5CFF.S */
9572/* File: armv5te/unused.S */
9573    bl      common_abort
9574
9575
9576/* ------------------------------ */
9577    .balign 64
9578.L_OP_UNUSED_5DFF: /* 0x15d */
9579/* File: armv5te/OP_UNUSED_5DFF.S */
9580/* File: armv5te/unused.S */
9581    bl      common_abort
9582
9583
9584/* ------------------------------ */
9585    .balign 64
9586.L_OP_UNUSED_5EFF: /* 0x15e */
9587/* File: armv5te/OP_UNUSED_5EFF.S */
9588/* File: armv5te/unused.S */
9589    bl      common_abort
9590
9591
9592/* ------------------------------ */
9593    .balign 64
9594.L_OP_UNUSED_5FFF: /* 0x15f */
9595/* File: armv5te/OP_UNUSED_5FFF.S */
9596/* File: armv5te/unused.S */
9597    bl      common_abort
9598
9599
9600/* ------------------------------ */
9601    .balign 64
9602.L_OP_UNUSED_60FF: /* 0x160 */
9603/* File: armv5te/OP_UNUSED_60FF.S */
9604/* File: armv5te/unused.S */
9605    bl      common_abort
9606
9607
9608/* ------------------------------ */
9609    .balign 64
9610.L_OP_UNUSED_61FF: /* 0x161 */
9611/* File: armv5te/OP_UNUSED_61FF.S */
9612/* File: armv5te/unused.S */
9613    bl      common_abort
9614
9615
9616/* ------------------------------ */
9617    .balign 64
9618.L_OP_UNUSED_62FF: /* 0x162 */
9619/* File: armv5te/OP_UNUSED_62FF.S */
9620/* File: armv5te/unused.S */
9621    bl      common_abort
9622
9623
9624/* ------------------------------ */
9625    .balign 64
9626.L_OP_UNUSED_63FF: /* 0x163 */
9627/* File: armv5te/OP_UNUSED_63FF.S */
9628/* File: armv5te/unused.S */
9629    bl      common_abort
9630
9631
9632/* ------------------------------ */
9633    .balign 64
9634.L_OP_UNUSED_64FF: /* 0x164 */
9635/* File: armv5te/OP_UNUSED_64FF.S */
9636/* File: armv5te/unused.S */
9637    bl      common_abort
9638
9639
9640/* ------------------------------ */
9641    .balign 64
9642.L_OP_UNUSED_65FF: /* 0x165 */
9643/* File: armv5te/OP_UNUSED_65FF.S */
9644/* File: armv5te/unused.S */
9645    bl      common_abort
9646
9647
9648/* ------------------------------ */
9649    .balign 64
9650.L_OP_UNUSED_66FF: /* 0x166 */
9651/* File: armv5te/OP_UNUSED_66FF.S */
9652/* File: armv5te/unused.S */
9653    bl      common_abort
9654
9655
9656/* ------------------------------ */
9657    .balign 64
9658.L_OP_UNUSED_67FF: /* 0x167 */
9659/* File: armv5te/OP_UNUSED_67FF.S */
9660/* File: armv5te/unused.S */
9661    bl      common_abort
9662
9663
9664/* ------------------------------ */
9665    .balign 64
9666.L_OP_UNUSED_68FF: /* 0x168 */
9667/* File: armv5te/OP_UNUSED_68FF.S */
9668/* File: armv5te/unused.S */
9669    bl      common_abort
9670
9671
9672/* ------------------------------ */
9673    .balign 64
9674.L_OP_UNUSED_69FF: /* 0x169 */
9675/* File: armv5te/OP_UNUSED_69FF.S */
9676/* File: armv5te/unused.S */
9677    bl      common_abort
9678
9679
9680/* ------------------------------ */
9681    .balign 64
9682.L_OP_UNUSED_6AFF: /* 0x16a */
9683/* File: armv5te/OP_UNUSED_6AFF.S */
9684/* File: armv5te/unused.S */
9685    bl      common_abort
9686
9687
9688/* ------------------------------ */
9689    .balign 64
9690.L_OP_UNUSED_6BFF: /* 0x16b */
9691/* File: armv5te/OP_UNUSED_6BFF.S */
9692/* File: armv5te/unused.S */
9693    bl      common_abort
9694
9695
9696/* ------------------------------ */
9697    .balign 64
9698.L_OP_UNUSED_6CFF: /* 0x16c */
9699/* File: armv5te/OP_UNUSED_6CFF.S */
9700/* File: armv5te/unused.S */
9701    bl      common_abort
9702
9703
9704/* ------------------------------ */
9705    .balign 64
9706.L_OP_UNUSED_6DFF: /* 0x16d */
9707/* File: armv5te/OP_UNUSED_6DFF.S */
9708/* File: armv5te/unused.S */
9709    bl      common_abort
9710
9711
9712/* ------------------------------ */
9713    .balign 64
9714.L_OP_UNUSED_6EFF: /* 0x16e */
9715/* File: armv5te/OP_UNUSED_6EFF.S */
9716/* File: armv5te/unused.S */
9717    bl      common_abort
9718
9719
9720/* ------------------------------ */
9721    .balign 64
9722.L_OP_UNUSED_6FFF: /* 0x16f */
9723/* File: armv5te/OP_UNUSED_6FFF.S */
9724/* File: armv5te/unused.S */
9725    bl      common_abort
9726
9727
9728/* ------------------------------ */
9729    .balign 64
9730.L_OP_UNUSED_70FF: /* 0x170 */
9731/* File: armv5te/OP_UNUSED_70FF.S */
9732/* File: armv5te/unused.S */
9733    bl      common_abort
9734
9735
9736/* ------------------------------ */
9737    .balign 64
9738.L_OP_UNUSED_71FF: /* 0x171 */
9739/* File: armv5te/OP_UNUSED_71FF.S */
9740/* File: armv5te/unused.S */
9741    bl      common_abort
9742
9743
9744/* ------------------------------ */
9745    .balign 64
9746.L_OP_UNUSED_72FF: /* 0x172 */
9747/* File: armv5te/OP_UNUSED_72FF.S */
9748/* File: armv5te/unused.S */
9749    bl      common_abort
9750
9751
9752/* ------------------------------ */
9753    .balign 64
9754.L_OP_UNUSED_73FF: /* 0x173 */
9755/* File: armv5te/OP_UNUSED_73FF.S */
9756/* File: armv5te/unused.S */
9757    bl      common_abort
9758
9759
9760/* ------------------------------ */
9761    .balign 64
9762.L_OP_UNUSED_74FF: /* 0x174 */
9763/* File: armv5te/OP_UNUSED_74FF.S */
9764/* File: armv5te/unused.S */
9765    bl      common_abort
9766
9767
9768/* ------------------------------ */
9769    .balign 64
9770.L_OP_UNUSED_75FF: /* 0x175 */
9771/* File: armv5te/OP_UNUSED_75FF.S */
9772/* File: armv5te/unused.S */
9773    bl      common_abort
9774
9775
9776/* ------------------------------ */
9777    .balign 64
9778.L_OP_UNUSED_76FF: /* 0x176 */
9779/* File: armv5te/OP_UNUSED_76FF.S */
9780/* File: armv5te/unused.S */
9781    bl      common_abort
9782
9783
9784/* ------------------------------ */
9785    .balign 64
9786.L_OP_UNUSED_77FF: /* 0x177 */
9787/* File: armv5te/OP_UNUSED_77FF.S */
9788/* File: armv5te/unused.S */
9789    bl      common_abort
9790
9791
9792/* ------------------------------ */
9793    .balign 64
9794.L_OP_UNUSED_78FF: /* 0x178 */
9795/* File: armv5te/OP_UNUSED_78FF.S */
9796/* File: armv5te/unused.S */
9797    bl      common_abort
9798
9799
9800/* ------------------------------ */
9801    .balign 64
9802.L_OP_UNUSED_79FF: /* 0x179 */
9803/* File: armv5te/OP_UNUSED_79FF.S */
9804/* File: armv5te/unused.S */
9805    bl      common_abort
9806
9807
9808/* ------------------------------ */
9809    .balign 64
9810.L_OP_UNUSED_7AFF: /* 0x17a */
9811/* File: armv5te/OP_UNUSED_7AFF.S */
9812/* File: armv5te/unused.S */
9813    bl      common_abort
9814
9815
9816/* ------------------------------ */
9817    .balign 64
9818.L_OP_UNUSED_7BFF: /* 0x17b */
9819/* File: armv5te/OP_UNUSED_7BFF.S */
9820/* File: armv5te/unused.S */
9821    bl      common_abort
9822
9823
9824/* ------------------------------ */
9825    .balign 64
9826.L_OP_UNUSED_7CFF: /* 0x17c */
9827/* File: armv5te/OP_UNUSED_7CFF.S */
9828/* File: armv5te/unused.S */
9829    bl      common_abort
9830
9831
9832/* ------------------------------ */
9833    .balign 64
9834.L_OP_UNUSED_7DFF: /* 0x17d */
9835/* File: armv5te/OP_UNUSED_7DFF.S */
9836/* File: armv5te/unused.S */
9837    bl      common_abort
9838
9839
9840/* ------------------------------ */
9841    .balign 64
9842.L_OP_UNUSED_7EFF: /* 0x17e */
9843/* File: armv5te/OP_UNUSED_7EFF.S */
9844/* File: armv5te/unused.S */
9845    bl      common_abort
9846
9847
9848/* ------------------------------ */
9849    .balign 64
9850.L_OP_UNUSED_7FFF: /* 0x17f */
9851/* File: armv5te/OP_UNUSED_7FFF.S */
9852/* File: armv5te/unused.S */
9853    bl      common_abort
9854
9855
9856/* ------------------------------ */
9857    .balign 64
9858.L_OP_UNUSED_80FF: /* 0x180 */
9859/* File: armv5te/OP_UNUSED_80FF.S */
9860/* File: armv5te/unused.S */
9861    bl      common_abort
9862
9863
9864/* ------------------------------ */
9865    .balign 64
9866.L_OP_UNUSED_81FF: /* 0x181 */
9867/* File: armv5te/OP_UNUSED_81FF.S */
9868/* File: armv5te/unused.S */
9869    bl      common_abort
9870
9871
9872/* ------------------------------ */
9873    .balign 64
9874.L_OP_UNUSED_82FF: /* 0x182 */
9875/* File: armv5te/OP_UNUSED_82FF.S */
9876/* File: armv5te/unused.S */
9877    bl      common_abort
9878
9879
9880/* ------------------------------ */
9881    .balign 64
9882.L_OP_UNUSED_83FF: /* 0x183 */
9883/* File: armv5te/OP_UNUSED_83FF.S */
9884/* File: armv5te/unused.S */
9885    bl      common_abort
9886
9887
9888/* ------------------------------ */
9889    .balign 64
9890.L_OP_UNUSED_84FF: /* 0x184 */
9891/* File: armv5te/OP_UNUSED_84FF.S */
9892/* File: armv5te/unused.S */
9893    bl      common_abort
9894
9895
9896/* ------------------------------ */
9897    .balign 64
9898.L_OP_UNUSED_85FF: /* 0x185 */
9899/* File: armv5te/OP_UNUSED_85FF.S */
9900/* File: armv5te/unused.S */
9901    bl      common_abort
9902
9903
9904/* ------------------------------ */
9905    .balign 64
9906.L_OP_UNUSED_86FF: /* 0x186 */
9907/* File: armv5te/OP_UNUSED_86FF.S */
9908/* File: armv5te/unused.S */
9909    bl      common_abort
9910
9911
9912/* ------------------------------ */
9913    .balign 64
9914.L_OP_UNUSED_87FF: /* 0x187 */
9915/* File: armv5te/OP_UNUSED_87FF.S */
9916/* File: armv5te/unused.S */
9917    bl      common_abort
9918
9919
9920/* ------------------------------ */
9921    .balign 64
9922.L_OP_UNUSED_88FF: /* 0x188 */
9923/* File: armv5te/OP_UNUSED_88FF.S */
9924/* File: armv5te/unused.S */
9925    bl      common_abort
9926
9927
9928/* ------------------------------ */
9929    .balign 64
9930.L_OP_UNUSED_89FF: /* 0x189 */
9931/* File: armv5te/OP_UNUSED_89FF.S */
9932/* File: armv5te/unused.S */
9933    bl      common_abort
9934
9935
9936/* ------------------------------ */
9937    .balign 64
9938.L_OP_UNUSED_8AFF: /* 0x18a */
9939/* File: armv5te/OP_UNUSED_8AFF.S */
9940/* File: armv5te/unused.S */
9941    bl      common_abort
9942
9943
9944/* ------------------------------ */
9945    .balign 64
9946.L_OP_UNUSED_8BFF: /* 0x18b */
9947/* File: armv5te/OP_UNUSED_8BFF.S */
9948/* File: armv5te/unused.S */
9949    bl      common_abort
9950
9951
9952/* ------------------------------ */
9953    .balign 64
9954.L_OP_UNUSED_8CFF: /* 0x18c */
9955/* File: armv5te/OP_UNUSED_8CFF.S */
9956/* File: armv5te/unused.S */
9957    bl      common_abort
9958
9959
9960/* ------------------------------ */
9961    .balign 64
9962.L_OP_UNUSED_8DFF: /* 0x18d */
9963/* File: armv5te/OP_UNUSED_8DFF.S */
9964/* File: armv5te/unused.S */
9965    bl      common_abort
9966
9967
9968/* ------------------------------ */
9969    .balign 64
9970.L_OP_UNUSED_8EFF: /* 0x18e */
9971/* File: armv5te/OP_UNUSED_8EFF.S */
9972/* File: armv5te/unused.S */
9973    bl      common_abort
9974
9975
9976/* ------------------------------ */
9977    .balign 64
9978.L_OP_UNUSED_8FFF: /* 0x18f */
9979/* File: armv5te/OP_UNUSED_8FFF.S */
9980/* File: armv5te/unused.S */
9981    bl      common_abort
9982
9983
9984/* ------------------------------ */
9985    .balign 64
9986.L_OP_UNUSED_90FF: /* 0x190 */
9987/* File: armv5te/OP_UNUSED_90FF.S */
9988/* File: armv5te/unused.S */
9989    bl      common_abort
9990
9991
9992/* ------------------------------ */
9993    .balign 64
9994.L_OP_UNUSED_91FF: /* 0x191 */
9995/* File: armv5te/OP_UNUSED_91FF.S */
9996/* File: armv5te/unused.S */
9997    bl      common_abort
9998
9999
10000/* ------------------------------ */
10001    .balign 64
10002.L_OP_UNUSED_92FF: /* 0x192 */
10003/* File: armv5te/OP_UNUSED_92FF.S */
10004/* File: armv5te/unused.S */
10005    bl      common_abort
10006
10007
10008/* ------------------------------ */
10009    .balign 64
10010.L_OP_UNUSED_93FF: /* 0x193 */
10011/* File: armv5te/OP_UNUSED_93FF.S */
10012/* File: armv5te/unused.S */
10013    bl      common_abort
10014
10015
10016/* ------------------------------ */
10017    .balign 64
10018.L_OP_UNUSED_94FF: /* 0x194 */
10019/* File: armv5te/OP_UNUSED_94FF.S */
10020/* File: armv5te/unused.S */
10021    bl      common_abort
10022
10023
10024/* ------------------------------ */
10025    .balign 64
10026.L_OP_UNUSED_95FF: /* 0x195 */
10027/* File: armv5te/OP_UNUSED_95FF.S */
10028/* File: armv5te/unused.S */
10029    bl      common_abort
10030
10031
10032/* ------------------------------ */
10033    .balign 64
10034.L_OP_UNUSED_96FF: /* 0x196 */
10035/* File: armv5te/OP_UNUSED_96FF.S */
10036/* File: armv5te/unused.S */
10037    bl      common_abort
10038
10039
10040/* ------------------------------ */
10041    .balign 64
10042.L_OP_UNUSED_97FF: /* 0x197 */
10043/* File: armv5te/OP_UNUSED_97FF.S */
10044/* File: armv5te/unused.S */
10045    bl      common_abort
10046
10047
10048/* ------------------------------ */
10049    .balign 64
10050.L_OP_UNUSED_98FF: /* 0x198 */
10051/* File: armv5te/OP_UNUSED_98FF.S */
10052/* File: armv5te/unused.S */
10053    bl      common_abort
10054
10055
10056/* ------------------------------ */
10057    .balign 64
10058.L_OP_UNUSED_99FF: /* 0x199 */
10059/* File: armv5te/OP_UNUSED_99FF.S */
10060/* File: armv5te/unused.S */
10061    bl      common_abort
10062
10063
10064/* ------------------------------ */
10065    .balign 64
10066.L_OP_UNUSED_9AFF: /* 0x19a */
10067/* File: armv5te/OP_UNUSED_9AFF.S */
10068/* File: armv5te/unused.S */
10069    bl      common_abort
10070
10071
10072/* ------------------------------ */
10073    .balign 64
10074.L_OP_UNUSED_9BFF: /* 0x19b */
10075/* File: armv5te/OP_UNUSED_9BFF.S */
10076/* File: armv5te/unused.S */
10077    bl      common_abort
10078
10079
10080/* ------------------------------ */
10081    .balign 64
10082.L_OP_UNUSED_9CFF: /* 0x19c */
10083/* File: armv5te/OP_UNUSED_9CFF.S */
10084/* File: armv5te/unused.S */
10085    bl      common_abort
10086
10087
10088/* ------------------------------ */
10089    .balign 64
10090.L_OP_UNUSED_9DFF: /* 0x19d */
10091/* File: armv5te/OP_UNUSED_9DFF.S */
10092/* File: armv5te/unused.S */
10093    bl      common_abort
10094
10095
10096/* ------------------------------ */
10097    .balign 64
10098.L_OP_UNUSED_9EFF: /* 0x19e */
10099/* File: armv5te/OP_UNUSED_9EFF.S */
10100/* File: armv5te/unused.S */
10101    bl      common_abort
10102
10103
10104/* ------------------------------ */
10105    .balign 64
10106.L_OP_UNUSED_9FFF: /* 0x19f */
10107/* File: armv5te/OP_UNUSED_9FFF.S */
10108/* File: armv5te/unused.S */
10109    bl      common_abort
10110
10111
10112/* ------------------------------ */
10113    .balign 64
10114.L_OP_UNUSED_A0FF: /* 0x1a0 */
10115/* File: armv5te/OP_UNUSED_A0FF.S */
10116/* File: armv5te/unused.S */
10117    bl      common_abort
10118
10119
10120/* ------------------------------ */
10121    .balign 64
10122.L_OP_UNUSED_A1FF: /* 0x1a1 */
10123/* File: armv5te/OP_UNUSED_A1FF.S */
10124/* File: armv5te/unused.S */
10125    bl      common_abort
10126
10127
10128/* ------------------------------ */
10129    .balign 64
10130.L_OP_UNUSED_A2FF: /* 0x1a2 */
10131/* File: armv5te/OP_UNUSED_A2FF.S */
10132/* File: armv5te/unused.S */
10133    bl      common_abort
10134
10135
10136/* ------------------------------ */
10137    .balign 64
10138.L_OP_UNUSED_A3FF: /* 0x1a3 */
10139/* File: armv5te/OP_UNUSED_A3FF.S */
10140/* File: armv5te/unused.S */
10141    bl      common_abort
10142
10143
10144/* ------------------------------ */
10145    .balign 64
10146.L_OP_UNUSED_A4FF: /* 0x1a4 */
10147/* File: armv5te/OP_UNUSED_A4FF.S */
10148/* File: armv5te/unused.S */
10149    bl      common_abort
10150
10151
10152/* ------------------------------ */
10153    .balign 64
10154.L_OP_UNUSED_A5FF: /* 0x1a5 */
10155/* File: armv5te/OP_UNUSED_A5FF.S */
10156/* File: armv5te/unused.S */
10157    bl      common_abort
10158
10159
10160/* ------------------------------ */
10161    .balign 64
10162.L_OP_UNUSED_A6FF: /* 0x1a6 */
10163/* File: armv5te/OP_UNUSED_A6FF.S */
10164/* File: armv5te/unused.S */
10165    bl      common_abort
10166
10167
10168/* ------------------------------ */
10169    .balign 64
10170.L_OP_UNUSED_A7FF: /* 0x1a7 */
10171/* File: armv5te/OP_UNUSED_A7FF.S */
10172/* File: armv5te/unused.S */
10173    bl      common_abort
10174
10175
10176/* ------------------------------ */
10177    .balign 64
10178.L_OP_UNUSED_A8FF: /* 0x1a8 */
10179/* File: armv5te/OP_UNUSED_A8FF.S */
10180/* File: armv5te/unused.S */
10181    bl      common_abort
10182
10183
10184/* ------------------------------ */
10185    .balign 64
10186.L_OP_UNUSED_A9FF: /* 0x1a9 */
10187/* File: armv5te/OP_UNUSED_A9FF.S */
10188/* File: armv5te/unused.S */
10189    bl      common_abort
10190
10191
10192/* ------------------------------ */
10193    .balign 64
10194.L_OP_UNUSED_AAFF: /* 0x1aa */
10195/* File: armv5te/OP_UNUSED_AAFF.S */
10196/* File: armv5te/unused.S */
10197    bl      common_abort
10198
10199
10200/* ------------------------------ */
10201    .balign 64
10202.L_OP_UNUSED_ABFF: /* 0x1ab */
10203/* File: armv5te/OP_UNUSED_ABFF.S */
10204/* File: armv5te/unused.S */
10205    bl      common_abort
10206
10207
10208/* ------------------------------ */
10209    .balign 64
10210.L_OP_UNUSED_ACFF: /* 0x1ac */
10211/* File: armv5te/OP_UNUSED_ACFF.S */
10212/* File: armv5te/unused.S */
10213    bl      common_abort
10214
10215
10216/* ------------------------------ */
10217    .balign 64
10218.L_OP_UNUSED_ADFF: /* 0x1ad */
10219/* File: armv5te/OP_UNUSED_ADFF.S */
10220/* File: armv5te/unused.S */
10221    bl      common_abort
10222
10223
10224/* ------------------------------ */
10225    .balign 64
10226.L_OP_UNUSED_AEFF: /* 0x1ae */
10227/* File: armv5te/OP_UNUSED_AEFF.S */
10228/* File: armv5te/unused.S */
10229    bl      common_abort
10230
10231
10232/* ------------------------------ */
10233    .balign 64
10234.L_OP_UNUSED_AFFF: /* 0x1af */
10235/* File: armv5te/OP_UNUSED_AFFF.S */
10236/* File: armv5te/unused.S */
10237    bl      common_abort
10238
10239
10240/* ------------------------------ */
10241    .balign 64
10242.L_OP_UNUSED_B0FF: /* 0x1b0 */
10243/* File: armv5te/OP_UNUSED_B0FF.S */
10244/* File: armv5te/unused.S */
10245    bl      common_abort
10246
10247
10248/* ------------------------------ */
10249    .balign 64
10250.L_OP_UNUSED_B1FF: /* 0x1b1 */
10251/* File: armv5te/OP_UNUSED_B1FF.S */
10252/* File: armv5te/unused.S */
10253    bl      common_abort
10254
10255
10256/* ------------------------------ */
10257    .balign 64
10258.L_OP_UNUSED_B2FF: /* 0x1b2 */
10259/* File: armv5te/OP_UNUSED_B2FF.S */
10260/* File: armv5te/unused.S */
10261    bl      common_abort
10262
10263
10264/* ------------------------------ */
10265    .balign 64
10266.L_OP_UNUSED_B3FF: /* 0x1b3 */
10267/* File: armv5te/OP_UNUSED_B3FF.S */
10268/* File: armv5te/unused.S */
10269    bl      common_abort
10270
10271
10272/* ------------------------------ */
10273    .balign 64
10274.L_OP_UNUSED_B4FF: /* 0x1b4 */
10275/* File: armv5te/OP_UNUSED_B4FF.S */
10276/* File: armv5te/unused.S */
10277    bl      common_abort
10278
10279
10280/* ------------------------------ */
10281    .balign 64
10282.L_OP_UNUSED_B5FF: /* 0x1b5 */
10283/* File: armv5te/OP_UNUSED_B5FF.S */
10284/* File: armv5te/unused.S */
10285    bl      common_abort
10286
10287
10288/* ------------------------------ */
10289    .balign 64
10290.L_OP_UNUSED_B6FF: /* 0x1b6 */
10291/* File: armv5te/OP_UNUSED_B6FF.S */
10292/* File: armv5te/unused.S */
10293    bl      common_abort
10294
10295
10296/* ------------------------------ */
10297    .balign 64
10298.L_OP_UNUSED_B7FF: /* 0x1b7 */
10299/* File: armv5te/OP_UNUSED_B7FF.S */
10300/* File: armv5te/unused.S */
10301    bl      common_abort
10302
10303
10304/* ------------------------------ */
10305    .balign 64
10306.L_OP_UNUSED_B8FF: /* 0x1b8 */
10307/* File: armv5te/OP_UNUSED_B8FF.S */
10308/* File: armv5te/unused.S */
10309    bl      common_abort
10310
10311
10312/* ------------------------------ */
10313    .balign 64
10314.L_OP_UNUSED_B9FF: /* 0x1b9 */
10315/* File: armv5te/OP_UNUSED_B9FF.S */
10316/* File: armv5te/unused.S */
10317    bl      common_abort
10318
10319
10320/* ------------------------------ */
10321    .balign 64
10322.L_OP_UNUSED_BAFF: /* 0x1ba */
10323/* File: armv5te/OP_UNUSED_BAFF.S */
10324/* File: armv5te/unused.S */
10325    bl      common_abort
10326
10327
10328/* ------------------------------ */
10329    .balign 64
10330.L_OP_UNUSED_BBFF: /* 0x1bb */
10331/* File: armv5te/OP_UNUSED_BBFF.S */
10332/* File: armv5te/unused.S */
10333    bl      common_abort
10334
10335
10336/* ------------------------------ */
10337    .balign 64
10338.L_OP_UNUSED_BCFF: /* 0x1bc */
10339/* File: armv5te/OP_UNUSED_BCFF.S */
10340/* File: armv5te/unused.S */
10341    bl      common_abort
10342
10343
10344/* ------------------------------ */
10345    .balign 64
10346.L_OP_UNUSED_BDFF: /* 0x1bd */
10347/* File: armv5te/OP_UNUSED_BDFF.S */
10348/* File: armv5te/unused.S */
10349    bl      common_abort
10350
10351
10352/* ------------------------------ */
10353    .balign 64
10354.L_OP_UNUSED_BEFF: /* 0x1be */
10355/* File: armv5te/OP_UNUSED_BEFF.S */
10356/* File: armv5te/unused.S */
10357    bl      common_abort
10358
10359
10360/* ------------------------------ */
10361    .balign 64
10362.L_OP_UNUSED_BFFF: /* 0x1bf */
10363/* File: armv5te/OP_UNUSED_BFFF.S */
10364/* File: armv5te/unused.S */
10365    bl      common_abort
10366
10367
10368/* ------------------------------ */
10369    .balign 64
10370.L_OP_UNUSED_C0FF: /* 0x1c0 */
10371/* File: armv5te/OP_UNUSED_C0FF.S */
10372/* File: armv5te/unused.S */
10373    bl      common_abort
10374
10375
10376/* ------------------------------ */
10377    .balign 64
10378.L_OP_UNUSED_C1FF: /* 0x1c1 */
10379/* File: armv5te/OP_UNUSED_C1FF.S */
10380/* File: armv5te/unused.S */
10381    bl      common_abort
10382
10383
10384/* ------------------------------ */
10385    .balign 64
10386.L_OP_UNUSED_C2FF: /* 0x1c2 */
10387/* File: armv5te/OP_UNUSED_C2FF.S */
10388/* File: armv5te/unused.S */
10389    bl      common_abort
10390
10391
10392/* ------------------------------ */
10393    .balign 64
10394.L_OP_UNUSED_C3FF: /* 0x1c3 */
10395/* File: armv5te/OP_UNUSED_C3FF.S */
10396/* File: armv5te/unused.S */
10397    bl      common_abort
10398
10399
10400/* ------------------------------ */
10401    .balign 64
10402.L_OP_UNUSED_C4FF: /* 0x1c4 */
10403/* File: armv5te/OP_UNUSED_C4FF.S */
10404/* File: armv5te/unused.S */
10405    bl      common_abort
10406
10407
10408/* ------------------------------ */
10409    .balign 64
10410.L_OP_UNUSED_C5FF: /* 0x1c5 */
10411/* File: armv5te/OP_UNUSED_C5FF.S */
10412/* File: armv5te/unused.S */
10413    bl      common_abort
10414
10415
10416/* ------------------------------ */
10417    .balign 64
10418.L_OP_UNUSED_C6FF: /* 0x1c6 */
10419/* File: armv5te/OP_UNUSED_C6FF.S */
10420/* File: armv5te/unused.S */
10421    bl      common_abort
10422
10423
10424/* ------------------------------ */
10425    .balign 64
10426.L_OP_UNUSED_C7FF: /* 0x1c7 */
10427/* File: armv5te/OP_UNUSED_C7FF.S */
10428/* File: armv5te/unused.S */
10429    bl      common_abort
10430
10431
10432/* ------------------------------ */
10433    .balign 64
10434.L_OP_UNUSED_C8FF: /* 0x1c8 */
10435/* File: armv5te/OP_UNUSED_C8FF.S */
10436/* File: armv5te/unused.S */
10437    bl      common_abort
10438
10439
10440/* ------------------------------ */
10441    .balign 64
10442.L_OP_UNUSED_C9FF: /* 0x1c9 */
10443/* File: armv5te/OP_UNUSED_C9FF.S */
10444/* File: armv5te/unused.S */
10445    bl      common_abort
10446
10447
10448/* ------------------------------ */
10449    .balign 64
10450.L_OP_UNUSED_CAFF: /* 0x1ca */
10451/* File: armv5te/OP_UNUSED_CAFF.S */
10452/* File: armv5te/unused.S */
10453    bl      common_abort
10454
10455
10456/* ------------------------------ */
10457    .balign 64
10458.L_OP_UNUSED_CBFF: /* 0x1cb */
10459/* File: armv5te/OP_UNUSED_CBFF.S */
10460/* File: armv5te/unused.S */
10461    bl      common_abort
10462
10463
10464/* ------------------------------ */
10465    .balign 64
10466.L_OP_UNUSED_CCFF: /* 0x1cc */
10467/* File: armv5te/OP_UNUSED_CCFF.S */
10468/* File: armv5te/unused.S */
10469    bl      common_abort
10470
10471
10472/* ------------------------------ */
10473    .balign 64
10474.L_OP_UNUSED_CDFF: /* 0x1cd */
10475/* File: armv5te/OP_UNUSED_CDFF.S */
10476/* File: armv5te/unused.S */
10477    bl      common_abort
10478
10479
10480/* ------------------------------ */
10481    .balign 64
10482.L_OP_UNUSED_CEFF: /* 0x1ce */
10483/* File: armv5te/OP_UNUSED_CEFF.S */
10484/* File: armv5te/unused.S */
10485    bl      common_abort
10486
10487
10488/* ------------------------------ */
10489    .balign 64
10490.L_OP_UNUSED_CFFF: /* 0x1cf */
10491/* File: armv5te/OP_UNUSED_CFFF.S */
10492/* File: armv5te/unused.S */
10493    bl      common_abort
10494
10495
10496/* ------------------------------ */
10497    .balign 64
10498.L_OP_UNUSED_D0FF: /* 0x1d0 */
10499/* File: armv5te/OP_UNUSED_D0FF.S */
10500/* File: armv5te/unused.S */
10501    bl      common_abort
10502
10503
10504/* ------------------------------ */
10505    .balign 64
10506.L_OP_UNUSED_D1FF: /* 0x1d1 */
10507/* File: armv5te/OP_UNUSED_D1FF.S */
10508/* File: armv5te/unused.S */
10509    bl      common_abort
10510
10511
10512/* ------------------------------ */
10513    .balign 64
10514.L_OP_UNUSED_D2FF: /* 0x1d2 */
10515/* File: armv5te/OP_UNUSED_D2FF.S */
10516/* File: armv5te/unused.S */
10517    bl      common_abort
10518
10519
10520/* ------------------------------ */
10521    .balign 64
10522.L_OP_UNUSED_D3FF: /* 0x1d3 */
10523/* File: armv5te/OP_UNUSED_D3FF.S */
10524/* File: armv5te/unused.S */
10525    bl      common_abort
10526
10527
10528/* ------------------------------ */
10529    .balign 64
10530.L_OP_UNUSED_D4FF: /* 0x1d4 */
10531/* File: armv5te/OP_UNUSED_D4FF.S */
10532/* File: armv5te/unused.S */
10533    bl      common_abort
10534
10535
10536/* ------------------------------ */
10537    .balign 64
10538.L_OP_UNUSED_D5FF: /* 0x1d5 */
10539/* File: armv5te/OP_UNUSED_D5FF.S */
10540/* File: armv5te/unused.S */
10541    bl      common_abort
10542
10543
10544/* ------------------------------ */
10545    .balign 64
10546.L_OP_UNUSED_D6FF: /* 0x1d6 */
10547/* File: armv5te/OP_UNUSED_D6FF.S */
10548/* File: armv5te/unused.S */
10549    bl      common_abort
10550
10551
10552/* ------------------------------ */
10553    .balign 64
10554.L_OP_UNUSED_D7FF: /* 0x1d7 */
10555/* File: armv5te/OP_UNUSED_D7FF.S */
10556/* File: armv5te/unused.S */
10557    bl      common_abort
10558
10559
10560/* ------------------------------ */
10561    .balign 64
10562.L_OP_UNUSED_D8FF: /* 0x1d8 */
10563/* File: armv5te/OP_UNUSED_D8FF.S */
10564/* File: armv5te/unused.S */
10565    bl      common_abort
10566
10567
10568/* ------------------------------ */
10569    .balign 64
10570.L_OP_UNUSED_D9FF: /* 0x1d9 */
10571/* File: armv5te/OP_UNUSED_D9FF.S */
10572/* File: armv5te/unused.S */
10573    bl      common_abort
10574
10575
10576/* ------------------------------ */
10577    .balign 64
10578.L_OP_UNUSED_DAFF: /* 0x1da */
10579/* File: armv5te/OP_UNUSED_DAFF.S */
10580/* File: armv5te/unused.S */
10581    bl      common_abort
10582
10583
10584/* ------------------------------ */
10585    .balign 64
10586.L_OP_UNUSED_DBFF: /* 0x1db */
10587/* File: armv5te/OP_UNUSED_DBFF.S */
10588/* File: armv5te/unused.S */
10589    bl      common_abort
10590
10591
10592/* ------------------------------ */
10593    .balign 64
10594.L_OP_UNUSED_DCFF: /* 0x1dc */
10595/* File: armv5te/OP_UNUSED_DCFF.S */
10596/* File: armv5te/unused.S */
10597    bl      common_abort
10598
10599
10600/* ------------------------------ */
10601    .balign 64
10602.L_OP_UNUSED_DDFF: /* 0x1dd */
10603/* File: armv5te/OP_UNUSED_DDFF.S */
10604/* File: armv5te/unused.S */
10605    bl      common_abort
10606
10607
10608/* ------------------------------ */
10609    .balign 64
10610.L_OP_UNUSED_DEFF: /* 0x1de */
10611/* File: armv5te/OP_UNUSED_DEFF.S */
10612/* File: armv5te/unused.S */
10613    bl      common_abort
10614
10615
10616/* ------------------------------ */
10617    .balign 64
10618.L_OP_UNUSED_DFFF: /* 0x1df */
10619/* File: armv5te/OP_UNUSED_DFFF.S */
10620/* File: armv5te/unused.S */
10621    bl      common_abort
10622
10623
10624/* ------------------------------ */
10625    .balign 64
10626.L_OP_UNUSED_E0FF: /* 0x1e0 */
10627/* File: armv5te/OP_UNUSED_E0FF.S */
10628/* File: armv5te/unused.S */
10629    bl      common_abort
10630
10631
10632/* ------------------------------ */
10633    .balign 64
10634.L_OP_UNUSED_E1FF: /* 0x1e1 */
10635/* File: armv5te/OP_UNUSED_E1FF.S */
10636/* File: armv5te/unused.S */
10637    bl      common_abort
10638
10639
10640/* ------------------------------ */
10641    .balign 64
10642.L_OP_UNUSED_E2FF: /* 0x1e2 */
10643/* File: armv5te/OP_UNUSED_E2FF.S */
10644/* File: armv5te/unused.S */
10645    bl      common_abort
10646
10647
10648/* ------------------------------ */
10649    .balign 64
10650.L_OP_UNUSED_E3FF: /* 0x1e3 */
10651/* File: armv5te/OP_UNUSED_E3FF.S */
10652/* File: armv5te/unused.S */
10653    bl      common_abort
10654
10655
10656/* ------------------------------ */
10657    .balign 64
10658.L_OP_UNUSED_E4FF: /* 0x1e4 */
10659/* File: armv5te/OP_UNUSED_E4FF.S */
10660/* File: armv5te/unused.S */
10661    bl      common_abort
10662
10663
10664/* ------------------------------ */
10665    .balign 64
10666.L_OP_UNUSED_E5FF: /* 0x1e5 */
10667/* File: armv5te/OP_UNUSED_E5FF.S */
10668/* File: armv5te/unused.S */
10669    bl      common_abort
10670
10671
10672/* ------------------------------ */
10673    .balign 64
10674.L_OP_UNUSED_E6FF: /* 0x1e6 */
10675/* File: armv5te/OP_UNUSED_E6FF.S */
10676/* File: armv5te/unused.S */
10677    bl      common_abort
10678
10679
10680/* ------------------------------ */
10681    .balign 64
10682.L_OP_UNUSED_E7FF: /* 0x1e7 */
10683/* File: armv5te/OP_UNUSED_E7FF.S */
10684/* File: armv5te/unused.S */
10685    bl      common_abort
10686
10687
10688/* ------------------------------ */
10689    .balign 64
10690.L_OP_UNUSED_E8FF: /* 0x1e8 */
10691/* File: armv5te/OP_UNUSED_E8FF.S */
10692/* File: armv5te/unused.S */
10693    bl      common_abort
10694
10695
10696/* ------------------------------ */
10697    .balign 64
10698.L_OP_UNUSED_E9FF: /* 0x1e9 */
10699/* File: armv5te/OP_UNUSED_E9FF.S */
10700/* File: armv5te/unused.S */
10701    bl      common_abort
10702
10703
10704/* ------------------------------ */
10705    .balign 64
10706.L_OP_UNUSED_EAFF: /* 0x1ea */
10707/* File: armv5te/OP_UNUSED_EAFF.S */
10708/* File: armv5te/unused.S */
10709    bl      common_abort
10710
10711
10712/* ------------------------------ */
10713    .balign 64
10714.L_OP_UNUSED_EBFF: /* 0x1eb */
10715/* File: armv5te/OP_UNUSED_EBFF.S */
10716/* File: armv5te/unused.S */
10717    bl      common_abort
10718
10719
10720/* ------------------------------ */
10721    .balign 64
10722.L_OP_UNUSED_ECFF: /* 0x1ec */
10723/* File: armv5te/OP_UNUSED_ECFF.S */
10724/* File: armv5te/unused.S */
10725    bl      common_abort
10726
10727
10728/* ------------------------------ */
10729    .balign 64
10730.L_OP_UNUSED_EDFF: /* 0x1ed */
10731/* File: armv5te/OP_UNUSED_EDFF.S */
10732/* File: armv5te/unused.S */
10733    bl      common_abort
10734
10735
10736/* ------------------------------ */
10737    .balign 64
10738.L_OP_UNUSED_EEFF: /* 0x1ee */
10739/* File: armv5te/OP_UNUSED_EEFF.S */
10740/* File: armv5te/unused.S */
10741    bl      common_abort
10742
10743
10744/* ------------------------------ */
10745    .balign 64
10746.L_OP_UNUSED_EFFF: /* 0x1ef */
10747/* File: armv5te/OP_UNUSED_EFFF.S */
10748/* File: armv5te/unused.S */
10749    bl      common_abort
10750
10751
10752/* ------------------------------ */
10753    .balign 64
10754.L_OP_UNUSED_F0FF: /* 0x1f0 */
10755/* File: armv5te/OP_UNUSED_F0FF.S */
10756/* File: armv5te/unused.S */
10757    bl      common_abort
10758
10759
10760/* ------------------------------ */
10761    .balign 64
10762.L_OP_UNUSED_F1FF: /* 0x1f1 */
10763/* File: armv5te/OP_UNUSED_F1FF.S */
10764/* File: armv5te/unused.S */
10765    bl      common_abort
10766
10767
10768/* ------------------------------ */
10769    .balign 64
10770.L_OP_UNUSED_F2FF: /* 0x1f2 */
10771/* File: armv5te/OP_UNUSED_F2FF.S */
10772/* File: armv5te/unused.S */
10773    bl      common_abort
10774
10775
10776/* ------------------------------ */
10777    .balign 64
10778.L_OP_UNUSED_F3FF: /* 0x1f3 */
10779/* File: armv5te/OP_UNUSED_F3FF.S */
10780/* File: armv5te/unused.S */
10781    bl      common_abort
10782
10783
10784/* ------------------------------ */
10785    .balign 64
10786.L_OP_UNUSED_F4FF: /* 0x1f4 */
10787/* File: armv5te/OP_UNUSED_F4FF.S */
10788/* File: armv5te/unused.S */
10789    bl      common_abort
10790
10791
10792/* ------------------------------ */
10793    .balign 64
10794.L_OP_UNUSED_F5FF: /* 0x1f5 */
10795/* File: armv5te/OP_UNUSED_F5FF.S */
10796/* File: armv5te/unused.S */
10797    bl      common_abort
10798
10799
10800/* ------------------------------ */
10801    .balign 64
10802.L_OP_UNUSED_F6FF: /* 0x1f6 */
10803/* File: armv5te/OP_UNUSED_F6FF.S */
10804/* File: armv5te/unused.S */
10805    bl      common_abort
10806
10807
10808/* ------------------------------ */
10809    .balign 64
10810.L_OP_UNUSED_F7FF: /* 0x1f7 */
10811/* File: armv5te/OP_UNUSED_F7FF.S */
10812/* File: armv5te/unused.S */
10813    bl      common_abort
10814
10815
10816/* ------------------------------ */
10817    .balign 64
10818.L_OP_UNUSED_F8FF: /* 0x1f8 */
10819/* File: armv5te/OP_UNUSED_F8FF.S */
10820/* File: armv5te/unused.S */
10821    bl      common_abort
10822
10823
10824/* ------------------------------ */
10825    .balign 64
10826.L_OP_UNUSED_F9FF: /* 0x1f9 */
10827/* File: armv5te/OP_UNUSED_F9FF.S */
10828/* File: armv5te/unused.S */
10829    bl      common_abort
10830
10831
10832/* ------------------------------ */
10833    .balign 64
10834.L_OP_UNUSED_FAFF: /* 0x1fa */
10835/* File: armv5te/OP_UNUSED_FAFF.S */
10836/* File: armv5te/unused.S */
10837    bl      common_abort
10838
10839
10840/* ------------------------------ */
10841    .balign 64
10842.L_OP_UNUSED_FBFF: /* 0x1fb */
10843/* File: armv5te/OP_UNUSED_FBFF.S */
10844/* File: armv5te/unused.S */
10845    bl      common_abort
10846
10847
10848/* ------------------------------ */
10849    .balign 64
10850.L_OP_UNUSED_FCFF: /* 0x1fc */
10851/* File: armv5te/OP_UNUSED_FCFF.S */
10852/* File: armv5te/unused.S */
10853    bl      common_abort
10854
10855
10856/* ------------------------------ */
10857    .balign 64
10858.L_OP_UNUSED_FDFF: /* 0x1fd */
10859/* File: armv5te/OP_UNUSED_FDFF.S */
10860/* File: armv5te/unused.S */
10861    bl      common_abort
10862
10863
10864/* ------------------------------ */
10865    .balign 64
10866.L_OP_UNUSED_FEFF: /* 0x1fe */
10867/* File: armv5te/OP_UNUSED_FEFF.S */
10868/* File: armv5te/unused.S */
10869    bl      common_abort
10870
10871
10872/* ------------------------------ */
10873    .balign 64
10874.L_OP_THROW_VERIFICATION_ERROR_JUMBO: /* 0x1ff */
10875/* File: armv5te/OP_THROW_VERIFICATION_ERROR_JUMBO.S */
10876    /*
10877     * Handle a jumbo throw-verification-error instruction.  This throws an
10878     * exception for an error discovered during verification.  The
10879     * exception is indicated by BBBB, with some detail provided by AAAAAAAA.
10880     */
10881    /* exop BBBB, Class@AAAAAAAA */
10882    FETCH(r1, 1)                        @ r1<- aaaa (lo)
10883    FETCH(r2, 2)                        @ r2<- AAAA (hi)
10884    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
10885    orr     r2, r1, r2, lsl #16         @ r2<- AAAAaaaa
10886    EXPORT_PC()                         @ export the PC
10887    FETCH(r1, 3)                        @ r1<- BBBB
10888    bl      dvmThrowVerificationError   @ always throws
10889    b       common_exceptionThrown      @ handle exception
10890
10891
10892    .balign 64
10893    .size   dvmAsmInstructionStart, .-dvmAsmInstructionStart
10894    .global dvmAsmInstructionEnd
10895dvmAsmInstructionEnd:
10896
10897/*
10898 * ===========================================================================
10899 *  Sister implementations
10900 * ===========================================================================
10901 */
10902    .global dvmAsmSisterStart
10903    .type   dvmAsmSisterStart, %function
10904    .text
10905    .balign 4
10906dvmAsmSisterStart:
10907
10908/* continuation for OP_CONST_STRING */
10909
10910    /*
10911     * Continuation if the String has not yet been resolved.
10912     *  r1: BBBB (String ref)
10913     *  r9: target register
10914     */
10915.LOP_CONST_STRING_resolve:
10916    EXPORT_PC()
10917    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
10918    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10919    bl      dvmResolveString            @ r0<- String reference
10920    cmp     r0, #0                      @ failed?
10921    beq     common_exceptionThrown      @ yup, handle the exception
10922    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10923    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10924    SET_VREG(r0, r9)                    @ vAA<- r0
10925    GOTO_OPCODE(ip)                     @ jump to next instruction
10926
10927/* continuation for OP_CONST_STRING_JUMBO */
10928
10929    /*
10930     * Continuation if the String has not yet been resolved.
10931     *  r1: BBBBBBBB (String ref)
10932     *  r9: target register
10933     */
10934.LOP_CONST_STRING_JUMBO_resolve:
10935    EXPORT_PC()
10936    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
10937    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10938    bl      dvmResolveString            @ r0<- String reference
10939    cmp     r0, #0                      @ failed?
10940    beq     common_exceptionThrown      @ yup, handle the exception
10941    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
10942    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10943    SET_VREG(r0, r9)                    @ vAA<- r0
10944    GOTO_OPCODE(ip)                     @ jump to next instruction
10945
10946/* continuation for OP_CONST_CLASS */
10947
10948    /*
10949     * Continuation if the Class has not yet been resolved.
10950     *  r1: BBBB (Class ref)
10951     *  r9: target register
10952     */
10953.LOP_CONST_CLASS_resolve:
10954    EXPORT_PC()
10955    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
10956    mov     r2, #1                      @ r2<- true
10957    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10958    bl      dvmResolveClass             @ r0<- Class reference
10959    cmp     r0, #0                      @ failed?
10960    beq     common_exceptionThrown      @ yup, handle the exception
10961    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10962    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10963    SET_VREG(r0, r9)                    @ vAA<- r0
10964    GOTO_OPCODE(ip)                     @ jump to next instruction
10965
10966/* continuation for OP_CHECK_CAST */
10967
10968    /*
10969     * Trivial test failed, need to perform full check.  This is common.
10970     *  r0 holds obj->clazz
10971     *  r1 holds desired class resolved from BBBB
10972     *  r9 holds object
10973     */
10974.LOP_CHECK_CAST_fullcheck:
10975    mov     r10, r1                     @ avoid ClassObject getting clobbered
10976    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
10977    cmp     r0, #0                      @ failed?
10978    bne     .LOP_CHECK_CAST_okay            @ no, success
10979
10980    @ A cast has failed.  We need to throw a ClassCastException.
10981    EXPORT_PC()                         @ about to throw
10982    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
10983    mov     r1, r10                     @ r1<- desired class
10984    bl      dvmThrowClassCastException
10985    b       common_exceptionThrown
10986
10987    /*
10988     * Resolution required.  This is the least-likely path.
10989     *
10990     *  r2 holds BBBB
10991     *  r9 holds object
10992     */
10993.LOP_CHECK_CAST_resolve:
10994    EXPORT_PC()                         @ resolve() could throw
10995    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
10996    mov     r1, r2                      @ r1<- BBBB
10997    mov     r2, #0                      @ r2<- false
10998    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10999    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
11000    cmp     r0, #0                      @ got null?
11001    beq     common_exceptionThrown      @ yes, handle exception
11002    mov     r1, r0                      @ r1<- class resolved from BBB
11003    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
11004    b       .LOP_CHECK_CAST_resolved        @ pick up where we left off
11005
11006/* continuation for OP_INSTANCE_OF */
11007
11008    /*
11009     * Trivial test failed, need to perform full check.  This is common.
11010     *  r0 holds obj->clazz
11011     *  r1 holds class resolved from BBBB
11012     *  r9 holds A
11013     */
11014.LOP_INSTANCE_OF_fullcheck:
11015    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
11016    @ fall through to OP_INSTANCE_OF_store
11017
11018    /*
11019     * r0 holds boolean result
11020     * r9 holds A
11021     */
11022.LOP_INSTANCE_OF_store:
11023    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11024    SET_VREG(r0, r9)                    @ vA<- r0
11025    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11026    GOTO_OPCODE(ip)                     @ jump to next instruction
11027
11028    /*
11029     * Trivial test succeeded, save and bail.
11030     *  r9 holds A
11031     */
11032.LOP_INSTANCE_OF_trivial:
11033    mov     r0, #1                      @ indicate success
11034    @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper
11035    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11036    SET_VREG(r0, r9)                    @ vA<- r0
11037    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11038    GOTO_OPCODE(ip)                     @ jump to next instruction
11039
11040    /*
11041     * Resolution required.  This is the least-likely path.
11042     *
11043     *  r3 holds BBBB
11044     *  r9 holds A
11045     */
11046.LOP_INSTANCE_OF_resolve:
11047    EXPORT_PC()                         @ resolve() could throw
11048    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
11049    mov     r1, r3                      @ r1<- BBBB
11050    mov     r2, #1                      @ r2<- true
11051    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
11052    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
11053    cmp     r0, #0                      @ got null?
11054    beq     common_exceptionThrown      @ yes, handle exception
11055    mov     r1, r0                      @ r1<- class resolved from BBB
11056    mov     r3, rINST, lsr #12          @ r3<- B
11057    GET_VREG(r0, r3)                    @ r0<- vB (object)
11058    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
11059    b       .LOP_INSTANCE_OF_resolved        @ pick up where we left off
11060
11061/* continuation for OP_NEW_INSTANCE */
11062
11063    .balign 32                          @ minimize cache lines
11064.LOP_NEW_INSTANCE_finish: @ r0=new object
11065    mov     r3, rINST, lsr #8           @ r3<- AA
11066    cmp     r0, #0                      @ failed?
11067    beq     common_exceptionThrown      @ yes, handle the exception
11068    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11069    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11070    SET_VREG(r0, r3)                    @ vAA<- r0
11071    GOTO_OPCODE(ip)                     @ jump to next instruction
11072
11073    /*
11074     * Class initialization required.
11075     *
11076     *  r0 holds class object
11077     */
11078.LOP_NEW_INSTANCE_needinit:
11079    mov     r9, r0                      @ save r0
11080    bl      dvmInitClass                @ initialize class
11081    cmp     r0, #0                      @ check boolean result
11082    mov     r0, r9                      @ restore r0
11083    bne     .LOP_NEW_INSTANCE_initialized     @ success, continue
11084    b       common_exceptionThrown      @ failed, deal with init exception
11085
11086    /*
11087     * Resolution required.  This is the least-likely path.
11088     *
11089     *  r1 holds BBBB
11090     */
11091.LOP_NEW_INSTANCE_resolve:
11092    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
11093    mov     r2, #0                      @ r2<- false
11094    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
11095    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
11096    cmp     r0, #0                      @ got null?
11097    bne     .LOP_NEW_INSTANCE_resolved        @ no, continue
11098    b       common_exceptionThrown      @ yes, handle exception
11099
11100.LstrInstantiationErrorPtr:
11101    .word   .LstrInstantiationError
11102
11103/* continuation for OP_NEW_ARRAY */
11104
11105
11106    /*
11107     * Resolve class.  (This is an uncommon case.)
11108     *
11109     *  r1 holds array length
11110     *  r2 holds class ref CCCC
11111     */
11112.LOP_NEW_ARRAY_resolve:
11113    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
11114    mov     r9, r1                      @ r9<- length (save)
11115    mov     r1, r2                      @ r1<- CCCC
11116    mov     r2, #0                      @ r2<- false
11117    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
11118    bl      dvmResolveClass             @ r0<- call(clazz, ref)
11119    cmp     r0, #0                      @ got null?
11120    mov     r1, r9                      @ r1<- length (restore)
11121    beq     common_exceptionThrown      @ yes, handle exception
11122    @ fall through to OP_NEW_ARRAY_finish
11123
11124    /*
11125     * Finish allocation.
11126     *
11127     *  r0 holds class
11128     *  r1 holds array length
11129     */
11130.LOP_NEW_ARRAY_finish:
11131    mov     r2, #ALLOC_DONT_TRACK       @ don't track in local refs table
11132    bl      dvmAllocArrayByClass        @ r0<- call(clazz, length, flags)
11133    cmp     r0, #0                      @ failed?
11134    mov     r2, rINST, lsr #8           @ r2<- A+
11135    beq     common_exceptionThrown      @ yes, handle the exception
11136    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11137    and     r2, r2, #15                 @ r2<- A
11138    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11139    SET_VREG(r0, r2)                    @ vA<- r0
11140    GOTO_OPCODE(ip)                     @ jump to next instruction
11141
11142/* continuation for OP_FILLED_NEW_ARRAY */
11143
11144    /*
11145     * On entry:
11146     *  r0 holds array class
11147     *  r10 holds AA or BA
11148     */
11149.LOP_FILLED_NEW_ARRAY_continue:
11150    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
11151    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
11152    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
11153    .if     0
11154    mov     r1, r10                     @ r1<- AA (length)
11155    .else
11156    mov     r1, r10, lsr #4             @ r1<- B (length)
11157    .endif
11158    cmp     rINST, #'I'                 @ array of ints?
11159    cmpne   rINST, #'L'                 @ array of objects?
11160    cmpne   rINST, #'['                 @ array of arrays?
11161    mov     r9, r1                      @ save length in r9
11162    bne     .LOP_FILLED_NEW_ARRAY_notimpl         @ no, not handled yet
11163    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
11164    cmp     r0, #0                      @ null return?
11165    beq     common_exceptionThrown      @ alloc failed, handle exception
11166
11167    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
11168    str     r0, [rGLUE, #offGlue_retval]      @ retval.l <- new array
11169    str     rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type
11170    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
11171    subs    r9, r9, #1                  @ length--, check for neg
11172    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
11173    bmi     2f                          @ was zero, bail
11174
11175    @ copy values from registers into the array
11176    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
11177    .if     0
11178    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
111791:  ldr     r3, [r2], #4                @ r3<- *r2++
11180    subs    r9, r9, #1                  @ count--
11181    str     r3, [r0], #4                @ *contents++ = vX
11182    bpl     1b
11183    @ continue at 2
11184    .else
11185    cmp     r9, #4                      @ length was initially 5?
11186    and     r2, r10, #15                @ r2<- A
11187    bne     1f                          @ <= 4 args, branch
11188    GET_VREG(r3, r2)                    @ r3<- vA
11189    sub     r9, r9, #1                  @ count--
11190    str     r3, [r0, #16]               @ contents[4] = vA
111911:  and     r2, r1, #15                 @ r2<- F/E/D/C
11192    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
11193    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
11194    subs    r9, r9, #1                  @ count--
11195    str     r3, [r0], #4                @ *contents++ = vX
11196    bpl     1b
11197    @ continue at 2
11198    .endif
11199
112002:
11201    ldr     r0, [rGLUE, #offGlue_retval]     @ r0<- object
11202    ldr     r1, [rGLUE, #offGlue_retval+4]   @ r1<- type
11203    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
11204    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
11205    cmp     r1, #'I'                         @ Is int array?
11206    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
11207    GOTO_OPCODE(ip)                          @ execute it
11208
11209    /*
11210     * Throw an exception indicating that we have not implemented this
11211     * mode of filled-new-array.
11212     */
11213.LOP_FILLED_NEW_ARRAY_notimpl:
11214    ldr     r0, .L_strInternalError
11215    ldr     r1, .L_strFilledNewArrayNotImpl
11216    bl      dvmThrowException
11217    b       common_exceptionThrown
11218
11219    .if     (!0)                 @ define in one or the other, not both
11220.L_strFilledNewArrayNotImpl:
11221    .word   .LstrFilledNewArrayNotImpl
11222.L_strInternalError:
11223    .word   .LstrInternalError
11224    .endif
11225
11226/* continuation for OP_FILLED_NEW_ARRAY_RANGE */
11227
11228    /*
11229     * On entry:
11230     *  r0 holds array class
11231     *  r10 holds AA or BA
11232     */
11233.LOP_FILLED_NEW_ARRAY_RANGE_continue:
11234    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
11235    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
11236    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
11237    .if     1
11238    mov     r1, r10                     @ r1<- AA (length)
11239    .else
11240    mov     r1, r10, lsr #4             @ r1<- B (length)
11241    .endif
11242    cmp     rINST, #'I'                 @ array of ints?
11243    cmpne   rINST, #'L'                 @ array of objects?
11244    cmpne   rINST, #'['                 @ array of arrays?
11245    mov     r9, r1                      @ save length in r9
11246    bne     .LOP_FILLED_NEW_ARRAY_RANGE_notimpl         @ no, not handled yet
11247    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
11248    cmp     r0, #0                      @ null return?
11249    beq     common_exceptionThrown      @ alloc failed, handle exception
11250
11251    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
11252    str     r0, [rGLUE, #offGlue_retval]      @ retval.l <- new array
11253    str     rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type
11254    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
11255    subs    r9, r9, #1                  @ length--, check for neg
11256    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
11257    bmi     2f                          @ was zero, bail
11258
11259    @ copy values from registers into the array
11260    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
11261    .if     1
11262    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
112631:  ldr     r3, [r2], #4                @ r3<- *r2++
11264    subs    r9, r9, #1                  @ count--
11265    str     r3, [r0], #4                @ *contents++ = vX
11266    bpl     1b
11267    @ continue at 2
11268    .else
11269    cmp     r9, #4                      @ length was initially 5?
11270    and     r2, r10, #15                @ r2<- A
11271    bne     1f                          @ <= 4 args, branch
11272    GET_VREG(r3, r2)                    @ r3<- vA
11273    sub     r9, r9, #1                  @ count--
11274    str     r3, [r0, #16]               @ contents[4] = vA
112751:  and     r2, r1, #15                 @ r2<- F/E/D/C
11276    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
11277    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
11278    subs    r9, r9, #1                  @ count--
11279    str     r3, [r0], #4                @ *contents++ = vX
11280    bpl     1b
11281    @ continue at 2
11282    .endif
11283
112842:
11285    ldr     r0, [rGLUE, #offGlue_retval]     @ r0<- object
11286    ldr     r1, [rGLUE, #offGlue_retval+4]   @ r1<- type
11287    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
11288    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
11289    cmp     r1, #'I'                         @ Is int array?
11290    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
11291    GOTO_OPCODE(ip)                          @ execute it
11292
11293    /*
11294     * Throw an exception indicating that we have not implemented this
11295     * mode of filled-new-array.
11296     */
11297.LOP_FILLED_NEW_ARRAY_RANGE_notimpl:
11298    ldr     r0, .L_strInternalError
11299    ldr     r1, .L_strFilledNewArrayNotImpl
11300    bl      dvmThrowException
11301    b       common_exceptionThrown
11302
11303    .if     (!1)                 @ define in one or the other, not both
11304.L_strFilledNewArrayNotImpl:
11305    .word   .LstrFilledNewArrayNotImpl
11306.L_strInternalError:
11307    .word   .LstrInternalError
11308    .endif
11309
11310/* continuation for OP_CMPL_FLOAT */
11311
11312    @ Test for NaN with a second comparison.  EABI forbids testing bit
11313    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
11314    @ make the library call.
11315.LOP_CMPL_FLOAT_gt_or_nan:
11316    mov     r1, r9                      @ reverse order
11317    mov     r0, r10
11318    bl      __aeabi_cfcmple             @ r0<- Z set if eq, C clear if <
11319    @bleq    common_abort
11320    movcc   r1, #1                      @ (greater than) r1<- 1
11321    bcc     .LOP_CMPL_FLOAT_finish
11322    mvn     r1, #0                            @ r1<- 1 or -1 for NaN
11323    b       .LOP_CMPL_FLOAT_finish
11324
11325
11326#if 0       /* "clasic" form */
11327    FETCH(r0, 1)                        @ r0<- CCBB
11328    and     r2, r0, #255                @ r2<- BB
11329    mov     r3, r0, lsr #8              @ r3<- CC
11330    GET_VREG(r9, r2)                    @ r9<- vBB
11331    GET_VREG(r10, r3)                   @ r10<- vCC
11332    mov     r0, r9                      @ r0<- vBB
11333    mov     r1, r10                     @ r1<- vCC
11334    bl      __aeabi_fcmpeq              @ r0<- (vBB == vCC)
11335    cmp     r0, #0                      @ equal?
11336    movne   r1, #0                      @ yes, result is 0
11337    bne     OP_CMPL_FLOAT_finish
11338    mov     r0, r9                      @ r0<- vBB
11339    mov     r1, r10                     @ r1<- vCC
11340    bl      __aeabi_fcmplt              @ r0<- (vBB < vCC)
11341    cmp     r0, #0                      @ less than?
11342    b       OP_CMPL_FLOAT_continue
11343@%break
11344
11345OP_CMPL_FLOAT_continue:
11346    mvnne   r1, #0                      @ yes, result is -1
11347    bne     OP_CMPL_FLOAT_finish
11348    mov     r0, r9                      @ r0<- vBB
11349    mov     r1, r10                     @ r1<- vCC
11350    bl      __aeabi_fcmpgt              @ r0<- (vBB > vCC)
11351    cmp     r0, #0                      @ greater than?
11352    beq     OP_CMPL_FLOAT_nan               @ no, must be NaN
11353    mov     r1, #1                      @ yes, result is 1
11354    @ fall through to _finish
11355
11356OP_CMPL_FLOAT_finish:
11357    mov     r3, rINST, lsr #8           @ r3<- AA
11358    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11359    SET_VREG(r1, r3)                    @ vAA<- r1
11360    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11361    GOTO_OPCODE(ip)                     @ jump to next instruction
11362
11363    /*
11364     * This is expected to be uncommon, so we double-branch (once to here,
11365     * again back to _finish).
11366     */
11367OP_CMPL_FLOAT_nan:
11368    mvn     r1, #0                            @ r1<- 1 or -1 for NaN
11369    b       OP_CMPL_FLOAT_finish
11370
11371#endif
11372
11373/* continuation for OP_CMPG_FLOAT */
11374
11375    @ Test for NaN with a second comparison.  EABI forbids testing bit
11376    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
11377    @ make the library call.
11378.LOP_CMPG_FLOAT_gt_or_nan:
11379    mov     r1, r9                      @ reverse order
11380    mov     r0, r10
11381    bl      __aeabi_cfcmple             @ r0<- Z set if eq, C clear if <
11382    @bleq    common_abort
11383    movcc   r1, #1                      @ (greater than) r1<- 1
11384    bcc     .LOP_CMPG_FLOAT_finish
11385    mov     r1, #1                            @ r1<- 1 or -1 for NaN
11386    b       .LOP_CMPG_FLOAT_finish
11387
11388
11389#if 0       /* "clasic" form */
11390    FETCH(r0, 1)                        @ r0<- CCBB
11391    and     r2, r0, #255                @ r2<- BB
11392    mov     r3, r0, lsr #8              @ r3<- CC
11393    GET_VREG(r9, r2)                    @ r9<- vBB
11394    GET_VREG(r10, r3)                   @ r10<- vCC
11395    mov     r0, r9                      @ r0<- vBB
11396    mov     r1, r10                     @ r1<- vCC
11397    bl      __aeabi_fcmpeq              @ r0<- (vBB == vCC)
11398    cmp     r0, #0                      @ equal?
11399    movne   r1, #0                      @ yes, result is 0
11400    bne     OP_CMPG_FLOAT_finish
11401    mov     r0, r9                      @ r0<- vBB
11402    mov     r1, r10                     @ r1<- vCC
11403    bl      __aeabi_fcmplt              @ r0<- (vBB < vCC)
11404    cmp     r0, #0                      @ less than?
11405    b       OP_CMPG_FLOAT_continue
11406@%break
11407
11408OP_CMPG_FLOAT_continue:
11409    mvnne   r1, #0                      @ yes, result is -1
11410    bne     OP_CMPG_FLOAT_finish
11411    mov     r0, r9                      @ r0<- vBB
11412    mov     r1, r10                     @ r1<- vCC
11413    bl      __aeabi_fcmpgt              @ r0<- (vBB > vCC)
11414    cmp     r0, #0                      @ greater than?
11415    beq     OP_CMPG_FLOAT_nan               @ no, must be NaN
11416    mov     r1, #1                      @ yes, result is 1
11417    @ fall through to _finish
11418
11419OP_CMPG_FLOAT_finish:
11420    mov     r3, rINST, lsr #8           @ r3<- AA
11421    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11422    SET_VREG(r1, r3)                    @ vAA<- r1
11423    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11424    GOTO_OPCODE(ip)                     @ jump to next instruction
11425
11426    /*
11427     * This is expected to be uncommon, so we double-branch (once to here,
11428     * again back to _finish).
11429     */
11430OP_CMPG_FLOAT_nan:
11431    mov     r1, #1                            @ r1<- 1 or -1 for NaN
11432    b       OP_CMPG_FLOAT_finish
11433
11434#endif
11435
11436/* continuation for OP_CMPL_DOUBLE */
11437
11438    @ Test for NaN with a second comparison.  EABI forbids testing bit
11439    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
11440    @ make the library call.
11441.LOP_CMPL_DOUBLE_gt_or_nan:
11442    ldmia   r10, {r0-r1}                @ reverse order
11443    ldmia   r9, {r2-r3}
11444    bl      __aeabi_cdcmple             @ r0<- Z set if eq, C clear if <
11445    @bleq    common_abort
11446    movcc   r1, #1                      @ (greater than) r1<- 1
11447    bcc     .LOP_CMPL_DOUBLE_finish
11448    mvn     r1, #0                            @ r1<- 1 or -1 for NaN
11449    b       .LOP_CMPL_DOUBLE_finish
11450
11451/* continuation for OP_CMPG_DOUBLE */
11452
11453    @ Test for NaN with a second comparison.  EABI forbids testing bit
11454    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
11455    @ make the library call.
11456.LOP_CMPG_DOUBLE_gt_or_nan:
11457    ldmia   r10, {r0-r1}                @ reverse order
11458    ldmia   r9, {r2-r3}
11459    bl      __aeabi_cdcmple             @ r0<- Z set if eq, C clear if <
11460    @bleq    common_abort
11461    movcc   r1, #1                      @ (greater than) r1<- 1
11462    bcc     .LOP_CMPG_DOUBLE_finish
11463    mov     r1, #1                            @ r1<- 1 or -1 for NaN
11464    b       .LOP_CMPG_DOUBLE_finish
11465
11466/* continuation for OP_CMP_LONG */
11467
11468.LOP_CMP_LONG_less:
11469    mvn     r1, #0                      @ r1<- -1
11470    @ Want to cond code the next mov so we can avoid branch, but don't see it;
11471    @ instead, we just replicate the tail end.
11472    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11473    SET_VREG(r1, r9)                    @ vAA<- r1
11474    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11475    GOTO_OPCODE(ip)                     @ jump to next instruction
11476
11477.LOP_CMP_LONG_greater:
11478    mov     r1, #1                      @ r1<- 1
11479    @ fall through to _finish
11480
11481.LOP_CMP_LONG_finish:
11482    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11483    SET_VREG(r1, r9)                    @ vAA<- r1
11484    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11485    GOTO_OPCODE(ip)                     @ jump to next instruction
11486
11487/* continuation for OP_AGET_WIDE */
11488
11489.LOP_AGET_WIDE_finish:
11490    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11491    ldrd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
11492    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
11493    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11494    stmia   r9, {r2-r3}                 @ vAA/vAA+1<- r2/r3
11495    GOTO_OPCODE(ip)                     @ jump to next instruction
11496
11497/* continuation for OP_APUT_WIDE */
11498
11499.LOP_APUT_WIDE_finish:
11500    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11501    ldmia   r9, {r2-r3}                 @ r2/r3<- vAA/vAA+1
11502    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11503    strd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
11504    GOTO_OPCODE(ip)                     @ jump to next instruction
11505
11506/* continuation for OP_APUT_OBJECT */
11507    /*
11508     * On entry:
11509     *  rINST = vBB (arrayObj)
11510     *  r9 = vAA (obj)
11511     *  r10 = offset into array (vBB + vCC * width)
11512     */
11513.LOP_APUT_OBJECT_finish:
11514    cmp     r9, #0                      @ storing null reference?
11515    beq     .LOP_APUT_OBJECT_skip_check      @ yes, skip type checks
11516    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
11517    ldr     r1, [rINST, #offObject_clazz]  @ r1<- arrayObj->clazz
11518    bl      dvmCanPutArrayElement       @ test object type vs. array type
11519    cmp     r0, #0                      @ okay?
11520    beq     .LOP_APUT_OBJECT_throw           @ no
11521    mov     r1, rINST                   @ r1<- arrayObj
11522    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11523    ldr     r2, [rGLUE, #offGlue_cardTable]     @ get biased CT base
11524    add     r10, #offArrayObject_contents   @ r0<- pointer to slot
11525    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11526    str     r9, [r10]                   @ vBB[vCC]<- vAA
11527    strb    r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head
11528    GOTO_OPCODE(ip)                     @ jump to next instruction
11529.LOP_APUT_OBJECT_skip_check:
11530    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11531    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11532    str     r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA
11533    GOTO_OPCODE(ip)                     @ jump to next instruction
11534.LOP_APUT_OBJECT_throw:
11535    @ The types don't match.  We need to throw an ArrayStoreException.
11536    ldr     r0, [r9, #offObject_clazz]
11537    ldr     r1, [rINST, #offObject_clazz]
11538    EXPORT_PC()
11539    bl      dvmThrowArrayStoreException
11540    b       common_exceptionThrown
11541
11542/* continuation for OP_IGET */
11543
11544    /*
11545     * Currently:
11546     *  r0 holds resolved field
11547     *  r9 holds object
11548     */
11549.LOP_IGET_finish:
11550    @bl      common_squeak0
11551    cmp     r9, #0                      @ check object for null
11552    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11553    beq     common_errNullObject        @ object was null
11554    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11555    @ no-op                             @ acquiring load
11556    mov     r2, rINST, lsr #8           @ r2<- A+
11557    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11558    and     r2, r2, #15                 @ r2<- A
11559    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11560    SET_VREG(r0, r2)                    @ fp[A]<- r0
11561    GOTO_OPCODE(ip)                     @ jump to next instruction
11562
11563/* continuation for OP_IGET_WIDE */
11564
11565    /*
11566     * Currently:
11567     *  r0 holds resolved field
11568     *  r9 holds object
11569     */
11570.LOP_IGET_WIDE_finish:
11571    cmp     r9, #0                      @ check object for null
11572    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11573    beq     common_errNullObject        @ object was null
11574    .if     0
11575    add     r0, r9, r3                  @ r0<- address of field
11576    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
11577    .else
11578    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
11579    .endif
11580    mov     r2, rINST, lsr #8           @ r2<- A+
11581    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11582    and     r2, r2, #15                 @ r2<- A
11583    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
11584    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11585    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
11586    GOTO_OPCODE(ip)                     @ jump to next instruction
11587
11588/* continuation for OP_IGET_OBJECT */
11589
11590    /*
11591     * Currently:
11592     *  r0 holds resolved field
11593     *  r9 holds object
11594     */
11595.LOP_IGET_OBJECT_finish:
11596    @bl      common_squeak0
11597    cmp     r9, #0                      @ check object for null
11598    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11599    beq     common_errNullObject        @ object was null
11600    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11601    @ no-op                             @ acquiring load
11602    mov     r2, rINST, lsr #8           @ r2<- A+
11603    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11604    and     r2, r2, #15                 @ r2<- A
11605    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11606    SET_VREG(r0, r2)                    @ fp[A]<- r0
11607    GOTO_OPCODE(ip)                     @ jump to next instruction
11608
11609/* continuation for OP_IGET_BOOLEAN */
11610
11611    /*
11612     * Currently:
11613     *  r0 holds resolved field
11614     *  r9 holds object
11615     */
11616.LOP_IGET_BOOLEAN_finish:
11617    @bl      common_squeak1
11618    cmp     r9, #0                      @ check object for null
11619    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11620    beq     common_errNullObject        @ object was null
11621    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11622    @ no-op                             @ acquiring load
11623    mov     r2, rINST, lsr #8           @ r2<- A+
11624    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11625    and     r2, r2, #15                 @ r2<- A
11626    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11627    SET_VREG(r0, r2)                    @ fp[A]<- r0
11628    GOTO_OPCODE(ip)                     @ jump to next instruction
11629
11630/* continuation for OP_IGET_BYTE */
11631
11632    /*
11633     * Currently:
11634     *  r0 holds resolved field
11635     *  r9 holds object
11636     */
11637.LOP_IGET_BYTE_finish:
11638    @bl      common_squeak2
11639    cmp     r9, #0                      @ check object for null
11640    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11641    beq     common_errNullObject        @ object was null
11642    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11643    @ no-op                             @ acquiring load
11644    mov     r2, rINST, lsr #8           @ r2<- A+
11645    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11646    and     r2, r2, #15                 @ r2<- A
11647    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11648    SET_VREG(r0, r2)                    @ fp[A]<- r0
11649    GOTO_OPCODE(ip)                     @ jump to next instruction
11650
11651/* continuation for OP_IGET_CHAR */
11652
11653    /*
11654     * Currently:
11655     *  r0 holds resolved field
11656     *  r9 holds object
11657     */
11658.LOP_IGET_CHAR_finish:
11659    @bl      common_squeak3
11660    cmp     r9, #0                      @ check object for null
11661    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11662    beq     common_errNullObject        @ object was null
11663    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11664    @ no-op                             @ acquiring load
11665    mov     r2, rINST, lsr #8           @ r2<- A+
11666    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11667    and     r2, r2, #15                 @ r2<- A
11668    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11669    SET_VREG(r0, r2)                    @ fp[A]<- r0
11670    GOTO_OPCODE(ip)                     @ jump to next instruction
11671
11672/* continuation for OP_IGET_SHORT */
11673
11674    /*
11675     * Currently:
11676     *  r0 holds resolved field
11677     *  r9 holds object
11678     */
11679.LOP_IGET_SHORT_finish:
11680    @bl      common_squeak4
11681    cmp     r9, #0                      @ check object for null
11682    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11683    beq     common_errNullObject        @ object was null
11684    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11685    @ no-op                             @ acquiring load
11686    mov     r2, rINST, lsr #8           @ r2<- A+
11687    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11688    and     r2, r2, #15                 @ r2<- A
11689    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11690    SET_VREG(r0, r2)                    @ fp[A]<- r0
11691    GOTO_OPCODE(ip)                     @ jump to next instruction
11692
11693/* continuation for OP_IPUT */
11694
11695    /*
11696     * Currently:
11697     *  r0 holds resolved field
11698     *  r9 holds object
11699     */
11700.LOP_IPUT_finish:
11701    @bl      common_squeak0
11702    mov     r1, rINST, lsr #8           @ r1<- A+
11703    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11704    and     r1, r1, #15                 @ r1<- A
11705    cmp     r9, #0                      @ check object for null
11706    GET_VREG(r0, r1)                    @ r0<- fp[A]
11707    beq     common_errNullObject        @ object was null
11708    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11709    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11710    @ no-op                             @ releasing store
11711    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11712    GOTO_OPCODE(ip)                     @ jump to next instruction
11713
11714/* continuation for OP_IPUT_WIDE */
11715
11716    /*
11717     * Currently:
11718     *  r0 holds resolved field
11719     *  r9 holds object
11720     */
11721.LOP_IPUT_WIDE_finish:
11722    mov     r2, rINST, lsr #8           @ r2<- A+
11723    cmp     r9, #0                      @ check object for null
11724    and     r2, r2, #15                 @ r2<- A
11725    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11726    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
11727    beq     common_errNullObject        @ object was null
11728    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11729    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
11730    GET_INST_OPCODE(r10)                @ extract opcode from rINST
11731    .if     0
11732    add     r2, r9, r3                  @ r2<- target address
11733    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
11734    .else
11735    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
11736    .endif
11737    GOTO_OPCODE(r10)                    @ jump to next instruction
11738
11739/* continuation for OP_IPUT_OBJECT */
11740
11741    /*
11742     * Currently:
11743     *  r0 holds resolved field
11744     *  r9 holds object
11745     */
11746.LOP_IPUT_OBJECT_finish:
11747    @bl      common_squeak0
11748    mov     r1, rINST, lsr #8           @ r1<- A+
11749    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11750    and     r1, r1, #15                 @ r1<- A
11751    cmp     r9, #0                      @ check object for null
11752    GET_VREG(r0, r1)                    @ r0<- fp[A]
11753    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
11754    beq     common_errNullObject        @ object was null
11755    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11756    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11757    @ no-op                             @ releasing store
11758    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
11759    cmp     r0, #0                      @ stored a null reference?
11760    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
11761    GOTO_OPCODE(ip)                     @ jump to next instruction
11762
11763/* continuation for OP_IPUT_BOOLEAN */
11764
11765    /*
11766     * Currently:
11767     *  r0 holds resolved field
11768     *  r9 holds object
11769     */
11770.LOP_IPUT_BOOLEAN_finish:
11771    @bl      common_squeak1
11772    mov     r1, rINST, lsr #8           @ r1<- A+
11773    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11774    and     r1, r1, #15                 @ r1<- A
11775    cmp     r9, #0                      @ check object for null
11776    GET_VREG(r0, r1)                    @ r0<- fp[A]
11777    beq     common_errNullObject        @ object was null
11778    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11779    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11780    @ no-op                             @ releasing store
11781    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11782    GOTO_OPCODE(ip)                     @ jump to next instruction
11783
11784/* continuation for OP_IPUT_BYTE */
11785
11786    /*
11787     * Currently:
11788     *  r0 holds resolved field
11789     *  r9 holds object
11790     */
11791.LOP_IPUT_BYTE_finish:
11792    @bl      common_squeak2
11793    mov     r1, rINST, lsr #8           @ r1<- A+
11794    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11795    and     r1, r1, #15                 @ r1<- A
11796    cmp     r9, #0                      @ check object for null
11797    GET_VREG(r0, r1)                    @ r0<- fp[A]
11798    beq     common_errNullObject        @ object was null
11799    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11800    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11801    @ no-op                             @ releasing store
11802    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11803    GOTO_OPCODE(ip)                     @ jump to next instruction
11804
11805/* continuation for OP_IPUT_CHAR */
11806
11807    /*
11808     * Currently:
11809     *  r0 holds resolved field
11810     *  r9 holds object
11811     */
11812.LOP_IPUT_CHAR_finish:
11813    @bl      common_squeak3
11814    mov     r1, rINST, lsr #8           @ r1<- A+
11815    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11816    and     r1, r1, #15                 @ r1<- A
11817    cmp     r9, #0                      @ check object for null
11818    GET_VREG(r0, r1)                    @ r0<- fp[A]
11819    beq     common_errNullObject        @ object was null
11820    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11821    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11822    @ no-op                             @ releasing store
11823    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11824    GOTO_OPCODE(ip)                     @ jump to next instruction
11825
11826/* continuation for OP_IPUT_SHORT */
11827
11828    /*
11829     * Currently:
11830     *  r0 holds resolved field
11831     *  r9 holds object
11832     */
11833.LOP_IPUT_SHORT_finish:
11834    @bl      common_squeak4
11835    mov     r1, rINST, lsr #8           @ r1<- A+
11836    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11837    and     r1, r1, #15                 @ r1<- A
11838    cmp     r9, #0                      @ check object for null
11839    GET_VREG(r0, r1)                    @ r0<- fp[A]
11840    beq     common_errNullObject        @ object was null
11841    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11842    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11843    @ no-op                             @ releasing store
11844    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11845    GOTO_OPCODE(ip)                     @ jump to next instruction
11846
11847/* continuation for OP_SGET */
11848
11849    /*
11850     * Continuation if the field has not yet been resolved.
11851     *  r1: BBBB field ref
11852     */
11853.LOP_SGET_resolve:
11854    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11855    EXPORT_PC()                         @ resolve() could throw, so export now
11856    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11857    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11858    cmp     r0, #0                      @ success?
11859    bne     .LOP_SGET_finish          @ yes, finish
11860    b       common_exceptionThrown      @ no, handle exception
11861
11862/* continuation for OP_SGET_WIDE */
11863
11864    /*
11865     * Continuation if the field has not yet been resolved.
11866     *  r1: BBBB field ref
11867     *
11868     * Returns StaticField pointer in r0.
11869     */
11870.LOP_SGET_WIDE_resolve:
11871    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11872    EXPORT_PC()                         @ resolve() could throw, so export now
11873    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11874    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11875    cmp     r0, #0                      @ success?
11876    bne     .LOP_SGET_WIDE_finish          @ yes, finish
11877    b       common_exceptionThrown      @ no, handle exception
11878
11879/* continuation for OP_SGET_OBJECT */
11880
11881    /*
11882     * Continuation if the field has not yet been resolved.
11883     *  r1: BBBB field ref
11884     */
11885.LOP_SGET_OBJECT_resolve:
11886    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11887    EXPORT_PC()                         @ resolve() could throw, so export now
11888    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11889    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11890    cmp     r0, #0                      @ success?
11891    bne     .LOP_SGET_OBJECT_finish          @ yes, finish
11892    b       common_exceptionThrown      @ no, handle exception
11893
11894/* continuation for OP_SGET_BOOLEAN */
11895
11896    /*
11897     * Continuation if the field has not yet been resolved.
11898     *  r1: BBBB field ref
11899     */
11900.LOP_SGET_BOOLEAN_resolve:
11901    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11902    EXPORT_PC()                         @ resolve() could throw, so export now
11903    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11904    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11905    cmp     r0, #0                      @ success?
11906    bne     .LOP_SGET_BOOLEAN_finish          @ yes, finish
11907    b       common_exceptionThrown      @ no, handle exception
11908
11909/* continuation for OP_SGET_BYTE */
11910
11911    /*
11912     * Continuation if the field has not yet been resolved.
11913     *  r1: BBBB field ref
11914     */
11915.LOP_SGET_BYTE_resolve:
11916    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11917    EXPORT_PC()                         @ resolve() could throw, so export now
11918    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11919    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11920    cmp     r0, #0                      @ success?
11921    bne     .LOP_SGET_BYTE_finish          @ yes, finish
11922    b       common_exceptionThrown      @ no, handle exception
11923
11924/* continuation for OP_SGET_CHAR */
11925
11926    /*
11927     * Continuation if the field has not yet been resolved.
11928     *  r1: BBBB field ref
11929     */
11930.LOP_SGET_CHAR_resolve:
11931    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11932    EXPORT_PC()                         @ resolve() could throw, so export now
11933    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11934    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11935    cmp     r0, #0                      @ success?
11936    bne     .LOP_SGET_CHAR_finish          @ yes, finish
11937    b       common_exceptionThrown      @ no, handle exception
11938
11939/* continuation for OP_SGET_SHORT */
11940
11941    /*
11942     * Continuation if the field has not yet been resolved.
11943     *  r1: BBBB field ref
11944     */
11945.LOP_SGET_SHORT_resolve:
11946    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11947    EXPORT_PC()                         @ resolve() could throw, so export now
11948    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11949    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11950    cmp     r0, #0                      @ success?
11951    bne     .LOP_SGET_SHORT_finish          @ yes, finish
11952    b       common_exceptionThrown      @ no, handle exception
11953
11954/* continuation for OP_SPUT */
11955
11956    /*
11957     * Continuation if the field has not yet been resolved.
11958     *  r1: BBBB field ref
11959     */
11960.LOP_SPUT_resolve:
11961    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11962    EXPORT_PC()                         @ resolve() could throw, so export now
11963    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11964    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11965    cmp     r0, #0                      @ success?
11966    bne     .LOP_SPUT_finish          @ yes, finish
11967    b       common_exceptionThrown      @ no, handle exception
11968
11969/* continuation for OP_SPUT_WIDE */
11970
11971    /*
11972     * Continuation if the field has not yet been resolved.
11973     *  r1: BBBB field ref
11974     *  r9: &fp[AA]
11975     *
11976     * Returns StaticField pointer in r2.
11977     */
11978.LOP_SPUT_WIDE_resolve:
11979    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11980    EXPORT_PC()                         @ resolve() could throw, so export now
11981    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11982    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11983    cmp     r0, #0                      @ success?
11984    mov     r2, r0                      @ copy to r2
11985    bne     .LOP_SPUT_WIDE_finish          @ yes, finish
11986    b       common_exceptionThrown      @ no, handle exception
11987
11988/* continuation for OP_SPUT_OBJECT */
11989.LOP_SPUT_OBJECT_finish:   @ field ptr in r0
11990    mov     r2, rINST, lsr #8           @ r2<- AA
11991    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11992    GET_VREG(r1, r2)                    @ r1<- fp[AA]
11993    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
11994    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
11995    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11996    @ no-op                             @ releasing store
11997    str     r1, [r0, #offStaticField_value]  @ field<- vAA
11998    cmp     r1, #0                      @ stored a null object?
11999    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
12000    GOTO_OPCODE(ip)                     @ jump to next instruction
12001
12002/* continuation for OP_SPUT_BOOLEAN */
12003
12004    /*
12005     * Continuation if the field has not yet been resolved.
12006     *  r1: BBBB field ref
12007     */
12008.LOP_SPUT_BOOLEAN_resolve:
12009    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12010    EXPORT_PC()                         @ resolve() could throw, so export now
12011    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12012    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12013    cmp     r0, #0                      @ success?
12014    bne     .LOP_SPUT_BOOLEAN_finish          @ yes, finish
12015    b       common_exceptionThrown      @ no, handle exception
12016
12017/* continuation for OP_SPUT_BYTE */
12018
12019    /*
12020     * Continuation if the field has not yet been resolved.
12021     *  r1: BBBB field ref
12022     */
12023.LOP_SPUT_BYTE_resolve:
12024    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12025    EXPORT_PC()                         @ resolve() could throw, so export now
12026    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12027    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12028    cmp     r0, #0                      @ success?
12029    bne     .LOP_SPUT_BYTE_finish          @ yes, finish
12030    b       common_exceptionThrown      @ no, handle exception
12031
12032/* continuation for OP_SPUT_CHAR */
12033
12034    /*
12035     * Continuation if the field has not yet been resolved.
12036     *  r1: BBBB field ref
12037     */
12038.LOP_SPUT_CHAR_resolve:
12039    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12040    EXPORT_PC()                         @ resolve() could throw, so export now
12041    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12042    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12043    cmp     r0, #0                      @ success?
12044    bne     .LOP_SPUT_CHAR_finish          @ yes, finish
12045    b       common_exceptionThrown      @ no, handle exception
12046
12047/* continuation for OP_SPUT_SHORT */
12048
12049    /*
12050     * Continuation if the field has not yet been resolved.
12051     *  r1: BBBB field ref
12052     */
12053.LOP_SPUT_SHORT_resolve:
12054    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12055    EXPORT_PC()                         @ resolve() could throw, so export now
12056    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12057    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12058    cmp     r0, #0                      @ success?
12059    bne     .LOP_SPUT_SHORT_finish          @ yes, finish
12060    b       common_exceptionThrown      @ no, handle exception
12061
12062/* continuation for OP_INVOKE_VIRTUAL */
12063
12064    /*
12065     * At this point:
12066     *  r0 = resolved base method
12067     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
12068     */
12069.LOP_INVOKE_VIRTUAL_continue:
12070    GET_VREG(r1, r10)                   @ r1<- "this" ptr
12071    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
12072    cmp     r1, #0                      @ is "this" null?
12073    beq     common_errNullObject        @ null "this", throw exception
12074    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
12075    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
12076    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
12077    bl      common_invokeMethodNoRange @ continue on
12078
12079/* continuation for OP_INVOKE_SUPER */
12080
12081    /*
12082     * At this point:
12083     *  r0 = resolved base method
12084     *  r9 = method->clazz
12085     */
12086.LOP_INVOKE_SUPER_continue:
12087    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
12088    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
12089    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
12090    EXPORT_PC()                         @ must export for invoke
12091    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
12092    bcs     .LOP_INVOKE_SUPER_nsm             @ method not present in superclass
12093    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
12094    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
12095    bl      common_invokeMethodNoRange @ continue on
12096
12097.LOP_INVOKE_SUPER_resolve:
12098    mov     r0, r9                      @ r0<- method->clazz
12099    mov     r2, #METHOD_VIRTUAL         @ resolver method type
12100    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
12101    cmp     r0, #0                      @ got null?
12102    bne     .LOP_INVOKE_SUPER_continue        @ no, continue
12103    b       common_exceptionThrown      @ yes, handle exception
12104
12105    /*
12106     * Throw a NoSuchMethodError with the method name as the message.
12107     *  r0 = resolved base method
12108     */
12109.LOP_INVOKE_SUPER_nsm:
12110    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
12111    b       common_errNoSuchMethod
12112
12113/* continuation for OP_INVOKE_DIRECT */
12114
12115    /*
12116     * On entry:
12117     *  r1 = reference (BBBB or CCCC)
12118     *  r10 = "this" register
12119     */
12120.LOP_INVOKE_DIRECT_resolve:
12121    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
12122    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12123    mov     r2, #METHOD_DIRECT          @ resolver method type
12124    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
12125    cmp     r0, #0                      @ got null?
12126    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
12127    bne     .LOP_INVOKE_DIRECT_finish          @ no, continue
12128    b       common_exceptionThrown      @ yes, handle exception
12129
12130/* continuation for OP_INVOKE_VIRTUAL_RANGE */
12131
12132    /*
12133     * At this point:
12134     *  r0 = resolved base method
12135     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
12136     */
12137.LOP_INVOKE_VIRTUAL_RANGE_continue:
12138    GET_VREG(r1, r10)                   @ r1<- "this" ptr
12139    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
12140    cmp     r1, #0                      @ is "this" null?
12141    beq     common_errNullObject        @ null "this", throw exception
12142    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
12143    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
12144    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
12145    bl      common_invokeMethodRange @ continue on
12146
12147/* continuation for OP_INVOKE_SUPER_RANGE */
12148
12149    /*
12150     * At this point:
12151     *  r0 = resolved base method
12152     *  r9 = method->clazz
12153     */
12154.LOP_INVOKE_SUPER_RANGE_continue:
12155    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
12156    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
12157    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
12158    EXPORT_PC()                         @ must export for invoke
12159    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
12160    bcs     .LOP_INVOKE_SUPER_RANGE_nsm             @ method not present in superclass
12161    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
12162    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
12163    bl      common_invokeMethodRange @ continue on
12164
12165.LOP_INVOKE_SUPER_RANGE_resolve:
12166    mov     r0, r9                      @ r0<- method->clazz
12167    mov     r2, #METHOD_VIRTUAL         @ resolver method type
12168    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
12169    cmp     r0, #0                      @ got null?
12170    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ no, continue
12171    b       common_exceptionThrown      @ yes, handle exception
12172
12173    /*
12174     * Throw a NoSuchMethodError with the method name as the message.
12175     *  r0 = resolved base method
12176     */
12177.LOP_INVOKE_SUPER_RANGE_nsm:
12178    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
12179    b       common_errNoSuchMethod
12180
12181/* continuation for OP_INVOKE_DIRECT_RANGE */
12182
12183    /*
12184     * On entry:
12185     *  r1 = reference (BBBB or CCCC)
12186     *  r10 = "this" register
12187     */
12188.LOP_INVOKE_DIRECT_RANGE_resolve:
12189    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
12190    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12191    mov     r2, #METHOD_DIRECT          @ resolver method type
12192    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
12193    cmp     r0, #0                      @ got null?
12194    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
12195    bne     .LOP_INVOKE_DIRECT_RANGE_finish          @ no, continue
12196    b       common_exceptionThrown      @ yes, handle exception
12197
12198/* continuation for OP_FLOAT_TO_LONG */
12199/*
12200 * Convert the float in r0 to a long in r0/r1.
12201 *
12202 * We have to clip values to long min/max per the specification.  The
12203 * expected common case is a "reasonable" value that converts directly
12204 * to modest integer.  The EABI convert function isn't doing this for us.
12205 */
12206f2l_doconv:
12207    stmfd   sp!, {r4, lr}
12208    mov     r1, #0x5f000000             @ (float)maxlong
12209    mov     r4, r0
12210    bl      __aeabi_fcmpge              @ is arg >= maxlong?
12211    cmp     r0, #0                      @ nonzero == yes
12212    mvnne   r0, #0                      @ return maxlong (7fffffff)
12213    mvnne   r1, #0x80000000
12214    ldmnefd sp!, {r4, pc}
12215
12216    mov     r0, r4                      @ recover arg
12217    mov     r1, #0xdf000000             @ (float)minlong
12218    bl      __aeabi_fcmple              @ is arg <= minlong?
12219    cmp     r0, #0                      @ nonzero == yes
12220    movne   r0, #0                      @ return minlong (80000000)
12221    movne   r1, #0x80000000
12222    ldmnefd sp!, {r4, pc}
12223
12224    mov     r0, r4                      @ recover arg
12225    mov     r1, r4
12226    bl      __aeabi_fcmpeq              @ is arg == self?
12227    cmp     r0, #0                      @ zero == no
12228    moveq   r1, #0                      @ return zero for NaN
12229    ldmeqfd sp!, {r4, pc}
12230
12231    mov     r0, r4                      @ recover arg
12232    bl      __aeabi_f2lz                @ convert float to long
12233    ldmfd   sp!, {r4, pc}
12234
12235/* continuation for OP_DOUBLE_TO_LONG */
12236/*
12237 * Convert the double in r0/r1 to a long in r0/r1.
12238 *
12239 * We have to clip values to long min/max per the specification.  The
12240 * expected common case is a "reasonable" value that converts directly
12241 * to modest integer.  The EABI convert function isn't doing this for us.
12242 */
12243d2l_doconv:
12244    stmfd   sp!, {r4, r5, lr}           @ save regs
12245    mov     r3, #0x43000000             @ maxlong, as a double (high word)
12246    add     r3, #0x00e00000             @  0x43e00000
12247    mov     r2, #0                      @ maxlong, as a double (low word)
12248    sub     sp, sp, #4                  @ align for EABI
12249    mov     r4, r0                      @ save a copy of r0
12250    mov     r5, r1                      @  and r1
12251    bl      __aeabi_dcmpge              @ is arg >= maxlong?
12252    cmp     r0, #0                      @ nonzero == yes
12253    mvnne   r0, #0                      @ return maxlong (7fffffffffffffff)
12254    mvnne   r1, #0x80000000
12255    bne     1f
12256
12257    mov     r0, r4                      @ recover arg
12258    mov     r1, r5
12259    mov     r3, #0xc3000000             @ minlong, as a double (high word)
12260    add     r3, #0x00e00000             @  0xc3e00000
12261    mov     r2, #0                      @ minlong, as a double (low word)
12262    bl      __aeabi_dcmple              @ is arg <= minlong?
12263    cmp     r0, #0                      @ nonzero == yes
12264    movne   r0, #0                      @ return minlong (8000000000000000)
12265    movne   r1, #0x80000000
12266    bne     1f
12267
12268    mov     r0, r4                      @ recover arg
12269    mov     r1, r5
12270    mov     r2, r4                      @ compare against self
12271    mov     r3, r5
12272    bl      __aeabi_dcmpeq              @ is arg == self?
12273    cmp     r0, #0                      @ zero == no
12274    moveq   r1, #0                      @ return zero for NaN
12275    beq     1f
12276
12277    mov     r0, r4                      @ recover arg
12278    mov     r1, r5
12279    bl      __aeabi_d2lz                @ convert double to long
12280
122811:
12282    add     sp, sp, #4
12283    ldmfd   sp!, {r4, r5, pc}
12284
12285/* continuation for OP_MUL_LONG */
12286
12287.LOP_MUL_LONG_finish:
12288    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12289    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
12290    GOTO_OPCODE(ip)                     @ jump to next instruction
12291
12292/* continuation for OP_SHL_LONG */
12293
12294.LOP_SHL_LONG_finish:
12295    mov     r0, r0, asl r2              @  r0<- r0 << r2
12296    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12297    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
12298    GOTO_OPCODE(ip)                     @ jump to next instruction
12299
12300/* continuation for OP_SHR_LONG */
12301
12302.LOP_SHR_LONG_finish:
12303    mov     r1, r1, asr r2              @  r1<- r1 >> r2
12304    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12305    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
12306    GOTO_OPCODE(ip)                     @ jump to next instruction
12307
12308/* continuation for OP_USHR_LONG */
12309
12310.LOP_USHR_LONG_finish:
12311    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
12312    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12313    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
12314    GOTO_OPCODE(ip)                     @ jump to next instruction
12315
12316/* continuation for OP_SHL_LONG_2ADDR */
12317
12318.LOP_SHL_LONG_2ADDR_finish:
12319    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12320    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
12321    GOTO_OPCODE(ip)                     @ jump to next instruction
12322
12323/* continuation for OP_SHR_LONG_2ADDR */
12324
12325.LOP_SHR_LONG_2ADDR_finish:
12326    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12327    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
12328    GOTO_OPCODE(ip)                     @ jump to next instruction
12329
12330/* continuation for OP_USHR_LONG_2ADDR */
12331
12332.LOP_USHR_LONG_2ADDR_finish:
12333    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12334    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
12335    GOTO_OPCODE(ip)                     @ jump to next instruction
12336
12337/* continuation for OP_IGET_VOLATILE */
12338
12339    /*
12340     * Currently:
12341     *  r0 holds resolved field
12342     *  r9 holds object
12343     */
12344.LOP_IGET_VOLATILE_finish:
12345    @bl      common_squeak0
12346    cmp     r9, #0                      @ check object for null
12347    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12348    beq     common_errNullObject        @ object was null
12349    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12350    SMP_DMB                            @ acquiring load
12351    mov     r2, rINST, lsr #8           @ r2<- A+
12352    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12353    and     r2, r2, #15                 @ r2<- A
12354    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12355    SET_VREG(r0, r2)                    @ fp[A]<- r0
12356    GOTO_OPCODE(ip)                     @ jump to next instruction
12357
12358/* continuation for OP_IPUT_VOLATILE */
12359
12360    /*
12361     * Currently:
12362     *  r0 holds resolved field
12363     *  r9 holds object
12364     */
12365.LOP_IPUT_VOLATILE_finish:
12366    @bl      common_squeak0
12367    mov     r1, rINST, lsr #8           @ r1<- A+
12368    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12369    and     r1, r1, #15                 @ r1<- A
12370    cmp     r9, #0                      @ check object for null
12371    GET_VREG(r0, r1)                    @ r0<- fp[A]
12372    beq     common_errNullObject        @ object was null
12373    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12374    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12375    SMP_DMB                            @ releasing store
12376    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12377    GOTO_OPCODE(ip)                     @ jump to next instruction
12378
12379/* continuation for OP_SGET_VOLATILE */
12380
12381    /*
12382     * Continuation if the field has not yet been resolved.
12383     *  r1: BBBB field ref
12384     */
12385.LOP_SGET_VOLATILE_resolve:
12386    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12387    EXPORT_PC()                         @ resolve() could throw, so export now
12388    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12389    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12390    cmp     r0, #0                      @ success?
12391    bne     .LOP_SGET_VOLATILE_finish          @ yes, finish
12392    b       common_exceptionThrown      @ no, handle exception
12393
12394/* continuation for OP_SPUT_VOLATILE */
12395
12396    /*
12397     * Continuation if the field has not yet been resolved.
12398     *  r1: BBBB field ref
12399     */
12400.LOP_SPUT_VOLATILE_resolve:
12401    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12402    EXPORT_PC()                         @ resolve() could throw, so export now
12403    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12404    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12405    cmp     r0, #0                      @ success?
12406    bne     .LOP_SPUT_VOLATILE_finish          @ yes, finish
12407    b       common_exceptionThrown      @ no, handle exception
12408
12409/* continuation for OP_IGET_OBJECT_VOLATILE */
12410
12411    /*
12412     * Currently:
12413     *  r0 holds resolved field
12414     *  r9 holds object
12415     */
12416.LOP_IGET_OBJECT_VOLATILE_finish:
12417    @bl      common_squeak0
12418    cmp     r9, #0                      @ check object for null
12419    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12420    beq     common_errNullObject        @ object was null
12421    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12422    SMP_DMB                            @ acquiring load
12423    mov     r2, rINST, lsr #8           @ r2<- A+
12424    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12425    and     r2, r2, #15                 @ r2<- A
12426    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12427    SET_VREG(r0, r2)                    @ fp[A]<- r0
12428    GOTO_OPCODE(ip)                     @ jump to next instruction
12429
12430/* continuation for OP_IGET_WIDE_VOLATILE */
12431
12432    /*
12433     * Currently:
12434     *  r0 holds resolved field
12435     *  r9 holds object
12436     */
12437.LOP_IGET_WIDE_VOLATILE_finish:
12438    cmp     r9, #0                      @ check object for null
12439    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12440    beq     common_errNullObject        @ object was null
12441    .if     1
12442    add     r0, r9, r3                  @ r0<- address of field
12443    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
12444    .else
12445    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
12446    .endif
12447    mov     r2, rINST, lsr #8           @ r2<- A+
12448    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12449    and     r2, r2, #15                 @ r2<- A
12450    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
12451    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12452    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
12453    GOTO_OPCODE(ip)                     @ jump to next instruction
12454
12455/* continuation for OP_IPUT_WIDE_VOLATILE */
12456
12457    /*
12458     * Currently:
12459     *  r0 holds resolved field
12460     *  r9 holds object
12461     */
12462.LOP_IPUT_WIDE_VOLATILE_finish:
12463    mov     r2, rINST, lsr #8           @ r2<- A+
12464    cmp     r9, #0                      @ check object for null
12465    and     r2, r2, #15                 @ r2<- A
12466    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12467    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
12468    beq     common_errNullObject        @ object was null
12469    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12470    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
12471    GET_INST_OPCODE(r10)                @ extract opcode from rINST
12472    .if     1
12473    add     r2, r9, r3                  @ r2<- target address
12474    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
12475    .else
12476    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
12477    .endif
12478    GOTO_OPCODE(r10)                    @ jump to next instruction
12479
12480/* continuation for OP_SGET_WIDE_VOLATILE */
12481
12482    /*
12483     * Continuation if the field has not yet been resolved.
12484     *  r1: BBBB field ref
12485     *
12486     * Returns StaticField pointer in r0.
12487     */
12488.LOP_SGET_WIDE_VOLATILE_resolve:
12489    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12490    EXPORT_PC()                         @ resolve() could throw, so export now
12491    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12492    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12493    cmp     r0, #0                      @ success?
12494    bne     .LOP_SGET_WIDE_VOLATILE_finish          @ yes, finish
12495    b       common_exceptionThrown      @ no, handle exception
12496
12497/* continuation for OP_SPUT_WIDE_VOLATILE */
12498
12499    /*
12500     * Continuation if the field has not yet been resolved.
12501     *  r1: BBBB field ref
12502     *  r9: &fp[AA]
12503     *
12504     * Returns StaticField pointer in r2.
12505     */
12506.LOP_SPUT_WIDE_VOLATILE_resolve:
12507    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12508    EXPORT_PC()                         @ resolve() could throw, so export now
12509    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12510    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12511    cmp     r0, #0                      @ success?
12512    mov     r2, r0                      @ copy to r2
12513    bne     .LOP_SPUT_WIDE_VOLATILE_finish          @ yes, finish
12514    b       common_exceptionThrown      @ no, handle exception
12515
12516/* continuation for OP_EXECUTE_INLINE */
12517
12518    /*
12519     * Extract args, call function.
12520     *  r0 = #of args (0-4)
12521     *  r10 = call index
12522     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
12523     *
12524     * Other ideas:
12525     * - Use a jump table from the main piece to jump directly into the
12526     *   AND/LDR pairs.  Costs a data load, saves a branch.
12527     * - Have five separate pieces that do the loading, so we can work the
12528     *   interleave a little better.  Increases code size.
12529     */
12530.LOP_EXECUTE_INLINE_continue:
12531    rsb     r0, r0, #4                  @ r0<- 4-r0
12532    FETCH(r9, 2)                        @ r9<- FEDC
12533    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
12534    bl      common_abort                @ (skipped due to ARM prefetch)
125354:  and     ip, r9, #0xf000             @ isolate F
12536    ldr     r3, [rFP, ip, lsr #10]      @ r3<- vF (shift right 12, left 2)
125373:  and     ip, r9, #0x0f00             @ isolate E
12538    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vE
125392:  and     ip, r9, #0x00f0             @ isolate D
12540    ldr     r1, [rFP, ip, lsr #2]       @ r1<- vD
125411:  and     ip, r9, #0x000f             @ isolate C
12542    ldr     r0, [rFP, ip, lsl #2]       @ r0<- vC
125430:
12544    ldr     r9, .LOP_EXECUTE_INLINE_table       @ table of InlineOperation
12545    ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
12546    @ (not reached)
12547
12548.LOP_EXECUTE_INLINE_table:
12549    .word   gDvmInlineOpsTable
12550
12551/* continuation for OP_EXECUTE_INLINE_RANGE */
12552
12553    /*
12554     * Extract args, call function.
12555     *  r0 = #of args (0-4)
12556     *  r10 = call index
12557     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
12558     */
12559.LOP_EXECUTE_INLINE_RANGE_continue:
12560    rsb     r0, r0, #4                  @ r0<- 4-r0
12561    FETCH(r9, 2)                        @ r9<- CCCC
12562    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
12563    bl      common_abort                @ (skipped due to ARM prefetch)
125644:  add     ip, r9, #3                  @ base+3
12565    GET_VREG(r3, ip)                    @ r3<- vBase[3]
125663:  add     ip, r9, #2                  @ base+2
12567    GET_VREG(r2, ip)                    @ r2<- vBase[2]
125682:  add     ip, r9, #1                  @ base+1
12569    GET_VREG(r1, ip)                    @ r1<- vBase[1]
125701:  add     ip, r9, #0                  @ (nop)
12571    GET_VREG(r0, ip)                    @ r0<- vBase[0]
125720:
12573    ldr     r9, .LOP_EXECUTE_INLINE_RANGE_table       @ table of InlineOperation
12574    ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
12575    @ (not reached)
12576
12577.LOP_EXECUTE_INLINE_RANGE_table:
12578    .word   gDvmInlineOpsTable
12579
12580/* continuation for OP_IPUT_OBJECT_VOLATILE */
12581
12582    /*
12583     * Currently:
12584     *  r0 holds resolved field
12585     *  r9 holds object
12586     */
12587.LOP_IPUT_OBJECT_VOLATILE_finish:
12588    @bl      common_squeak0
12589    mov     r1, rINST, lsr #8           @ r1<- A+
12590    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12591    and     r1, r1, #15                 @ r1<- A
12592    cmp     r9, #0                      @ check object for null
12593    GET_VREG(r0, r1)                    @ r0<- fp[A]
12594    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12595    beq     common_errNullObject        @ object was null
12596    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12597    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12598    SMP_DMB                            @ releasing store
12599    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
12600    cmp     r0, #0                      @ stored a null reference?
12601    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
12602    GOTO_OPCODE(ip)                     @ jump to next instruction
12603
12604/* continuation for OP_SGET_OBJECT_VOLATILE */
12605
12606    /*
12607     * Continuation if the field has not yet been resolved.
12608     *  r1: BBBB field ref
12609     */
12610.LOP_SGET_OBJECT_VOLATILE_resolve:
12611    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12612    EXPORT_PC()                         @ resolve() could throw, so export now
12613    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12614    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12615    cmp     r0, #0                      @ success?
12616    bne     .LOP_SGET_OBJECT_VOLATILE_finish          @ yes, finish
12617    b       common_exceptionThrown      @ no, handle exception
12618
12619/* continuation for OP_SPUT_OBJECT_VOLATILE */
12620.LOP_SPUT_OBJECT_VOLATILE_finish:   @ field ptr in r0
12621    mov     r2, rINST, lsr #8           @ r2<- AA
12622    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12623    GET_VREG(r1, r2)                    @ r1<- fp[AA]
12624    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12625    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
12626    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12627    SMP_DMB                            @ releasing store
12628    str     r1, [r0, #offStaticField_value]  @ field<- vAA
12629    cmp     r1, #0                      @ stored a null object?
12630    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
12631    GOTO_OPCODE(ip)                     @ jump to next instruction
12632
12633/* continuation for OP_CONST_CLASS_JUMBO */
12634
12635    /*
12636     * Continuation if the Class has not yet been resolved.
12637     *  r1: AAAAAAAA (Class ref)
12638     *  r9: target register
12639     */
12640.LOP_CONST_CLASS_JUMBO_resolve:
12641    EXPORT_PC()
12642    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
12643    mov     r2, #1                      @ r2<- true
12644    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
12645    bl      dvmResolveClass             @ r0<- Class reference
12646    cmp     r0, #0                      @ failed?
12647    beq     common_exceptionThrown      @ yup, handle the exception
12648    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12649    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12650    SET_VREG(r0, r9)                    @ vBBBB<- r0
12651    GOTO_OPCODE(ip)                     @ jump to next instruction
12652
12653/* continuation for OP_CHECK_CAST_JUMBO */
12654
12655    /*
12656     * Trivial test failed, need to perform full check.  This is common.
12657     *  r0 holds obj->clazz
12658     *  r1 holds desired class resolved from AAAAAAAA
12659     *  r9 holds object
12660     */
12661.LOP_CHECK_CAST_JUMBO_fullcheck:
12662    mov     r10, r1                     @ avoid ClassObject getting clobbered
12663    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
12664    cmp     r0, #0                      @ failed?
12665    bne     .LOP_CHECK_CAST_JUMBO_okay            @ no, success
12666
12667    @ A cast has failed.  We need to throw a ClassCastException.
12668    EXPORT_PC()                         @ about to throw
12669    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
12670    mov     r1, r10                     @ r1<- desired class
12671    bl      dvmThrowClassCastException
12672    b       common_exceptionThrown
12673
12674    /*
12675     * Advance PC and get the next opcode.
12676     */
12677.LOP_CHECK_CAST_JUMBO_okay:
12678    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12679    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12680    GOTO_OPCODE(ip)                     @ jump to next instruction
12681
12682    /*
12683     * Resolution required.  This is the least-likely path.
12684     *
12685     *  r2 holds AAAAAAAA
12686     *  r9 holds object
12687     */
12688.LOP_CHECK_CAST_JUMBO_resolve:
12689    EXPORT_PC()                         @ resolve() could throw
12690    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
12691    mov     r1, r2                      @ r1<- AAAAAAAA
12692    mov     r2, #0                      @ r2<- false
12693    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12694    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12695    cmp     r0, #0                      @ got null?
12696    beq     common_exceptionThrown      @ yes, handle exception
12697    mov     r1, r0                      @ r1<- class resolved from AAAAAAAA
12698    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
12699    b       .LOP_CHECK_CAST_JUMBO_resolved        @ pick up where we left off
12700
12701/* continuation for OP_INSTANCE_OF_JUMBO */
12702
12703    /*
12704     * Class resolved, determine type of check necessary.  This is common.
12705     *  r0 holds obj->clazz
12706     *  r1 holds class resolved from AAAAAAAA
12707     *  r9 holds BBBB
12708     */
12709.LOP_INSTANCE_OF_JUMBO_resolved:
12710    cmp     r0, r1                      @ same class (trivial success)?
12711    beq     .LOP_INSTANCE_OF_JUMBO_trivial         @ yes, trivial finish
12712    @ fall through to OP_INSTANCE_OF_JUMBO_fullcheck
12713
12714    /*
12715     * Trivial test failed, need to perform full check.  This is common.
12716     *  r0 holds obj->clazz
12717     *  r1 holds class resolved from AAAAAAAA
12718     *  r9 holds BBBB
12719     */
12720.LOP_INSTANCE_OF_JUMBO_fullcheck:
12721    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
12722    @ fall through to OP_INSTANCE_OF_JUMBO_store
12723
12724    /*
12725     * r0 holds boolean result
12726     * r9 holds BBBB
12727     */
12728.LOP_INSTANCE_OF_JUMBO_store:
12729    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12730    SET_VREG(r0, r9)                    @ vBBBB<- r0
12731    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12732    GOTO_OPCODE(ip)                     @ jump to next instruction
12733
12734    /*
12735     * Trivial test succeeded, save and bail.
12736     *  r9 holds BBBB
12737     */
12738.LOP_INSTANCE_OF_JUMBO_trivial:
12739    mov     r0, #1                      @ indicate success
12740    @ could b OP_INSTANCE_OF_JUMBO_store, but copying is faster and cheaper
12741    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12742    SET_VREG(r0, r9)                    @ vBBBB<- r0
12743    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12744    GOTO_OPCODE(ip)                     @ jump to next instruction
12745
12746    /*
12747     * Resolution required.  This is the least-likely path.
12748     *
12749     *  r3 holds AAAAAAAA
12750     *  r9 holds BBBB
12751     */
12752
12753.LOP_INSTANCE_OF_JUMBO_resolve:
12754    EXPORT_PC()                         @ resolve() could throw
12755    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
12756    mov     r1, r3                      @ r1<- AAAAAAAA
12757    mov     r2, #1                      @ r2<- true
12758    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
12759    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12760    cmp     r0, #0                      @ got null?
12761    beq     common_exceptionThrown      @ yes, handle exception
12762    FETCH(r3, 4)                        @ r3<- vCCCC
12763    mov     r1, r0                      @ r1<- class resolved from AAAAAAAA
12764    GET_VREG(r0, r3)                    @ r0<- vCCCC (object)
12765    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
12766    b       .LOP_INSTANCE_OF_JUMBO_resolved        @ pick up where we left off
12767
12768/* continuation for OP_NEW_INSTANCE_JUMBO */
12769
12770    .balign 32                          @ minimize cache lines
12771.LOP_NEW_INSTANCE_JUMBO_finish: @ r0=new object
12772    FETCH(r3, 3)                        @ r3<- BBBB
12773    cmp     r0, #0                      @ failed?
12774    beq     common_exceptionThrown      @ yes, handle the exception
12775    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12776    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12777    SET_VREG(r0, r3)                    @ vBBBB<- r0
12778    GOTO_OPCODE(ip)                     @ jump to next instruction
12779
12780    /*
12781     * Class initialization required.
12782     *
12783     *  r0 holds class object
12784     */
12785.LOP_NEW_INSTANCE_JUMBO_needinit:
12786    mov     r9, r0                      @ save r0
12787    bl      dvmInitClass                @ initialize class
12788    cmp     r0, #0                      @ check boolean result
12789    mov     r0, r9                      @ restore r0
12790    bne     .LOP_NEW_INSTANCE_JUMBO_initialized     @ success, continue
12791    b       common_exceptionThrown      @ failed, deal with init exception
12792
12793    /*
12794     * Resolution required.  This is the least-likely path.
12795     *
12796     *  r1 holds AAAAAAAA
12797     */
12798.LOP_NEW_INSTANCE_JUMBO_resolve:
12799    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
12800    mov     r2, #0                      @ r2<- false
12801    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12802    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12803    cmp     r0, #0                      @ got null?
12804    bne     .LOP_NEW_INSTANCE_JUMBO_resolved        @ no, continue
12805    b       common_exceptionThrown      @ yes, handle exception
12806
12807/* continuation for OP_NEW_ARRAY_JUMBO */
12808
12809
12810    /*
12811     * Resolve class.  (This is an uncommon case.)
12812     *
12813     *  r1 holds array length
12814     *  r2 holds class ref AAAAAAAA
12815     */
12816.LOP_NEW_ARRAY_JUMBO_resolve:
12817    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
12818    mov     r9, r1                      @ r9<- length (save)
12819    mov     r1, r2                      @ r1<- AAAAAAAA
12820    mov     r2, #0                      @ r2<- false
12821    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12822    bl      dvmResolveClass             @ r0<- call(clazz, ref)
12823    cmp     r0, #0                      @ got null?
12824    mov     r1, r9                      @ r1<- length (restore)
12825    beq     common_exceptionThrown      @ yes, handle exception
12826    @ fall through to OP_NEW_ARRAY_JUMBO_finish
12827
12828    /*
12829     * Finish allocation.
12830     *
12831     *  r0 holds class
12832     *  r1 holds array length
12833     */
12834.LOP_NEW_ARRAY_JUMBO_finish:
12835    mov     r2, #ALLOC_DONT_TRACK       @ don't track in local refs table
12836    bl      dvmAllocArrayByClass        @ r0<- call(clazz, length, flags)
12837    cmp     r0, #0                      @ failed?
12838    FETCH(r2, 3)                        @ r2<- vBBBB
12839    beq     common_exceptionThrown      @ yes, handle the exception
12840    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12841    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12842    SET_VREG(r0, r2)                    @ vBBBB<- r0
12843    GOTO_OPCODE(ip)                     @ jump to next instruction
12844
12845/* continuation for OP_FILLED_NEW_ARRAY_JUMBO */
12846
12847    /*
12848     * On entry:
12849     *  r0 holds array class
12850     */
12851.LOP_FILLED_NEW_ARRAY_JUMBO_continue:
12852    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
12853    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
12854    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
12855    FETCH(r1, 3)                        @ r1<- BBBB (length)
12856    cmp     rINST, #'I'                 @ array of ints?
12857    cmpne   rINST, #'L'                 @ array of objects?
12858    cmpne   rINST, #'['                 @ array of arrays?
12859    mov     r9, r1                      @ save length in r9
12860    bne     .LOP_FILLED_NEW_ARRAY_JUMBO_notimpl         @ no, not handled yet
12861    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
12862    cmp     r0, #0                      @ null return?
12863    beq     common_exceptionThrown      @ alloc failed, handle exception
12864
12865    FETCH(r1, 4)                        @ r1<- CCCC
12866    str     r0, [rGLUE, #offGlue_retval]      @ retval.l <- new array
12867    str     rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type
12868    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
12869    subs    r9, r9, #1                  @ length--, check for neg
12870    FETCH_ADVANCE_INST(5)               @ advance to next instr, load rINST
12871    bmi     2f                          @ was zero, bail
12872
12873    @ copy values from registers into the array
12874    @ r0=array, r1=CCCC, r9=BBBB (length)
12875    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
128761:  ldr     r3, [r2], #4                @ r3<- *r2++
12877    subs    r9, r9, #1                  @ count--
12878    str     r3, [r0], #4                @ *contents++ = vX
12879    bpl     1b
12880
128812:  ldr     r0, [rGLUE, #offGlue_retval]     @ r0<- object
12882    ldr     r1, [rGLUE, #offGlue_retval+4]   @ r1<- type
12883    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12884    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
12885    cmp     r1, #'I'                         @ Is int array?
12886    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
12887    GOTO_OPCODE(ip)                          @ execute it
12888
12889    /*
12890     * Throw an exception indicating that we have not implemented this
12891     * mode of filled-new-array.
12892     */
12893.LOP_FILLED_NEW_ARRAY_JUMBO_notimpl:
12894    ldr     r0, .L_strInternalError
12895    ldr     r1, .L_strFilledNewArrayNotImpl
12896    bl      dvmThrowException
12897    b       common_exceptionThrown
12898
12899/* continuation for OP_IGET_JUMBO */
12900
12901    /*
12902     * Currently:
12903     *  r0 holds resolved field
12904     *  r9 holds object
12905     */
12906.LOP_IGET_JUMBO_resolved:
12907    cmp     r0, #0                      @ resolution unsuccessful?
12908    beq     common_exceptionThrown      @ yes, throw exception
12909    @ fall through to OP_IGET_JUMBO_finish
12910
12911    /*
12912     * Currently:
12913     *  r0 holds resolved field
12914     *  r9 holds object
12915     */
12916.LOP_IGET_JUMBO_finish:
12917    @bl      common_squeak0
12918    cmp     r9, #0                      @ check object for null
12919    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12920    beq     common_errNullObject        @ object was null
12921    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12922    @ no-op                             @ acquiring load
12923    FETCH(r2, 3)                        @ r2<- BBBB
12924    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12925    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12926    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12927    GOTO_OPCODE(ip)                     @ jump to next instruction
12928
12929/* continuation for OP_IGET_WIDE_JUMBO */
12930
12931    /*
12932     * Currently:
12933     *  r0 holds resolved field
12934     *  r9 holds object
12935     */
12936.LOP_IGET_WIDE_JUMBO_resolved:
12937    cmp     r0, #0                      @ resolution unsuccessful?
12938    beq     common_exceptionThrown      @ yes, throw exception
12939    @ fall through to OP_IGET_WIDE_JUMBO_finish
12940
12941    /*
12942     * Currently:
12943     *  r0 holds resolved field
12944     *  r9 holds object
12945     */
12946.LOP_IGET_WIDE_JUMBO_finish:
12947    cmp     r9, #0                      @ check object for null
12948    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12949    beq     common_errNullObject        @ object was null
12950    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
12951    FETCH(r2, 3)                        @ r2<- BBBB
12952    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12953    add     r3, rFP, r2, lsl #2         @ r3<- &fp[BBBB]
12954    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12955    stmia   r3, {r0-r1}                 @ fp[BBBB]<- r0/r1
12956    GOTO_OPCODE(ip)                     @ jump to next instruction
12957
12958/* continuation for OP_IGET_OBJECT_JUMBO */
12959
12960    /*
12961     * Currently:
12962     *  r0 holds resolved field
12963     *  r9 holds object
12964     */
12965.LOP_IGET_OBJECT_JUMBO_resolved:
12966    cmp     r0, #0                      @ resolution unsuccessful?
12967    beq     common_exceptionThrown      @ yes, throw exception
12968    @ fall through to OP_IGET_OBJECT_JUMBO_finish
12969
12970    /*
12971     * Currently:
12972     *  r0 holds resolved field
12973     *  r9 holds object
12974     */
12975.LOP_IGET_OBJECT_JUMBO_finish:
12976    @bl      common_squeak0
12977    cmp     r9, #0                      @ check object for null
12978    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12979    beq     common_errNullObject        @ object was null
12980    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12981    @ no-op                             @ acquiring load
12982    FETCH(r2, 3)                        @ r2<- BBBB
12983    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12984    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12985    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12986    GOTO_OPCODE(ip)                     @ jump to next instruction
12987
12988/* continuation for OP_IGET_BOOLEAN_JUMBO */
12989
12990    /*
12991     * Currently:
12992     *  r0 holds resolved field
12993     *  r9 holds object
12994     */
12995.LOP_IGET_BOOLEAN_JUMBO_resolved:
12996    cmp     r0, #0                      @ resolution unsuccessful?
12997    beq     common_exceptionThrown      @ yes, throw exception
12998    @ fall through to OP_IGET_BOOLEAN_JUMBO_finish
12999
13000    /*
13001     * Currently:
13002     *  r0 holds resolved field
13003     *  r9 holds object
13004     */
13005.LOP_IGET_BOOLEAN_JUMBO_finish:
13006    @bl      common_squeak1
13007    cmp     r9, #0                      @ check object for null
13008    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
13009    beq     common_errNullObject        @ object was null
13010    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
13011    @ no-op                             @ acquiring load
13012    FETCH(r2, 3)                        @ r2<- BBBB
13013    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
13014    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
13015    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13016    GOTO_OPCODE(ip)                     @ jump to next instruction
13017
13018/* continuation for OP_IGET_BYTE_JUMBO */
13019
13020    /*
13021     * Currently:
13022     *  r0 holds resolved field
13023     *  r9 holds object
13024     */
13025.LOP_IGET_BYTE_JUMBO_resolved:
13026    cmp     r0, #0                      @ resolution unsuccessful?
13027    beq     common_exceptionThrown      @ yes, throw exception
13028    @ fall through to OP_IGET_BYTE_JUMBO_finish
13029
13030    /*
13031     * Currently:
13032     *  r0 holds resolved field
13033     *  r9 holds object
13034     */
13035.LOP_IGET_BYTE_JUMBO_finish:
13036    @bl      common_squeak2
13037    cmp     r9, #0                      @ check object for null
13038    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
13039    beq     common_errNullObject        @ object was null
13040    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
13041    @ no-op                             @ acquiring load
13042    FETCH(r2, 3)                        @ r2<- BBBB
13043    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
13044    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
13045    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13046    GOTO_OPCODE(ip)                     @ jump to next instruction
13047
13048/* continuation for OP_IGET_CHAR_JUMBO */
13049
13050    /*
13051     * Currently:
13052     *  r0 holds resolved field
13053     *  r9 holds object
13054     */
13055.LOP_IGET_CHAR_JUMBO_resolved:
13056    cmp     r0, #0                      @ resolution unsuccessful?
13057    beq     common_exceptionThrown      @ yes, throw exception
13058    @ fall through to OP_IGET_CHAR_JUMBO_finish
13059
13060    /*
13061     * Currently:
13062     *  r0 holds resolved field
13063     *  r9 holds object
13064     */
13065.LOP_IGET_CHAR_JUMBO_finish:
13066    @bl      common_squeak3
13067    cmp     r9, #0                      @ check object for null
13068    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
13069    beq     common_errNullObject        @ object was null
13070    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
13071    @ no-op                             @ acquiring load
13072    FETCH(r2, 3)                        @ r2<- BBBB
13073    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
13074    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
13075    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13076    GOTO_OPCODE(ip)                     @ jump to next instruction
13077
13078/* continuation for OP_IGET_SHORT_JUMBO */
13079
13080    /*
13081     * Currently:
13082     *  r0 holds resolved field
13083     *  r9 holds object
13084     */
13085.LOP_IGET_SHORT_JUMBO_resolved:
13086    cmp     r0, #0                      @ resolution unsuccessful?
13087    beq     common_exceptionThrown      @ yes, throw exception
13088    @ fall through to OP_IGET_SHORT_JUMBO_finish
13089
13090    /*
13091     * Currently:
13092     *  r0 holds resolved field
13093     *  r9 holds object
13094     */
13095.LOP_IGET_SHORT_JUMBO_finish:
13096    @bl      common_squeak4
13097    cmp     r9, #0                      @ check object for null
13098    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
13099    beq     common_errNullObject        @ object was null
13100    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
13101    @ no-op                             @ acquiring load
13102    FETCH(r2, 3)                        @ r2<- BBBB
13103    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
13104    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
13105    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13106    GOTO_OPCODE(ip)                     @ jump to next instruction
13107
13108/* continuation for OP_IPUT_JUMBO */
13109
13110    /*
13111     * Currently:
13112     *  r0 holds resolved field
13113     *  r9 holds object
13114     */
13115.LOP_IPUT_JUMBO_resolved:
13116     cmp     r0, #0                     @ resolution unsuccessful?
13117     beq     common_exceptionThrown     @ yes, throw exception
13118     @ fall through to OP_IPUT_JUMBO_finish
13119
13120    /*
13121     * Currently:
13122     *  r0 holds resolved field
13123     *  r9 holds object
13124     */
13125.LOP_IPUT_JUMBO_finish:
13126    @bl      common_squeak0
13127    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
13128    FETCH(r1, 3)                        @ r1<- BBBB
13129    cmp     r9, #0                      @ check object for null
13130    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
13131    beq     common_errNullObject        @ object was null
13132    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
13133    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13134    @ no-op                             @ releasing store
13135    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
13136    GOTO_OPCODE(ip)                     @ jump to next instruction
13137
13138/* continuation for OP_IPUT_WIDE_JUMBO */
13139
13140    /*
13141     * Currently:
13142     *  r0 holds resolved field
13143     *  r9 holds object
13144     */
13145.LOP_IPUT_WIDE_JUMBO_resolved:
13146     cmp     r0, #0                     @ resolution unsuccessful?
13147     beq     common_exceptionThrown     @ yes, throw exception
13148     @ fall through to OP_IPUT_WIDE_JUMBO_finish
13149
13150    /*
13151     * Currently:
13152     *  r0 holds resolved field
13153     *  r9 holds object
13154     */
13155.LOP_IPUT_WIDE_JUMBO_finish:
13156    cmp     r9, #0                      @ check object for null
13157    FETCH(r2, 3)                        @ r1<- BBBB
13158    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
13159    add     r2, rFP, r2, lsl #2         @ r3<- &fp[BBBB]
13160    beq     common_errNullObject        @ object was null
13161    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
13162    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[BBBB]
13163    GET_INST_OPCODE(r10)                @ extract opcode from rINST
13164    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
13165    GOTO_OPCODE(r10)                    @ jump to next instruction
13166
13167/* continuation for OP_IPUT_OBJECT_JUMBO */
13168
13169    /*
13170     * Currently:
13171     *  r0 holds resolved field
13172     *  r9 holds object
13173     */
13174.LOP_IPUT_OBJECT_JUMBO_resolved:
13175     cmp     r0, #0                     @ resolution unsuccessful?
13176     beq     common_exceptionThrown     @ yes, throw exception
13177     @ fall through to OP_IPUT_OBJECT_JUMBO_finish
13178
13179    /*
13180     * Currently:
13181     *  r0 holds resolved field
13182     *  r9 holds object
13183     */
13184.LOP_IPUT_OBJECT_JUMBO_finish:
13185    @bl      common_squeak0
13186    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
13187    FETCH(r1, 3)                        @ r1<- BBBB
13188    cmp     r9, #0                      @ check object for null
13189    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
13190    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
13191    beq     common_errNullObject        @ object was null
13192    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
13193    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13194    @ no-op                             @ releasing store
13195    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
13196    cmp     r0, #0                      @ stored a null reference?
13197    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
13198    GOTO_OPCODE(ip)                     @ jump to next instruction
13199
13200/* continuation for OP_IPUT_BOOLEAN_JUMBO */
13201
13202    /*
13203     * Currently:
13204     *  r0 holds resolved field
13205     *  r9 holds object
13206     */
13207.LOP_IPUT_BOOLEAN_JUMBO_resolved:
13208     cmp     r0, #0                     @ resolution unsuccessful?
13209     beq     common_exceptionThrown     @ yes, throw exception
13210     @ fall through to OP_IPUT_BOOLEAN_JUMBO_finish
13211
13212    /*
13213     * Currently:
13214     *  r0 holds resolved field
13215     *  r9 holds object
13216     */
13217.LOP_IPUT_BOOLEAN_JUMBO_finish:
13218    @bl      common_squeak1
13219    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
13220    FETCH(r1, 3)                        @ r1<- BBBB
13221    cmp     r9, #0                      @ check object for null
13222    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
13223    beq     common_errNullObject        @ object was null
13224    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
13225    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13226    @ no-op                             @ releasing store
13227    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
13228    GOTO_OPCODE(ip)                     @ jump to next instruction
13229
13230/* continuation for OP_IPUT_BYTE_JUMBO */
13231
13232    /*
13233     * Currently:
13234     *  r0 holds resolved field
13235     *  r9 holds object
13236     */
13237.LOP_IPUT_BYTE_JUMBO_resolved:
13238     cmp     r0, #0                     @ resolution unsuccessful?
13239     beq     common_exceptionThrown     @ yes, throw exception
13240     @ fall through to OP_IPUT_BYTE_JUMBO_finish
13241
13242    /*
13243     * Currently:
13244     *  r0 holds resolved field
13245     *  r9 holds object
13246     */
13247.LOP_IPUT_BYTE_JUMBO_finish:
13248    @bl      common_squeak2
13249    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
13250    FETCH(r1, 3)                        @ r1<- BBBB
13251    cmp     r9, #0                      @ check object for null
13252    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
13253    beq     common_errNullObject        @ object was null
13254    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
13255    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13256    @ no-op                             @ releasing store
13257    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
13258    GOTO_OPCODE(ip)                     @ jump to next instruction
13259
13260/* continuation for OP_IPUT_CHAR_JUMBO */
13261
13262    /*
13263     * Currently:
13264     *  r0 holds resolved field
13265     *  r9 holds object
13266     */
13267.LOP_IPUT_CHAR_JUMBO_resolved:
13268     cmp     r0, #0                     @ resolution unsuccessful?
13269     beq     common_exceptionThrown     @ yes, throw exception
13270     @ fall through to OP_IPUT_CHAR_JUMBO_finish
13271
13272    /*
13273     * Currently:
13274     *  r0 holds resolved field
13275     *  r9 holds object
13276     */
13277.LOP_IPUT_CHAR_JUMBO_finish:
13278    @bl      common_squeak3
13279    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
13280    FETCH(r1, 3)                        @ r1<- BBBB
13281    cmp     r9, #0                      @ check object for null
13282    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
13283    beq     common_errNullObject        @ object was null
13284    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
13285    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13286    @ no-op                             @ releasing store
13287    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
13288    GOTO_OPCODE(ip)                     @ jump to next instruction
13289
13290/* continuation for OP_IPUT_SHORT_JUMBO */
13291
13292    /*
13293     * Currently:
13294     *  r0 holds resolved field
13295     *  r9 holds object
13296     */
13297.LOP_IPUT_SHORT_JUMBO_resolved:
13298     cmp     r0, #0                     @ resolution unsuccessful?
13299     beq     common_exceptionThrown     @ yes, throw exception
13300     @ fall through to OP_IPUT_SHORT_JUMBO_finish
13301
13302    /*
13303     * Currently:
13304     *  r0 holds resolved field
13305     *  r9 holds object
13306     */
13307.LOP_IPUT_SHORT_JUMBO_finish:
13308    @bl      common_squeak4
13309    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
13310    FETCH(r1, 3)                        @ r1<- BBBB
13311    cmp     r9, #0                      @ check object for null
13312    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
13313    beq     common_errNullObject        @ object was null
13314    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
13315    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13316    @ no-op                             @ releasing store
13317    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
13318    GOTO_OPCODE(ip)                     @ jump to next instruction
13319
13320/* continuation for OP_SGET_JUMBO */
13321
13322    /*
13323     * Continuation if the field has not yet been resolved.
13324     *  r1: AAAAAAAA field ref
13325     */
13326.LOP_SGET_JUMBO_resolve:
13327    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13328    EXPORT_PC()                         @ resolve() could throw, so export now
13329    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13330    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13331    cmp     r0, #0                      @ success?
13332    bne     .LOP_SGET_JUMBO_finish          @ yes, finish
13333    b       common_exceptionThrown      @ no, handle exception
13334
13335/* continuation for OP_SGET_WIDE_JUMBO */
13336
13337    /*
13338     * Continuation if the field has not yet been resolved.
13339     *  r1: BBBB field ref
13340     *
13341     * Returns StaticField pointer in r0.
13342     */
13343.LOP_SGET_WIDE_JUMBO_resolve:
13344    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13345    EXPORT_PC()                         @ resolve() could throw, so export now
13346    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13347    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13348    cmp     r0, #0                      @ success?
13349    bne     .LOP_SGET_WIDE_JUMBO_finish          @ yes, finish
13350    b       common_exceptionThrown      @ no, handle exception
13351
13352/* continuation for OP_SGET_OBJECT_JUMBO */
13353
13354    /*
13355     * Continuation if the field has not yet been resolved.
13356     *  r1: AAAAAAAA field ref
13357     */
13358.LOP_SGET_OBJECT_JUMBO_resolve:
13359    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13360    EXPORT_PC()                         @ resolve() could throw, so export now
13361    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13362    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13363    cmp     r0, #0                      @ success?
13364    bne     .LOP_SGET_OBJECT_JUMBO_finish          @ yes, finish
13365    b       common_exceptionThrown      @ no, handle exception
13366
13367/* continuation for OP_SGET_BOOLEAN_JUMBO */
13368
13369    /*
13370     * Continuation if the field has not yet been resolved.
13371     *  r1: AAAAAAAA field ref
13372     */
13373.LOP_SGET_BOOLEAN_JUMBO_resolve:
13374    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13375    EXPORT_PC()                         @ resolve() could throw, so export now
13376    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13377    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13378    cmp     r0, #0                      @ success?
13379    bne     .LOP_SGET_BOOLEAN_JUMBO_finish          @ yes, finish
13380    b       common_exceptionThrown      @ no, handle exception
13381
13382/* continuation for OP_SGET_BYTE_JUMBO */
13383
13384    /*
13385     * Continuation if the field has not yet been resolved.
13386     *  r1: AAAAAAAA field ref
13387     */
13388.LOP_SGET_BYTE_JUMBO_resolve:
13389    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13390    EXPORT_PC()                         @ resolve() could throw, so export now
13391    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13392    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13393    cmp     r0, #0                      @ success?
13394    bne     .LOP_SGET_BYTE_JUMBO_finish          @ yes, finish
13395    b       common_exceptionThrown      @ no, handle exception
13396
13397/* continuation for OP_SGET_CHAR_JUMBO */
13398
13399    /*
13400     * Continuation if the field has not yet been resolved.
13401     *  r1: AAAAAAAA field ref
13402     */
13403.LOP_SGET_CHAR_JUMBO_resolve:
13404    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13405    EXPORT_PC()                         @ resolve() could throw, so export now
13406    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13407    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13408    cmp     r0, #0                      @ success?
13409    bne     .LOP_SGET_CHAR_JUMBO_finish          @ yes, finish
13410    b       common_exceptionThrown      @ no, handle exception
13411
13412/* continuation for OP_SGET_SHORT_JUMBO */
13413
13414    /*
13415     * Continuation if the field has not yet been resolved.
13416     *  r1: AAAAAAAA field ref
13417     */
13418.LOP_SGET_SHORT_JUMBO_resolve:
13419    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13420    EXPORT_PC()                         @ resolve() could throw, so export now
13421    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13422    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13423    cmp     r0, #0                      @ success?
13424    bne     .LOP_SGET_SHORT_JUMBO_finish          @ yes, finish
13425    b       common_exceptionThrown      @ no, handle exception
13426
13427/* continuation for OP_SPUT_JUMBO */
13428
13429    /*
13430     * Continuation if the field has not yet been resolved.
13431     *  r1: AAAAAAAA field ref
13432     */
13433.LOP_SPUT_JUMBO_resolve:
13434    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13435    EXPORT_PC()                         @ resolve() could throw, so export now
13436    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13437    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13438    cmp     r0, #0                      @ success?
13439    bne     .LOP_SPUT_JUMBO_finish          @ yes, finish
13440    b       common_exceptionThrown      @ no, handle exception
13441
13442/* continuation for OP_SPUT_WIDE_JUMBO */
13443
13444    /*
13445     * Continuation if the field has not yet been resolved.
13446     *  r1: BBBB field ref
13447     *  r9: &fp[AA]
13448     *
13449     * Returns StaticField pointer in r2.
13450     */
13451.LOP_SPUT_WIDE_JUMBO_resolve:
13452    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13453    EXPORT_PC()                         @ resolve() could throw, so export now
13454    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13455    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13456    cmp     r0, #0                      @ success?
13457    mov     r2, r0                      @ copy to r2
13458    bne     .LOP_SPUT_WIDE_JUMBO_finish          @ yes, finish
13459    b       common_exceptionThrown      @ no, handle exception
13460
13461/* continuation for OP_SPUT_OBJECT_JUMBO */
13462
13463.LOP_SPUT_OBJECT_JUMBO_finish:   @ field ptr in r0
13464    FETCH(r2, 3)                        @ r2<- BBBB
13465    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
13466    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
13467    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
13468    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
13469    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13470    @ no-op                             @ releasing store
13471    str     r1, [r0, #offStaticField_value]  @ field<- vBBBB
13472    cmp     r1, #0                      @ stored a null object?
13473    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
13474    GOTO_OPCODE(ip)                     @ jump to next instruction
13475
13476/* continuation for OP_SPUT_BOOLEAN_JUMBO */
13477
13478    /*
13479     * Continuation if the field has not yet been resolved.
13480     *  r1: AAAAAAAA field ref
13481     */
13482.LOP_SPUT_BOOLEAN_JUMBO_resolve:
13483    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13484    EXPORT_PC()                         @ resolve() could throw, so export now
13485    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13486    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13487    cmp     r0, #0                      @ success?
13488    bne     .LOP_SPUT_BOOLEAN_JUMBO_finish          @ yes, finish
13489    b       common_exceptionThrown      @ no, handle exception
13490
13491/* continuation for OP_SPUT_BYTE_JUMBO */
13492
13493    /*
13494     * Continuation if the field has not yet been resolved.
13495     *  r1: AAAAAAAA field ref
13496     */
13497.LOP_SPUT_BYTE_JUMBO_resolve:
13498    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13499    EXPORT_PC()                         @ resolve() could throw, so export now
13500    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13501    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13502    cmp     r0, #0                      @ success?
13503    bne     .LOP_SPUT_BYTE_JUMBO_finish          @ yes, finish
13504    b       common_exceptionThrown      @ no, handle exception
13505
13506/* continuation for OP_SPUT_CHAR_JUMBO */
13507
13508    /*
13509     * Continuation if the field has not yet been resolved.
13510     *  r1: AAAAAAAA field ref
13511     */
13512.LOP_SPUT_CHAR_JUMBO_resolve:
13513    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13514    EXPORT_PC()                         @ resolve() could throw, so export now
13515    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13516    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13517    cmp     r0, #0                      @ success?
13518    bne     .LOP_SPUT_CHAR_JUMBO_finish          @ yes, finish
13519    b       common_exceptionThrown      @ no, handle exception
13520
13521/* continuation for OP_SPUT_SHORT_JUMBO */
13522
13523    /*
13524     * Continuation if the field has not yet been resolved.
13525     *  r1: AAAAAAAA field ref
13526     */
13527.LOP_SPUT_SHORT_JUMBO_resolve:
13528    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13529    EXPORT_PC()                         @ resolve() could throw, so export now
13530    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13531    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13532    cmp     r0, #0                      @ success?
13533    bne     .LOP_SPUT_SHORT_JUMBO_finish          @ yes, finish
13534    b       common_exceptionThrown      @ no, handle exception
13535
13536/* continuation for OP_INVOKE_VIRTUAL_JUMBO */
13537
13538    /*
13539     * At this point:
13540     *  r0 = resolved base method
13541     */
13542.LOP_INVOKE_VIRTUAL_JUMBO_continue:
13543    FETCH(r10, 4)                       @ r10<- CCCC
13544    GET_VREG(r1, r10)                   @ r1<- "this" ptr
13545    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
13546    cmp     r1, #0                      @ is "this" null?
13547    beq     common_errNullObject        @ null "this", throw exception
13548    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
13549    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
13550    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
13551    bl      common_invokeMethodJumbo    @ continue on
13552
13553/* continuation for OP_INVOKE_SUPER_JUMBO */
13554
13555    /*
13556     * At this point:
13557     *  r0 = resolved base method
13558     *  r9 = method->clazz
13559     */
13560.LOP_INVOKE_SUPER_JUMBO_continue:
13561    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
13562    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
13563    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
13564    EXPORT_PC()                         @ must export for invoke
13565    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
13566    bcs     .LOP_INVOKE_SUPER_JUMBO_nsm             @ method not present in superclass
13567    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
13568    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
13569    bl      common_invokeMethodJumbo    @ continue on
13570
13571.LOP_INVOKE_SUPER_JUMBO_resolve:
13572    mov     r0, r9                      @ r0<- method->clazz
13573    mov     r2, #METHOD_VIRTUAL         @ resolver method type
13574    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
13575    cmp     r0, #0                      @ got null?
13576    bne     .LOP_INVOKE_SUPER_JUMBO_continue        @ no, continue
13577    b       common_exceptionThrown      @ yes, handle exception
13578
13579    /*
13580     * Throw a NoSuchMethodError with the method name as the message.
13581     *  r0 = resolved base method
13582     */
13583.LOP_INVOKE_SUPER_JUMBO_nsm:
13584    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
13585    b       common_errNoSuchMethod
13586
13587/* continuation for OP_INVOKE_DIRECT_JUMBO */
13588
13589    /*
13590     * On entry:
13591     *  r1 = reference (CCCC)
13592     *  r10 = "this" register
13593     */
13594.LOP_INVOKE_DIRECT_JUMBO_resolve:
13595    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
13596    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
13597    mov     r2, #METHOD_DIRECT          @ resolver method type
13598    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
13599    cmp     r0, #0                      @ got null?
13600    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
13601    bne     .LOP_INVOKE_DIRECT_JUMBO_finish          @ no, continue
13602    b       common_exceptionThrown      @ yes, handle exception
13603
13604    .size   dvmAsmSisterStart, .-dvmAsmSisterStart
13605    .global dvmAsmSisterEnd
13606dvmAsmSisterEnd:
13607
13608/* File: armv5te/footer.S */
13609
13610/*
13611 * ===========================================================================
13612 *  Common subroutines and data
13613 * ===========================================================================
13614 */
13615
13616
13617
13618    .text
13619    .align  2
13620
13621#if defined(WITH_JIT)
13622#if defined(WITH_SELF_VERIFICATION)
13623    .global dvmJitToInterpPunt
13624dvmJitToInterpPunt:
13625    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13626    mov    r2,#kSVSPunt                 @ r2<- interpreter entry point
13627    mov    r3, #0
13628    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13629    b      jitSVShadowRunEnd            @ doesn't return
13630
13631    .global dvmJitToInterpSingleStep
13632dvmJitToInterpSingleStep:
13633    str    lr,[rGLUE,#offGlue_jitResumeNPC]
13634    str    r1,[rGLUE,#offGlue_jitResumeDPC]
13635    mov    r2,#kSVSSingleStep           @ r2<- interpreter entry point
13636    b      jitSVShadowRunEnd            @ doesn't return
13637
13638    .global dvmJitToInterpNoChainNoProfile
13639dvmJitToInterpNoChainNoProfile:
13640    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13641    mov    r0,rPC                       @ pass our target PC
13642    mov    r2,#kSVSNoProfile            @ r2<- interpreter entry point
13643    mov    r3, #0                       @ 0 means !inJitCodeCache
13644    str    r3, [r10, #offThread_inJitCodeCache] @ back to the interp land
13645    b      jitSVShadowRunEnd            @ doesn't return
13646
13647    .global dvmJitToInterpTraceSelectNoChain
13648dvmJitToInterpTraceSelectNoChain:
13649    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13650    mov    r0,rPC                       @ pass our target PC
13651    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
13652    mov    r3, #0                       @ 0 means !inJitCodeCache
13653    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13654    b      jitSVShadowRunEnd            @ doesn't return
13655
13656    .global dvmJitToInterpTraceSelect
13657dvmJitToInterpTraceSelect:
13658    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13659    ldr    r0,[lr, #-1]                 @ pass our target PC
13660    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
13661    mov    r3, #0                       @ 0 means !inJitCodeCache
13662    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13663    b      jitSVShadowRunEnd            @ doesn't return
13664
13665    .global dvmJitToInterpBackwardBranch
13666dvmJitToInterpBackwardBranch:
13667    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13668    ldr    r0,[lr, #-1]                 @ pass our target PC
13669    mov    r2,#kSVSBackwardBranch       @ r2<- interpreter entry point
13670    mov    r3, #0                       @ 0 means !inJitCodeCache
13671    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13672    b      jitSVShadowRunEnd            @ doesn't return
13673
13674    .global dvmJitToInterpNormal
13675dvmJitToInterpNormal:
13676    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13677    ldr    r0,[lr, #-1]                 @ pass our target PC
13678    mov    r2,#kSVSNormal               @ r2<- interpreter entry point
13679    mov    r3, #0                       @ 0 means !inJitCodeCache
13680    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13681    b      jitSVShadowRunEnd            @ doesn't return
13682
13683    .global dvmJitToInterpNoChain
13684dvmJitToInterpNoChain:
13685    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13686    mov    r0,rPC                       @ pass our target PC
13687    mov    r2,#kSVSNoChain              @ r2<- interpreter entry point
13688    mov    r3, #0                       @ 0 means !inJitCodeCache
13689    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13690    b      jitSVShadowRunEnd            @ doesn't return
13691#else
13692/*
13693 * Return from the translation cache to the interpreter when the compiler is
13694 * having issues translating/executing a Dalvik instruction. We have to skip
13695 * the code cache lookup otherwise it is possible to indefinitely bouce
13696 * between the interpreter and the code cache if the instruction that fails
13697 * to be compiled happens to be at a trace start.
13698 */
13699    .global dvmJitToInterpPunt
13700dvmJitToInterpPunt:
13701    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13702    mov    rPC, r0
13703#if defined(WITH_JIT_TUNING)
13704    mov    r0,lr
13705    bl     dvmBumpPunt;
13706#endif
13707    EXPORT_PC()
13708    mov    r0, #0
13709    str    r0, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13710    adrl   rIBASE, dvmAsmInstructionStart
13711    FETCH_INST()
13712    GET_INST_OPCODE(ip)
13713    GOTO_OPCODE(ip)
13714
13715/*
13716 * Return to the interpreter to handle a single instruction.
13717 * On entry:
13718 *    r0 <= PC
13719 *    r1 <= PC of resume instruction
13720 *    lr <= resume point in translation
13721 */
13722    .global dvmJitToInterpSingleStep
13723dvmJitToInterpSingleStep:
13724    str    lr,[rGLUE,#offGlue_jitResumeNPC]
13725    str    r1,[rGLUE,#offGlue_jitResumeDPC]
13726    mov    r1,#kInterpEntryInstr
13727    @ enum is 4 byte in aapcs-EABI
13728    str    r1, [rGLUE, #offGlue_entryPoint]
13729    mov    rPC,r0
13730    EXPORT_PC()
13731
13732    adrl   rIBASE, dvmAsmInstructionStart
13733    mov    r2,#kJitSingleStep     @ Ask for single step and then revert
13734    str    r2,[rGLUE,#offGlue_jitState]
13735    mov    r1,#1                  @ set changeInterp to bail to debug interp
13736    b      common_gotoBail
13737
13738/*
13739 * Return from the translation cache and immediately request
13740 * a translation for the exit target.  Commonly used for callees.
13741 */
13742    .global dvmJitToInterpTraceSelectNoChain
13743dvmJitToInterpTraceSelectNoChain:
13744#if defined(WITH_JIT_TUNING)
13745    bl     dvmBumpNoChain
13746#endif
13747    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13748    mov    r0,rPC
13749    bl     dvmJitGetTraceAddr       @ Is there a translation?
13750    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13751    mov    r1, rPC                  @ arg1 of translation may need this
13752    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13753    cmp    r0,#0                    @ !0 means translation exists
13754    bxne   r0                       @ continue native execution if so
13755    b      2f                       @ branch over to use the interpreter
13756
13757/*
13758 * Return from the translation cache and immediately request
13759 * a translation for the exit target.  Commonly used following
13760 * invokes.
13761 */
13762    .global dvmJitToInterpTraceSelect
13763dvmJitToInterpTraceSelect:
13764    ldr    rPC,[lr, #-1]           @ get our target PC
13765    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13766    add    rINST,lr,#-5            @ save start of chain branch
13767    add    rINST, #-4              @  .. which is 9 bytes back
13768    mov    r0,rPC
13769    bl     dvmJitGetTraceAddr      @ Is there a translation?
13770    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13771    cmp    r0,#0
13772    beq    2f
13773    mov    r1,rINST
13774    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
13775    mov    r1, rPC                  @ arg1 of translation may need this
13776    mov    lr, #0                   @ in case target is HANDLER_INTERPRET
13777    cmp    r0,#0                    @ successful chain?
13778    bxne   r0                       @ continue native execution
13779    b      toInterpreter            @ didn't chain - resume with interpreter
13780
13781/* No translation, so request one if profiling isn't disabled*/
137822:
13783    adrl   rIBASE, dvmAsmInstructionStart
13784    GET_JIT_PROF_TABLE(r0)
13785    FETCH_INST()
13786    cmp    r0, #0
13787    movne  r2,#kJitTSelectRequestHot   @ ask for trace selection
13788    bne    common_selectTrace
13789    GET_INST_OPCODE(ip)
13790    GOTO_OPCODE(ip)
13791
13792/*
13793 * Return from the translation cache to the interpreter.
13794 * The return was done with a BLX from thumb mode, and
13795 * the following 32-bit word contains the target rPC value.
13796 * Note that lr (r14) will have its low-order bit set to denote
13797 * its thumb-mode origin.
13798 *
13799 * We'll need to stash our lr origin away, recover the new
13800 * target and then check to see if there is a translation available
13801 * for our new target.  If so, we do a translation chain and
13802 * go back to native execution.  Otherwise, it's back to the
13803 * interpreter (after treating this entry as a potential
13804 * trace start).
13805 */
13806    .global dvmJitToInterpNormal
13807dvmJitToInterpNormal:
13808    ldr    rPC,[lr, #-1]           @ get our target PC
13809    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13810    add    rINST,lr,#-5            @ save start of chain branch
13811    add    rINST,#-4               @ .. which is 9 bytes back
13812#if defined(WITH_JIT_TUNING)
13813    bl     dvmBumpNormal
13814#endif
13815    mov    r0,rPC
13816    bl     dvmJitGetTraceAddr      @ Is there a translation?
13817    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13818    cmp    r0,#0
13819    beq    toInterpreter            @ go if not, otherwise do chain
13820    mov    r1,rINST
13821    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
13822    mov    r1, rPC                  @ arg1 of translation may need this
13823    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13824    cmp    r0,#0                    @ successful chain?
13825    bxne   r0                       @ continue native execution
13826    b      toInterpreter            @ didn't chain - resume with interpreter
13827
13828/*
13829 * Return from the translation cache to the interpreter to do method invocation.
13830 * Check if translation exists for the callee, but don't chain to it.
13831 */
13832    .global dvmJitToInterpNoChainNoProfile
13833dvmJitToInterpNoChainNoProfile:
13834#if defined(WITH_JIT_TUNING)
13835    bl     dvmBumpNoChain
13836#endif
13837    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13838    mov    r0,rPC
13839    bl     dvmJitGetTraceAddr       @ Is there a translation?
13840    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13841    mov    r1, rPC                  @ arg1 of translation may need this
13842    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13843    cmp    r0,#0
13844    bxne   r0                       @ continue native execution if so
13845    EXPORT_PC()
13846    adrl   rIBASE, dvmAsmInstructionStart
13847    FETCH_INST()
13848    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13849    GOTO_OPCODE(ip)                     @ jump to next instruction
13850
13851/*
13852 * Return from the translation cache to the interpreter to do method invocation.
13853 * Check if translation exists for the callee, but don't chain to it.
13854 */
13855    .global dvmJitToInterpNoChain
13856dvmJitToInterpNoChain:
13857#if defined(WITH_JIT_TUNING)
13858    bl     dvmBumpNoChain
13859#endif
13860    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13861    mov    r0,rPC
13862    bl     dvmJitGetTraceAddr       @ Is there a translation?
13863    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13864    mov    r1, rPC                  @ arg1 of translation may need this
13865    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13866    cmp    r0,#0
13867    bxne   r0                       @ continue native execution if so
13868#endif
13869
13870/*
13871 * No translation, restore interpreter regs and start interpreting.
13872 * rGLUE & rFP were preserved in the translated code, and rPC has
13873 * already been restored by the time we get here.  We'll need to set
13874 * up rIBASE & rINST, and load the address of the JitTable into r0.
13875 */
13876toInterpreter:
13877    EXPORT_PC()
13878    adrl   rIBASE, dvmAsmInstructionStart
13879    FETCH_INST()
13880    GET_JIT_PROF_TABLE(r0)
13881    @ NOTE: intended fallthrough
13882
13883/*
13884 * Common code to update potential trace start counter, and initiate
13885 * a trace-build if appropriate.  On entry, rPC should point to the
13886 * next instruction to execute, and rINST should be already loaded with
13887 * the next opcode word, and r0 holds a pointer to the jit profile
13888 * table (pJitProfTable).
13889 */
13890common_testUpdateProfile:
13891    cmp     r0,#0
13892    GET_INST_OPCODE(ip)
13893    GOTO_OPCODE_IFEQ(ip)       @ if not profiling, fallthrough otherwise */
13894
13895common_updateProfile:
13896    eor     r3,rPC,rPC,lsr #12 @ cheap, but fast hash function
13897    lsl     r3,r3,#(32 - JIT_PROF_SIZE_LOG_2)          @ shift out excess bits
13898    ldrb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter
13899    GET_INST_OPCODE(ip)
13900    subs    r1,r1,#1           @ decrement counter
13901    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it
13902    GOTO_OPCODE_IFNE(ip)       @ if not threshold, fallthrough otherwise */
13903
13904/*
13905 * Here, we switch to the debug interpreter to request
13906 * trace selection.  First, though, check to see if there
13907 * is already a native translation in place (and, if so,
13908 * jump to it now).
13909 */
13910    GET_JIT_THRESHOLD(r1)
13911    ldr     r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
13912    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter
13913    EXPORT_PC()
13914    mov     r0,rPC
13915    bl      dvmJitGetTraceAddr          @ r0<- dvmJitGetTraceAddr(rPC)
13916    str     r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13917    mov     r1, rPC                     @ arg1 of translation may need this
13918    mov     lr, #0                      @  in case target is HANDLER_INTERPRET
13919    cmp     r0,#0
13920#if !defined(WITH_SELF_VERIFICATION)
13921    bxne    r0                          @ jump to the translation
13922    mov     r2,#kJitTSelectRequest      @ ask for trace selection
13923    @ fall-through to common_selectTrace
13924#else
13925    moveq   r2,#kJitTSelectRequest      @ ask for trace selection
13926    beq     common_selectTrace
13927    /*
13928     * At this point, we have a target translation.  However, if
13929     * that translation is actually the interpret-only pseudo-translation
13930     * we want to treat it the same as no translation.
13931     */
13932    mov     r10, r0                     @ save target
13933    bl      dvmCompilerGetInterpretTemplate
13934    cmp     r0, r10                     @ special case?
13935    bne     jitSVShadowRunStart         @ set up self verification shadow space
13936    @ Need to clear the inJitCodeCache flag
13937    ldr    r10, [rGLUE, #offGlue_self]  @ r10 <- glue->self
13938    mov    r3, #0                       @ 0 means not in the JIT code cache
13939    str    r3, [r10, #offThread_inJitCodeCache] @ back to the interp land
13940    GET_INST_OPCODE(ip)
13941    GOTO_OPCODE(ip)
13942    /* no return */
13943#endif
13944
13945/*
13946 * On entry:
13947 *  r2 is jit state, e.g. kJitTSelectRequest or kJitTSelectRequestHot
13948 */
13949common_selectTrace:
13950    str     r2,[rGLUE,#offGlue_jitState]
13951    mov     r2,#kInterpEntryInstr       @ normal entry reason
13952    str     r2,[rGLUE,#offGlue_entryPoint]
13953    mov     r1,#1                       @ set changeInterp
13954    b       common_gotoBail
13955
13956#if defined(WITH_SELF_VERIFICATION)
13957/*
13958 * Save PC and registers to shadow memory for self verification mode
13959 * before jumping to native translation.
13960 * On entry:
13961 *    rPC, rFP, rGLUE: the values that they should contain
13962 *    r10: the address of the target translation.
13963 */
13964jitSVShadowRunStart:
13965    mov     r0,rPC                      @ r0<- program counter
13966    mov     r1,rFP                      @ r1<- frame pointer
13967    mov     r2,rGLUE                    @ r2<- InterpState pointer
13968    mov     r3,r10                      @ r3<- target translation
13969    bl      dvmSelfVerificationSaveState @ save registers to shadow space
13970    ldr     rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space
13971    add     rGLUE,r0,#offShadowSpace_interpState @ rGLUE<- rGLUE in shadow space
13972    bx      r10                         @ jump to the translation
13973
13974/*
13975 * Restore PC, registers, and interpState to original values
13976 * before jumping back to the interpreter.
13977 */
13978jitSVShadowRunEnd:
13979    mov    r1,rFP                        @ pass ending fp
13980    bl     dvmSelfVerificationRestoreState @ restore pc and fp values
13981    ldr    rPC,[r0,#offShadowSpace_startPC] @ restore PC
13982    ldr    rFP,[r0,#offShadowSpace_fp]   @ restore FP
13983    ldr    rGLUE,[r0,#offShadowSpace_glue] @ restore InterpState
13984    ldr    r1,[r0,#offShadowSpace_svState] @ get self verification state
13985    cmp    r1,#0                         @ check for punt condition
13986    beq    1f
13987    mov    r2,#kJitSelfVerification      @ ask for self verification
13988    str    r2,[rGLUE,#offGlue_jitState]
13989    mov    r2,#kInterpEntryInstr         @ normal entry reason
13990    str    r2,[rGLUE,#offGlue_entryPoint]
13991    mov    r1,#1                         @ set changeInterp
13992    b      common_gotoBail
13993
139941:                                       @ exit to interpreter without check
13995    EXPORT_PC()
13996    adrl   rIBASE, dvmAsmInstructionStart
13997    FETCH_INST()
13998    GET_INST_OPCODE(ip)
13999    GOTO_OPCODE(ip)
14000#endif
14001
14002#endif
14003
14004/*
14005 * Common code when a backward branch is taken.
14006 *
14007 * TODO: we could avoid a branch by just setting r0 and falling through
14008 * into the common_periodicChecks code, and having a test on r0 at the
14009 * end determine if we should return to the caller or update & branch to
14010 * the next instr.
14011 *
14012 * On entry:
14013 *  r9 is PC adjustment *in bytes*
14014 */
14015common_backwardBranch:
14016    mov     r0, #kInterpEntryInstr
14017    bl      common_periodicChecks
14018#if defined(WITH_JIT)
14019    GET_JIT_PROF_TABLE(r0)
14020    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
14021    cmp     r0,#0
14022    bne     common_updateProfile
14023    GET_INST_OPCODE(ip)
14024    GOTO_OPCODE(ip)
14025#else
14026    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
14027    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14028    GOTO_OPCODE(ip)                     @ jump to next instruction
14029#endif
14030
14031
14032/*
14033 * Need to see if the thread needs to be suspended or debugger/profiler
14034 * activity has begun.  If so, we suspend the thread or side-exit to
14035 * the debug interpreter as appropriate.
14036 *
14037 * The common case is no activity on any of these, so we want to figure
14038 * that out quickly.  If something is up, we can then sort out what.
14039 *
14040 * We want to be fast if the VM was built without debugger or profiler
14041 * support, but we also need to recognize that the system is usually
14042 * shipped with both of these enabled.
14043 *
14044 * TODO: reduce this so we're just checking a single location.
14045 *
14046 * On entry:
14047 *  r0 is reentry type, e.g. kInterpEntryInstr (for debugger/profiling)
14048 *  r9 is trampoline PC adjustment *in bytes*
14049 */
14050common_periodicChecks:
14051    ldr     r1, [rGLUE, #offGlue_pInterpBreak] @ r3<- &interpBreak
14052    /* speculatively load address of thread-specific suspend count */
14053    ldr     r3, [rGLUE, #offGlue_pSelfSuspendCount] @ r3<- &suspendCount
14054    ldr     r1, [r1]                                @ r1<- interpBreak
14055    /* speculatively load thread-specific suspend count */
14056    ldr     ip, [r3]                    @ ip<- suspendCount (int)
14057    cmp     r1, #0                                  @ anything unusual?
14058    bxeq    lr                                      @ return if not
14059    /*
14060     * One or more interesting events have happened.  Figure out what.
14061     *
14062     * r0 still holds the reentry type.
14063     */
14064    cmp     ip, #0                      @ want suspend?
14065    beq     3f                          @ no, must be something else
14066
14067    stmfd   sp!, {r0, lr}               @ preserve r0 and lr
14068#if defined(WITH_JIT)
14069    /*
14070     * Refresh the Jit's cached copy of profile table pointer.  This pointer
14071     * doubles as the Jit's on/off switch.
14072     */
14073    ldr     r3, [rGLUE, #offGlue_ppJitProfTable] @ r3<-&gDvmJit.pJitProfTable
14074    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
14075    ldr     r3, [r3] @ r3 <- pJitProfTable
14076    EXPORT_PC()                         @ need for precise GC
14077    str     r3, [rGLUE, #offGlue_pJitProfTable] @ refresh Jit's on/off switch
14078#else
14079    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
14080    EXPORT_PC()                         @ need for precise GC
14081#endif
14082    bl      dvmCheckSuspendPending      @ do full check, suspend if necessary
14083    ldmfd   sp!, {r0, lr}               @ restore r0 and lr
14084
14085    /*
14086     * Reload the interpBreak flags - they may have changed while we
14087     * were suspended.
14088     */
14089    ldr     r1, [rGLUE, #offGlue_pInterpBreak]   @ r1<- &interpBreak
14090    ldr     r1, [r1]                    @ r1<- interpBreak
140913:
14092    /*
14093     * TODO: this code is too fragile.  Need a general mechanism
14094     * to identify what actions to take by submode.  Some profiling modes
14095     * (instruction count) need to single-step, while method tracing
14096     * may not.  Debugging with breakpoints can run unfettered, but
14097     * source-level single-stepping requires Dalvik singlestepping.
14098     * GC may require a one-shot action and then full-speed resumption.
14099     */
14100    ands    r1, #(kSubModeDebuggerActive | kSubModeEmulatorTrace | kSubModeInstCounting)
14101    bxeq    lr                          @ nothing to do, return
14102
14103    @ debugger/profiler enabled, bail out; glue->entryPoint was set above
14104    str     r0, [rGLUE, #offGlue_entryPoint]    @ store r0, need for debug/prof
14105    add     rPC, rPC, r9                @ update rPC
14106    mov     r1, #1                      @ "want switch" = true
14107    b       common_gotoBail             @ side exit
14108
14109
14110/*
14111 * The equivalent of "goto bail", this calls through the "bail handler".
14112 *
14113 * State registers will be saved to the "glue" area before bailing.
14114 *
14115 * On entry:
14116 *  r1 is "bool changeInterp", indicating if we want to switch to the
14117 *     other interpreter or just bail all the way out
14118 */
14119common_gotoBail:
14120    SAVE_PC_FP_TO_GLUE()                @ export state to "glue"
14121    mov     r0, rGLUE                   @ r0<- glue ptr
14122    b       dvmMterpStdBail             @ call(glue, changeInterp)
14123
14124    @add     r1, r1, #1                  @ using (boolean+1)
14125    @add     r0, rGLUE, #offGlue_jmpBuf  @ r0<- &glue->jmpBuf
14126    @bl      _longjmp                    @ does not return
14127    @bl      common_abort
14128
14129
14130/*
14131 * Common code for jumbo method invocation.
14132 * NOTE: this adjusts rPC to account for the difference in instruction width.
14133 * As a result, the savedPc in the stack frame will not be wholly accurate. So
14134 * long as that is only used for source file line number calculations, we're
14135 * okay.
14136 *
14137 * On entry:
14138 *  r0 is "Method* methodToCall", the method we're trying to call
14139 */
14140common_invokeMethodJumbo:
14141.LinvokeNewJumbo:
14142    @ prepare to copy args to "outs" area of current frame
14143    add     rPC, rPC, #4                @ adjust pc to make return consistent
14144    FETCH(r2, 1)                        @ r2<- BBBB (arg count)
14145    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
14146    cmp     r2, #0                      @ no args?
14147    beq     .LinvokeArgsDone            @ if no args, skip the rest
14148    FETCH(r1, 2)                        @ r1<- CCCC
14149    b       .LinvokeRangeArgs           @ handle args like invoke range
14150
14151/*
14152 * Common code for method invocation with range.
14153 *
14154 * On entry:
14155 *  r0 is "Method* methodToCall", the method we're trying to call
14156 */
14157common_invokeMethodRange:
14158.LinvokeNewRange:
14159    @ prepare to copy args to "outs" area of current frame
14160    movs    r2, rINST, lsr #8           @ r2<- AA (arg count) -- test for zero
14161    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
14162    beq     .LinvokeArgsDone            @ if no args, skip the rest
14163    FETCH(r1, 2)                        @ r1<- CCCC
14164
14165.LinvokeRangeArgs:
14166    @ r0=methodToCall, r1=CCCC, r2=count, r10=outs
14167    @ (very few methods have > 10 args; could unroll for common cases)
14168    add     r3, rFP, r1, lsl #2         @ r3<- &fp[CCCC]
14169    sub     r10, r10, r2, lsl #2        @ r10<- "outs" area, for call args
141701:  ldr     r1, [r3], #4                @ val = *fp++
14171    subs    r2, r2, #1                  @ count--
14172    str     r1, [r10], #4               @ *outs++ = val
14173    bne     1b                          @ ...while count != 0
14174    b       .LinvokeArgsDone
14175
14176/*
14177 * Common code for method invocation without range.
14178 *
14179 * On entry:
14180 *  r0 is "Method* methodToCall", the method we're trying to call
14181 */
14182common_invokeMethodNoRange:
14183.LinvokeNewNoRange:
14184    @ prepare to copy args to "outs" area of current frame
14185    movs    r2, rINST, lsr #12          @ r2<- B (arg count) -- test for zero
14186    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
14187    FETCH(r1, 2)                        @ r1<- GFED (load here to hide latency)
14188    beq     .LinvokeArgsDone
14189
14190    @ r0=methodToCall, r1=GFED, r2=count, r10=outs
14191.LinvokeNonRange:
14192    rsb     r2, r2, #5                  @ r2<- 5-r2
14193    add     pc, pc, r2, lsl #4          @ computed goto, 4 instrs each
14194    bl      common_abort                @ (skipped due to ARM prefetch)
141955:  and     ip, rINST, #0x0f00          @ isolate A
14196    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vA (shift right 8, left 2)
14197    mov     r0, r0                      @ nop
14198    str     r2, [r10, #-4]!             @ *--outs = vA
141994:  and     ip, r1, #0xf000             @ isolate G
14200    ldr     r2, [rFP, ip, lsr #10]      @ r2<- vG (shift right 12, left 2)
14201    mov     r0, r0                      @ nop
14202    str     r2, [r10, #-4]!             @ *--outs = vG
142033:  and     ip, r1, #0x0f00             @ isolate F
14204    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vF
14205    mov     r0, r0                      @ nop
14206    str     r2, [r10, #-4]!             @ *--outs = vF
142072:  and     ip, r1, #0x00f0             @ isolate E
14208    ldr     r2, [rFP, ip, lsr #2]       @ r2<- vE
14209    mov     r0, r0                      @ nop
14210    str     r2, [r10, #-4]!             @ *--outs = vE
142111:  and     ip, r1, #0x000f             @ isolate D
14212    ldr     r2, [rFP, ip, lsl #2]       @ r2<- vD
14213    mov     r0, r0                      @ nop
14214    str     r2, [r10, #-4]!             @ *--outs = vD
142150:  @ fall through to .LinvokeArgsDone
14216
14217.LinvokeArgsDone: @ r0=methodToCall
14218    ldrh    r9, [r0, #offMethod_registersSize]  @ r9<- methodToCall->regsSize
14219    ldrh    r3, [r0, #offMethod_outsSize]  @ r3<- methodToCall->outsSize
14220    ldr     r2, [r0, #offMethod_insns]  @ r2<- method->insns
14221    ldr     rINST, [r0, #offMethod_clazz]  @ rINST<- method->clazz
14222    @ find space for the new stack frame, check for overflow
14223    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- stack save area
14224    sub     r1, r1, r9, lsl #2          @ r1<- newFp (old savearea - regsSize)
14225    SAVEAREA_FROM_FP(r10, r1)           @ r10<- newSaveArea
14226@    bl      common_dumpRegs
14227    ldr     r9, [rGLUE, #offGlue_interpStackEnd]    @ r9<- interpStackEnd
14228    sub     r3, r10, r3, lsl #2         @ r3<- bottom (newsave - outsSize)
14229    cmp     r3, r9                      @ bottom < interpStackEnd?
14230    ldr     lr, [rGLUE, #offGlue_pInterpBreak]
14231    ldr     r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags
14232    blo     .LstackOverflow             @ yes, this frame will overflow stack
14233
14234    @ set up newSaveArea
14235    ldr     lr, [lr]                    @ lr<- active submodes
14236#ifdef EASY_GDB
14237    SAVEAREA_FROM_FP(ip, rFP)           @ ip<- stack save area
14238    str     ip, [r10, #offStackSaveArea_prevSave]
14239#endif
14240    str     rFP, [r10, #offStackSaveArea_prevFrame]
14241    str     rPC, [r10, #offStackSaveArea_savedPc]
14242#if defined(WITH_JIT)
14243    mov     r9, #0
14244    str     r9, [r10, #offStackSaveArea_returnAddr]
14245#endif
14246    ands    lr, #kSubModeMethodTrace    @ method tracing?
14247    beq     1f                          @ skip if not
14248    stmfd   sp!, {r0-r3}                @ preserve r0-r3
14249    mov     r1, r6
14250    @ r0=methodToCall, r1=rGlue
14251    bl      dvmFastMethodTraceEnter
14252    ldmfd   sp!, {r0-r3}                @ restore r0-r3
142531:
14254    str     r0, [r10, #offStackSaveArea_method]
14255    tst     r3, #ACC_NATIVE
14256    bne     .LinvokeNative
14257
14258    /*
14259    stmfd   sp!, {r0-r3}
14260    bl      common_printNewline
14261    mov     r0, rFP
14262    mov     r1, #0
14263    bl      dvmDumpFp
14264    ldmfd   sp!, {r0-r3}
14265    stmfd   sp!, {r0-r3}
14266    mov     r0, r1
14267    mov     r1, r10
14268    bl      dvmDumpFp
14269    bl      common_printNewline
14270    ldmfd   sp!, {r0-r3}
14271    */
14272
14273    ldrh    r9, [r2]                        @ r9 <- load INST from new PC
14274    ldr     r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
14275    mov     rPC, r2                         @ publish new rPC
14276    ldr     r2, [rGLUE, #offGlue_self]      @ r2<- glue->self
14277
14278    @ Update "glue" values for the new method
14279    @ r0=methodToCall, r1=newFp, r2=self, r3=newMethodClass, r9=newINST
14280    str     r0, [rGLUE, #offGlue_method]    @ glue->method = methodToCall
14281    str     r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ...
14282#if defined(WITH_JIT)
14283    GET_JIT_PROF_TABLE(r0)
14284    mov     rFP, r1                         @ fp = newFp
14285    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
14286    mov     rINST, r9                       @ publish new rINST
14287    str     r1, [r2, #offThread_curFrame]   @ self->curFrame = newFp
14288    cmp     r0,#0
14289    bne     common_updateProfile
14290    GOTO_OPCODE(ip)                         @ jump to next instruction
14291#else
14292    mov     rFP, r1                         @ fp = newFp
14293    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
14294    mov     rINST, r9                       @ publish new rINST
14295    str     r1, [r2, #offThread_curFrame]   @ self->curFrame = newFp
14296    GOTO_OPCODE(ip)                         @ jump to next instruction
14297#endif
14298
14299.LinvokeNative:
14300    @ Prep for the native call
14301    @ r0=methodToCall, r1=newFp, r10=newSaveArea
14302    ldr     r3, [rGLUE, #offGlue_self]      @ r3<- glue->self
14303    ldr     lr, [rGLUE, #offGlue_pInterpBreak]
14304    ldr     r9, [r3, #offThread_jniLocal_topCookie] @ r9<- thread->localRef->...
14305    str     r1, [r3, #offThread_curFrame]   @ self->curFrame = newFp
14306    str     r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top
14307    ldr     lr, [lr]                    @ lr<- active submodes
14308    mov     r9, r3                      @ r9<- glue->self (preserve)
14309
14310    mov     r2, r0                      @ r2<- methodToCall
14311    mov     r0, r1                      @ r0<- newFp (points to args)
14312    add     r1, rGLUE, #offGlue_retval  @ r1<- &retval
14313
14314#ifdef ASSIST_DEBUGGER
14315    /* insert fake function header to help gdb find the stack frame */
14316    b       .Lskip
14317    .type   dalvik_mterp, %function
14318dalvik_mterp:
14319    .fnstart
14320    MTERP_ENTRY1
14321    MTERP_ENTRY2
14322.Lskip:
14323#endif
14324
14325    ands    lr, #kSubModeMethodTrace    @ method tracing?
14326    beq     110f                        @ hop if not
14327    @ r2=JNIMethod, r6=rGLUE
14328    stmfd   sp!, {r2,r6}
14329
14330    mov     lr, pc                      @ set return addr
14331    ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
14332
14333    @ r0=JNIMethod, r1=rGLUE
14334    ldmfd   sp!, {r0-r1}
14335    bl      dvmFastNativeMethodTraceExit
14336    b       220f
14337110:
14338    mov     lr, pc                      @ set return addr
14339    ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
14340220:
14341#if defined(WITH_JIT)
14342    ldr     r3, [rGLUE, #offGlue_ppJitProfTable] @ Refresh Jit's on/off status
14343#endif
14344
14345    @ native return; r9=self, r10=newSaveArea
14346    @ equivalent to dvmPopJniLocals
14347    ldr     r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top
14348    ldr     r1, [r9, #offThread_exception] @ check for exception
14349#if defined(WITH_JIT)
14350    ldr     r3, [r3]                    @ r3 <- gDvmJit.pProfTable
14351#endif
14352    str     rFP, [r9, #offThread_curFrame]  @ self->curFrame = fp
14353    cmp     r1, #0                      @ null?
14354    str     r0, [r9, #offThread_jniLocal_topCookie] @ new top <- old top
14355#if defined(WITH_JIT)
14356    str     r3, [rGLUE, #offGlue_pJitProfTable] @ refresh cached on/off switch
14357#endif
14358    bne     common_exceptionThrown      @ no, handle exception
14359
14360    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
14361    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14362    GOTO_OPCODE(ip)                     @ jump to next instruction
14363
14364.LstackOverflow:    @ r0=methodToCall
14365    mov     r1, r0                      @ r1<- methodToCall
14366    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- self
14367    bl      dvmHandleStackOverflow
14368    b       common_exceptionThrown
14369#ifdef ASSIST_DEBUGGER
14370    .fnend
14371#endif
14372
14373
14374    /*
14375     * Common code for method invocation, calling through "glue code".
14376     *
14377     * TODO: now that we have range and non-range invoke handlers, this
14378     *       needs to be split into two.  Maybe just create entry points
14379     *       that set r9 and jump here?
14380     *
14381     * On entry:
14382     *  r0 is "Method* methodToCall", the method we're trying to call
14383     *  r9 is "bool methodCallRange", indicating if this is a /range variant
14384     */
14385     .if    0
14386.LinvokeOld:
14387    sub     sp, sp, #8                  @ space for args + pad
14388    FETCH(ip, 2)                        @ ip<- FEDC or CCCC
14389    mov     r2, r0                      @ A2<- methodToCall
14390    mov     r0, rGLUE                   @ A0<- glue
14391    SAVE_PC_FP_TO_GLUE()                @ export state to "glue"
14392    mov     r1, r9                      @ A1<- methodCallRange
14393    mov     r3, rINST, lsr #8           @ A3<- AA
14394    str     ip, [sp, #0]                @ A4<- ip
14395    bl      dvmMterp_invokeMethod       @ call the C invokeMethod
14396    add     sp, sp, #8                  @ remove arg area
14397    b       common_resumeAfterGlueCall  @ continue to next instruction
14398    .endif
14399
14400
14401
14402/*
14403 * Common code for handling a return instruction.
14404 *
14405 * This does not return.
14406 */
14407common_returnFromMethod:
14408.LreturnNew:
14409    mov     r0, #kInterpEntryReturn
14410    mov     r9, #0
14411    bl      common_periodicChecks
14412
14413    ldr     lr, [rGLUE, #offGlue_pInterpBreak]
14414    SAVEAREA_FROM_FP(r0, rFP)
14415    ldr     lr, [lr]                    @ lr<- active submodes
14416    ldr     r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc
14417    ands    lr, #kSubModeMethodTrace    @ method tracing?
14418    beq     333f
14419    stmfd   sp!, {r0-r3}                @ preserve r0-r3
14420    mov     r0, r6
14421    @ r0=rGlue
14422    bl      dvmFastJavaMethodTraceExit
14423    ldmfd   sp!, {r0-r3}                @ restore r0-r3
14424333:
14425    ldr     rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame
14426    ldr     r3, [rGLUE, #offGlue_self]  @ r3<- glue->self
14427    ldr     r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)]
14428                                        @ r2<- method we're returning to
14429    cmp     r2, #0                      @ is this a break frame?
14430#if defined(WORKAROUND_CORTEX_A9_745320)
14431    /* Don't use conditional loads if the HW defect exists */
14432    beq     101f
14433    ldr     r10, [r2, #offMethod_clazz] @ r10<- method->clazz
14434101:
14435#else
14436    ldrne   r10, [r2, #offMethod_clazz] @ r10<- method->clazz
14437#endif
14438    mov     r1, #0                      @ "want switch" = false
14439    beq     common_gotoBail             @ break frame, bail out completely
14440
14441    PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST
14442    str     r2, [rGLUE, #offGlue_method]@ glue->method = newSave->method
14443    ldr     r1, [r10, #offClassObject_pDvmDex]   @ r1<- method->clazz->pDvmDex
14444    str     rFP, [r3, #offThread_curFrame]  @ self->curFrame = fp
14445#if defined(WITH_JIT)
14446    ldr     r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr
14447    mov     rPC, r9                     @ publish new rPC
14448    str     r1, [rGLUE, #offGlue_methodClassDex]
14449    str     r10, [r3, #offThread_inJitCodeCache]  @ may return to JIT'ed land
14450    cmp     r10, #0                      @ caller is compiled code
14451    blxne   r10
14452    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14453    GOTO_OPCODE(ip)                     @ jump to next instruction
14454#else
14455    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14456    mov     rPC, r9                     @ publish new rPC
14457    str     r1, [rGLUE, #offGlue_methodClassDex]
14458    GOTO_OPCODE(ip)                     @ jump to next instruction
14459#endif
14460
14461    /*
14462     * Return handling, calls through "glue code".
14463     */
14464     .if    0
14465.LreturnOld:
14466    SAVE_PC_FP_TO_GLUE()                @ export state
14467    mov     r0, rGLUE                   @ arg to function
14468    bl      dvmMterp_returnFromMethod
14469    b       common_resumeAfterGlueCall
14470    .endif
14471
14472
14473/*
14474 * Somebody has thrown an exception.  Handle it.
14475 *
14476 * If the exception processing code returns to us (instead of falling
14477 * out of the interpreter), continue with whatever the next instruction
14478 * now happens to be.
14479 *
14480 * This does not return.
14481 */
14482     .global dvmMterpCommonExceptionThrown
14483dvmMterpCommonExceptionThrown:
14484common_exceptionThrown:
14485.LexceptionNew:
14486    mov     r0, #kInterpEntryThrow
14487    mov     r9, #0
14488    bl      common_periodicChecks
14489
14490    ldr     r10, [rGLUE, #offGlue_self] @ r10<- glue->self
14491    ldr     r9, [r10, #offThread_exception] @ r9<- self->exception
14492    mov     r1, r10                     @ r1<- self
14493    mov     r0, r9                      @ r0<- exception
14494    bl      dvmAddTrackedAlloc          @ don't let the exception be GCed
14495    mov     r3, #0                      @ r3<- NULL
14496    str     r3, [r10, #offThread_exception] @ self->exception = NULL
14497
14498    /* set up args and a local for "&fp" */
14499    /* (str sp, [sp, #-4]!  would be perfect here, but is discouraged) */
14500    str     rFP, [sp, #-4]!             @ *--sp = fp
14501    mov     ip, sp                      @ ip<- &fp
14502    mov     r3, #0                      @ r3<- false
14503    str     ip, [sp, #-4]!              @ *--sp = &fp
14504    ldr     r1, [rGLUE, #offGlue_method] @ r1<- glue->method
14505    mov     r0, r10                     @ r0<- self
14506    ldr     r1, [r1, #offMethod_insns]  @ r1<- method->insns
14507    mov     r2, r9                      @ r2<- exception
14508    sub     r1, rPC, r1                 @ r1<- pc - method->insns
14509    mov     r1, r1, asr #1              @ r1<- offset in code units
14510
14511    /* call, r0 gets catchRelPc (a code-unit offset) */
14512    bl      dvmFindCatchBlock           @ call(self, relPc, exc, scan?, &fp)
14513
14514    /* fix earlier stack overflow if necessary; may trash rFP */
14515    ldrb    r1, [r10, #offThread_stackOverflowed]
14516    cmp     r1, #0                      @ did we overflow earlier?
14517    beq     1f                          @ no, skip ahead
14518    mov     rFP, r0                     @ save relPc result in rFP
14519    mov     r0, r10                     @ r0<- self
14520    mov     r1, r9                      @ r1<- exception
14521    bl      dvmCleanupStackOverflow     @ call(self)
14522    mov     r0, rFP                     @ restore result
145231:
14524
14525    /* update frame pointer and check result from dvmFindCatchBlock */
14526    ldr     rFP, [sp, #4]               @ retrieve the updated rFP
14527    cmp     r0, #0                      @ is catchRelPc < 0?
14528    add     sp, sp, #8                  @ restore stack
14529    bmi     .LnotCaughtLocally
14530
14531    /* adjust locals to match self->curFrame and updated PC */
14532    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- new save area
14533    ldr     r1, [r1, #offStackSaveArea_method] @ r1<- new method
14534    str     r1, [rGLUE, #offGlue_method]    @ glue->method = new method
14535    ldr     r2, [r1, #offMethod_clazz]      @ r2<- method->clazz
14536    ldr     r3, [r1, #offMethod_insns]      @ r3<- method->insns
14537    ldr     r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex
14538    add     rPC, r3, r0, asl #1             @ rPC<- method->insns + catchRelPc
14539    str     r2, [rGLUE, #offGlue_methodClassDex] @ glue->pDvmDex = meth...
14540
14541    /* release the tracked alloc on the exception */
14542    mov     r0, r9                      @ r0<- exception
14543    mov     r1, r10                     @ r1<- self
14544    bl      dvmReleaseTrackedAlloc      @ release the exception
14545
14546    /* restore the exception if the handler wants it */
14547    FETCH_INST()                        @ load rINST from rPC
14548    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14549    cmp     ip, #OP_MOVE_EXCEPTION      @ is it "move-exception"?
14550    streq   r9, [r10, #offThread_exception] @ yes, restore the exception
14551    GOTO_OPCODE(ip)                     @ jump to next instruction
14552
14553.LnotCaughtLocally: @ r9=exception, r10=self
14554    /* fix stack overflow if necessary */
14555    ldrb    r1, [r10, #offThread_stackOverflowed]
14556    cmp     r1, #0                      @ did we overflow earlier?
14557    movne   r0, r10                     @ if yes: r0<- self
14558    movne   r1, r9                      @ if yes: r1<- exception
14559    blne    dvmCleanupStackOverflow     @ if yes: call(self)
14560
14561    @ may want to show "not caught locally" debug messages here
14562#if DVM_SHOW_EXCEPTION >= 2
14563    /* call __android_log_print(prio, tag, format, ...) */
14564    /* "Exception %s from %s:%d not caught locally" */
14565    @ dvmLineNumFromPC(method, pc - method->insns)
14566    ldr     r0, [rGLUE, #offGlue_method]
14567    ldr     r1, [r0, #offMethod_insns]
14568    sub     r1, rPC, r1
14569    asr     r1, r1, #1
14570    bl      dvmLineNumFromPC
14571    str     r0, [sp, #-4]!
14572    @ dvmGetMethodSourceFile(method)
14573    ldr     r0, [rGLUE, #offGlue_method]
14574    bl      dvmGetMethodSourceFile
14575    str     r0, [sp, #-4]!
14576    @ exception->clazz->descriptor
14577    ldr     r3, [r9, #offObject_clazz]
14578    ldr     r3, [r3, #offClassObject_descriptor]
14579    @
14580    ldr     r2, strExceptionNotCaughtLocally
14581    ldr     r1, strLogTag
14582    mov     r0, #3                      @ LOG_DEBUG
14583    bl      __android_log_print
14584#endif
14585    str     r9, [r10, #offThread_exception] @ restore exception
14586    mov     r0, r9                      @ r0<- exception
14587    mov     r1, r10                     @ r1<- self
14588    bl      dvmReleaseTrackedAlloc      @ release the exception
14589    mov     r1, #0                      @ "want switch" = false
14590    b       common_gotoBail             @ bail out
14591
14592
14593    /*
14594     * Exception handling, calls through "glue code".
14595     */
14596    .if     0
14597.LexceptionOld:
14598    SAVE_PC_FP_TO_GLUE()                @ export state
14599    mov     r0, rGLUE                   @ arg to function
14600    bl      dvmMterp_exceptionThrown
14601    b       common_resumeAfterGlueCall
14602    .endif
14603
14604
14605/*
14606 * After returning from a "glued" function, pull out the updated
14607 * values and start executing at the next instruction.
14608 */
14609common_resumeAfterGlueCall:
14610    LOAD_PC_FP_FROM_GLUE()              @ pull rPC and rFP out of glue
14611    FETCH_INST()                        @ load rINST from rPC
14612    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14613    GOTO_OPCODE(ip)                     @ jump to next instruction
14614
14615/*
14616 * Invalid array index. Note that our calling convention is strange; we use r1
14617 * and r3 because those just happen to be the registers all our callers are
14618 * using. We shuffle them here before calling the C function.
14619 * r1: index
14620 * r3: size
14621 */
14622common_errArrayIndex:
14623    EXPORT_PC()
14624    mov     r0, r1
14625    mov     r1, r3
14626    bl      dvmThrowAIOOBE
14627    b       common_exceptionThrown
14628
14629/*
14630 * Integer divide or mod by zero.
14631 */
14632common_errDivideByZero:
14633    EXPORT_PC()
14634    ldr     r0, strArithmeticException
14635    ldr     r1, strDivideByZero
14636    bl      dvmThrowException
14637    b       common_exceptionThrown
14638
14639/*
14640 * Attempt to allocate an array with a negative size.
14641 */
14642common_errNegativeArraySize:
14643    EXPORT_PC()
14644    ldr     r0, strNegativeArraySizeException
14645    mov     r1, #0
14646    bl      dvmThrowException
14647    b       common_exceptionThrown
14648
14649/*
14650 * Invocation of a non-existent method.
14651 */
14652common_errNoSuchMethod:
14653    EXPORT_PC()
14654    ldr     r0, strNoSuchMethodError
14655    mov     r1, #0
14656    bl      dvmThrowException
14657    b       common_exceptionThrown
14658
14659/*
14660 * We encountered a null object when we weren't expecting one.  We
14661 * export the PC, throw a NullPointerException, and goto the exception
14662 * processing code.
14663 */
14664common_errNullObject:
14665    EXPORT_PC()
14666    ldr     r0, strNullPointerException
14667    mov     r1, #0
14668    bl      dvmThrowException
14669    b       common_exceptionThrown
14670
14671/*
14672 * For debugging, cause an immediate fault.  The source address will
14673 * be in lr (use a bl instruction to jump here).
14674 */
14675common_abort:
14676    ldr     pc, .LdeadFood
14677.LdeadFood:
14678    .word   0xdeadf00d
14679
14680/*
14681 * Spit out a "we were here", preserving all registers.  (The attempt
14682 * to save ip won't work, but we need to save an even number of
14683 * registers for EABI 64-bit stack alignment.)
14684 */
14685    .macro  SQUEAK num
14686common_squeak\num:
14687    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14688    ldr     r0, strSqueak
14689    mov     r1, #\num
14690    bl      printf
14691    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14692    bx      lr
14693    .endm
14694
14695    SQUEAK  0
14696    SQUEAK  1
14697    SQUEAK  2
14698    SQUEAK  3
14699    SQUEAK  4
14700    SQUEAK  5
14701
14702/*
14703 * Spit out the number in r0, preserving registers.
14704 */
14705common_printNum:
14706    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14707    mov     r1, r0
14708    ldr     r0, strSqueak
14709    bl      printf
14710    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14711    bx      lr
14712
14713/*
14714 * Print a newline, preserving registers.
14715 */
14716common_printNewline:
14717    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14718    ldr     r0, strNewline
14719    bl      printf
14720    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14721    bx      lr
14722
14723    /*
14724     * Print the 32-bit quantity in r0 as a hex value, preserving registers.
14725     */
14726common_printHex:
14727    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14728    mov     r1, r0
14729    ldr     r0, strPrintHex
14730    bl      printf
14731    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14732    bx      lr
14733
14734/*
14735 * Print the 64-bit quantity in r0-r1, preserving registers.
14736 */
14737common_printLong:
14738    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14739    mov     r3, r1
14740    mov     r2, r0
14741    ldr     r0, strPrintLong
14742    bl      printf
14743    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14744    bx      lr
14745
14746/*
14747 * Print full method info.  Pass the Method* in r0.  Preserves regs.
14748 */
14749common_printMethod:
14750    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14751    bl      dvmMterpPrintMethod
14752    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14753    bx      lr
14754
14755/*
14756 * Call a C helper function that dumps regs and possibly some
14757 * additional info.  Requires the C function to be compiled in.
14758 */
14759    .if     0
14760common_dumpRegs:
14761    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14762    bl      dvmMterpDumpArmRegs
14763    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14764    bx      lr
14765    .endif
14766
14767#if 0
14768/*
14769 * Experiment on VFP mode.
14770 *
14771 * uint32_t setFPSCR(uint32_t val, uint32_t mask)
14772 *
14773 * Updates the bits specified by "mask", setting them to the values in "val".
14774 */
14775setFPSCR:
14776    and     r0, r0, r1                  @ make sure no stray bits are set
14777    fmrx    r2, fpscr                   @ get VFP reg
14778    mvn     r1, r1                      @ bit-invert mask
14779    and     r2, r2, r1                  @ clear masked bits
14780    orr     r2, r2, r0                  @ set specified bits
14781    fmxr    fpscr, r2                   @ set VFP reg
14782    mov     r0, r2                      @ return new value
14783    bx      lr
14784
14785    .align  2
14786    .global dvmConfigureFP
14787    .type   dvmConfigureFP, %function
14788dvmConfigureFP:
14789    stmfd   sp!, {ip, lr}
14790    /* 0x03000000 sets DN/FZ */
14791    /* 0x00009f00 clears the six exception enable flags */
14792    bl      common_squeak0
14793    mov     r0, #0x03000000             @ r0<- 0x03000000
14794    add     r1, r0, #0x9f00             @ r1<- 0x03009f00
14795    bl      setFPSCR
14796    ldmfd   sp!, {ip, pc}
14797#endif
14798
14799
14800/*
14801 * String references, must be close to the code that uses them.
14802 */
14803    .align  2
14804strArithmeticException:
14805    .word   .LstrArithmeticException
14806strDivideByZero:
14807    .word   .LstrDivideByZero
14808strNegativeArraySizeException:
14809    .word   .LstrNegativeArraySizeException
14810strNoSuchMethodError:
14811    .word   .LstrNoSuchMethodError
14812strNullPointerException:
14813    .word   .LstrNullPointerException
14814
14815strLogTag:
14816    .word   .LstrLogTag
14817strExceptionNotCaughtLocally:
14818    .word   .LstrExceptionNotCaughtLocally
14819
14820strNewline:
14821    .word   .LstrNewline
14822strSqueak:
14823    .word   .LstrSqueak
14824strPrintHex:
14825    .word   .LstrPrintHex
14826strPrintLong:
14827    .word   .LstrPrintLong
14828
14829/*
14830 * Zero-terminated ASCII string data.
14831 *
14832 * On ARM we have two choices: do like gcc does, and LDR from a .word
14833 * with the address, or use an ADR pseudo-op to get the address
14834 * directly.  ADR saves 4 bytes and an indirection, but it's using a
14835 * PC-relative addressing mode and hence has a limited range, which
14836 * makes it not work well with mergeable string sections.
14837 */
14838    .section .rodata.str1.4,"aMS",%progbits,1
14839
14840.LstrBadEntryPoint:
14841    .asciz  "Bad entry point %d\n"
14842.LstrArithmeticException:
14843    .asciz  "Ljava/lang/ArithmeticException;"
14844.LstrDivideByZero:
14845    .asciz  "divide by zero"
14846.LstrFilledNewArrayNotImpl:
14847    .asciz  "filled-new-array only implemented for objects and 'int'"
14848.LstrInternalError:
14849    .asciz  "Ljava/lang/InternalError;"
14850.LstrInstantiationError:
14851    .asciz  "Ljava/lang/InstantiationError;"
14852.LstrNegativeArraySizeException:
14853    .asciz  "Ljava/lang/NegativeArraySizeException;"
14854.LstrNoSuchMethodError:
14855    .asciz  "Ljava/lang/NoSuchMethodError;"
14856.LstrNullPointerException:
14857    .asciz  "Ljava/lang/NullPointerException;"
14858
14859.LstrLogTag:
14860    .asciz  "mterp"
14861.LstrExceptionNotCaughtLocally:
14862    .asciz  "Exception %s from %s:%d not caught locally\n"
14863
14864.LstrNewline:
14865    .asciz  "\n"
14866.LstrSqueak:
14867    .asciz  "<%d>"
14868.LstrPrintHex:
14869    .asciz  "<0x%x>"
14870.LstrPrintLong:
14871    .asciz  "<%lld>"
14872
14873