InterpAsm-armv5te-vfp.S revision 6af2ddd107842c3737c04c37343cac9be17f4209
1/*
2 * This file was generated automatically by gen-mterp.py for 'armv5te-vfp'.
3 *
4 * --> DO NOT EDIT <--
5 */
6
7/* File: armv5te/header.S */
8/*
9 * Copyright (C) 2008 The Android Open Source Project
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 *      http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23
24/*
25 * ARMv5 definitions and declarations.
26 */
27
28/*
29ARM EABI general notes:
30
31r0-r3 hold first 4 args to a method; they are not preserved across method calls
32r4-r8 are available for general use
33r9 is given special treatment in some situations, but not for us
34r10 (sl) seems to be generally available
35r11 (fp) is used by gcc (unless -fomit-frame-pointer is set)
36r12 (ip) is scratch -- not preserved across method calls
37r13 (sp) should be managed carefully in case a signal arrives
38r14 (lr) must be preserved
39r15 (pc) can be tinkered with directly
40
41r0 holds returns of <= 4 bytes
42r0-r1 hold returns of 8 bytes, low word in r0
43
44Callee must save/restore r4+ (except r12) if it modifies them.  If VFP
45is present, registers s16-s31 (a/k/a d8-d15, a/k/a q4-q7) must be preserved,
46s0-s15 (d0-d7, q0-a3) do not need to be.
47
48Stack is "full descending".  Only the arguments that don't fit in the first 4
49registers are placed on the stack.  "sp" points at the first stacked argument
50(i.e. the 5th arg).
51
52VFP: single-precision results in s0, double-precision results in d0.
53
54In the EABI, "sp" must be 64-bit aligned on entry to a function, and any
5564-bit quantities (long long, double) must be 64-bit aligned.
56*/
57
58/*
59Mterp and ARM notes:
60
61The following registers have fixed assignments:
62
63  reg nick      purpose
64  r4  rPC       interpreted program counter, used for fetching instructions
65  r5  rFP       interpreted frame pointer, used for accessing locals and args
66  r6  rGLUE     MterpGlue pointer
67  r7  rINST     first 16-bit code unit of current instruction
68  r8  rIBASE    interpreted instruction base pointer, used for computed goto
69
70Macros are provided for common operations.  Each macro MUST emit only
71one instruction to make instruction-counting easier.  They MUST NOT alter
72unspecified registers or condition codes.
73*/
74
75/* single-purpose registers, given names for clarity */
76#define rPC     r4
77#define rFP     r5
78#define rGLUE   r6
79#define rINST   r7
80#define rIBASE  r8
81
82/* save/restore the PC and/or FP from the glue struct */
83#define LOAD_PC_FROM_GLUE()     ldr     rPC, [rGLUE, #offGlue_pc]
84#define SAVE_PC_TO_GLUE()       str     rPC, [rGLUE, #offGlue_pc]
85#define LOAD_FP_FROM_GLUE()     ldr     rFP, [rGLUE, #offGlue_fp]
86#define SAVE_FP_TO_GLUE()       str     rFP, [rGLUE, #offGlue_fp]
87#define LOAD_PC_FP_FROM_GLUE()  ldmia   rGLUE, {rPC, rFP}
88#define SAVE_PC_FP_TO_GLUE()    stmia   rGLUE, {rPC, rFP}
89
90/*
91 * "export" the PC to the stack frame, f/b/o future exception objects.  Must
92 * be done *before* something calls dvmThrowException.
93 *
94 * In C this is "SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc", i.e.
95 * fp - sizeof(StackSaveArea) + offsetof(SaveArea, xtra.currentPc)
96 *
97 * It's okay to do this more than once.
98 */
99#define EXPORT_PC() \
100    str     rPC, [rFP, #(-sizeofStackSaveArea + offStackSaveArea_currentPc)]
101
102/*
103 * Given a frame pointer, find the stack save area.
104 *
105 * In C this is "((StackSaveArea*)(_fp) -1)".
106 */
107#define SAVEAREA_FROM_FP(_reg, _fpreg) \
108    sub     _reg, _fpreg, #sizeofStackSaveArea
109
110/*
111 * Fetch the next instruction from rPC into rINST.  Does not advance rPC.
112 */
113#define FETCH_INST()            ldrh    rINST, [rPC]
114
115/*
116 * Fetch the next instruction from the specified offset.  Advances rPC
117 * to point to the next instruction.  "_count" is in 16-bit code units.
118 *
119 * Because of the limited size of immediate constants on ARM, this is only
120 * suitable for small forward movements (i.e. don't try to implement "goto"
121 * with this).
122 *
123 * This must come AFTER anything that can throw an exception, or the
124 * exception catch may miss.  (This also implies that it must come after
125 * EXPORT_PC().)
126 */
127#define FETCH_ADVANCE_INST(_count) ldrh    rINST, [rPC, #(_count*2)]!
128
129/*
130 * The operation performed here is similar to FETCH_ADVANCE_INST, except the
131 * src and dest registers are parameterized (not hard-wired to rPC and rINST).
132 */
133#define PREFETCH_ADVANCE_INST(_dreg, _sreg, _count) \
134        ldrh    _dreg, [_sreg, #(_count*2)]!
135
136/*
137 * Fetch the next instruction from an offset specified by _reg.  Updates
138 * rPC to point to the next instruction.  "_reg" must specify the distance
139 * in bytes, *not* 16-bit code units, and may be a signed value.
140 *
141 * We want to write "ldrh rINST, [rPC, _reg, lsl #2]!", but some of the
142 * bits that hold the shift distance are used for the half/byte/sign flags.
143 * In some cases we can pre-double _reg for free, so we require a byte offset
144 * here.
145 */
146#define FETCH_ADVANCE_INST_RB(_reg) ldrh    rINST, [rPC, _reg]!
147
148/*
149 * Fetch a half-word code unit from an offset past the current PC.  The
150 * "_count" value is in 16-bit code units.  Does not advance rPC.
151 *
152 * The "_S" variant works the same but treats the value as signed.
153 */
154#define FETCH(_reg, _count)     ldrh    _reg, [rPC, #(_count*2)]
155#define FETCH_S(_reg, _count)   ldrsh   _reg, [rPC, #(_count*2)]
156
157/*
158 * Fetch one byte from an offset past the current PC.  Pass in the same
159 * "_count" as you would for FETCH, and an additional 0/1 indicating which
160 * byte of the halfword you want (lo/hi).
161 */
162#define FETCH_B(_reg, _count, _byte) ldrb     _reg, [rPC, #(_count*2+_byte)]
163
164/*
165 * Put the instruction's opcode field into the specified register.
166 */
167#define GET_INST_OPCODE(_reg)   and     _reg, rINST, #255
168
169/*
170 * Put the prefetched instruction's opcode field into the specified register.
171 */
172#define GET_PREFETCHED_OPCODE(_oreg, _ireg)   and     _oreg, _ireg, #255
173
174/*
175 * Begin executing the opcode in _reg.  Because this only jumps within the
176 * interpreter, we don't have to worry about pre-ARMv5 THUMB interwork.
177 */
178#define GOTO_OPCODE(_reg)       add     pc, rIBASE, _reg, lsl #6
179#define GOTO_OPCODE_IFEQ(_reg)  addeq   pc, rIBASE, _reg, lsl #6
180#define GOTO_OPCODE_IFNE(_reg)  addne   pc, rIBASE, _reg, lsl #6
181
182/*
183 * Get/set the 32-bit value from a Dalvik register.
184 */
185#define GET_VREG(_reg, _vreg)   ldr     _reg, [rFP, _vreg, lsl #2]
186#define SET_VREG(_reg, _vreg)   str     _reg, [rFP, _vreg, lsl #2]
187
188#if defined(WITH_JIT)
189#define GET_JIT_PROF_TABLE(_reg)    ldr     _reg,[rGLUE,#offGlue_pJitProfTable]
190#define GET_JIT_THRESHOLD(_reg)     ldr     _reg,[rGLUE,#offGlue_jitThreshold]
191#endif
192
193/*
194 * Convert a virtual register index into an address.
195 */
196#define VREG_INDEX_TO_ADDR(_reg, _vreg) \
197        add     _reg, rFP, _vreg, lsl #2
198
199/*
200 * This is a #include, not a %include, because we want the C pre-processor
201 * to expand the macros into assembler assignment statements.
202 */
203#include "../common/asm-constants.h"
204
205#if defined(WITH_JIT)
206#include "../common/jit-config.h"
207#endif
208
209/* File: armv5te/platform.S */
210/*
211 * ===========================================================================
212 *  CPU-version-specific defines
213 * ===========================================================================
214 */
215
216/*
217 * Macro for data memory barrier; not meaningful pre-ARMv6K.
218 */
219.macro  SMP_DMB
220.endm
221
222/*
223 * Macro for data memory barrier; not meaningful pre-ARMv6K.
224 */
225.macro  SMP_DMB_ST
226.endm
227
228/* File: armv5te/entry.S */
229/*
230 * Copyright (C) 2008 The Android Open Source Project
231 *
232 * Licensed under the Apache License, Version 2.0 (the "License");
233 * you may not use this file except in compliance with the License.
234 * You may obtain a copy of the License at
235 *
236 *      http://www.apache.org/licenses/LICENSE-2.0
237 *
238 * Unless required by applicable law or agreed to in writing, software
239 * distributed under the License is distributed on an "AS IS" BASIS,
240 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
241 * See the License for the specific language governing permissions and
242 * limitations under the License.
243 */
244/*
245 * Interpreter entry point.
246 */
247
248/*
249 * We don't have formal stack frames, so gdb scans upward in the code
250 * to find the start of the function (a label with the %function type),
251 * and then looks at the next few instructions to figure out what
252 * got pushed onto the stack.  From this it figures out how to restore
253 * the registers, including PC, for the previous stack frame.  If gdb
254 * sees a non-function label, it stops scanning, so either we need to
255 * have nothing but assembler-local labels between the entry point and
256 * the break, or we need to fake it out.
257 *
258 * When this is defined, we add some stuff to make gdb less confused.
259 */
260#define ASSIST_DEBUGGER 1
261
262    .text
263    .align  2
264    .global dvmMterpStdRun
265    .type   dvmMterpStdRun, %function
266
267/*
268 * On entry:
269 *  r0  MterpGlue* glue
270 *
271 * This function returns a boolean "changeInterp" value.  The return comes
272 * via a call to dvmMterpStdBail().
273 */
274dvmMterpStdRun:
275#define MTERP_ENTRY1 \
276    .save {r4-r10,fp,lr}; \
277    stmfd   sp!, {r4-r10,fp,lr}         @ save 9 regs
278#define MTERP_ENTRY2 \
279    .pad    #4; \
280    sub     sp, sp, #4                  @ align 64
281
282    .fnstart
283    MTERP_ENTRY1
284    MTERP_ENTRY2
285
286    /* save stack pointer, add magic word for debuggerd */
287    str     sp, [r0, #offGlue_bailPtr]  @ save SP for eventual return
288
289    /* set up "named" registers, figure out entry point */
290    mov     rGLUE, r0                   @ set rGLUE
291    ldr     r1, [r0, #offGlue_entryPoint]   @ enum is 4 bytes in aapcs-EABI
292    LOAD_PC_FP_FROM_GLUE()              @ load rPC and rFP from "glue"
293    adr     rIBASE, dvmAsmInstructionStart  @ set rIBASE
294    cmp     r1, #kInterpEntryInstr      @ usual case?
295    bne     .Lnot_instr                 @ no, handle it
296
297#if defined(WITH_JIT)
298.LentryInstr:
299    ldr     r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
300    /* Entry is always a possible trace start */
301    GET_JIT_PROF_TABLE(r0)
302    FETCH_INST()
303    mov     r1, #0                      @ prepare the value for the new state
304    str     r1, [r10, #offThread_inJitCodeCache] @ back to the interp land
305    cmp     r0,#0                       @ is profiling disabled?
306#if !defined(WITH_SELF_VERIFICATION)
307    bne     common_updateProfile        @ profiling is enabled
308#else
309    ldr     r2, [r10, #offThread_shadowSpace]   @ to find out the jit exit state
310    beq     1f                          @ profiling is disabled
311    ldr     r3, [r2, #offShadowSpace_jitExitState]  @ jit exit state
312    cmp     r3, #kSVSTraceSelect        @ hot trace following?
313    moveq   r2,#kJitTSelectRequestHot   @ ask for trace selection
314    beq     common_selectTrace          @ go build the trace
315    cmp     r3, #kSVSNoProfile          @ don't profile the next instruction?
316    beq     1f                          @ intrepret the next instruction
317    b       common_updateProfile        @ collect profiles
318#endif
3191:
320    GET_INST_OPCODE(ip)
321    GOTO_OPCODE(ip)
322#else
323    /* start executing the instruction at rPC */
324    FETCH_INST()                        @ load rINST from rPC
325    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
326    GOTO_OPCODE(ip)                     @ jump to next instruction
327#endif
328
329.Lnot_instr:
330    cmp     r1, #kInterpEntryReturn     @ were we returning from a method?
331    beq     common_returnFromMethod
332
333.Lnot_return:
334    cmp     r1, #kInterpEntryThrow      @ were we throwing an exception?
335    beq     common_exceptionThrown
336
337#if defined(WITH_JIT)
338.Lnot_throw:
339    ldr     r10,[rGLUE, #offGlue_jitResumeNPC]
340    ldr     r2,[rGLUE, #offGlue_jitResumeDPC]
341    cmp     r1, #kInterpEntryResume     @ resuming after Jit single-step?
342    bne     .Lbad_arg
343    cmp     rPC,r2
344    bne     .LentryInstr                @ must have branched, don't resume
345#if defined(WITH_SELF_VERIFICATION)
346    @ glue->entryPoint will be set in dvmSelfVerificationSaveState
347    b       jitSVShadowRunStart         @ re-enter the translation after the
348                                        @ single-stepped instruction
349    @noreturn
350#endif
351    mov     r1, #kInterpEntryInstr
352    str     r1, [rGLUE, #offGlue_entryPoint]
353    bx      r10                         @ re-enter the translation
354#endif
355
356.Lbad_arg:
357    ldr     r0, strBadEntryPoint
358    @ r1 holds value of entryPoint
359    bl      printf
360    bl      dvmAbort
361    .fnend
362    .size   dvmMterpStdRun, .-dvmMterpStdRun
363
364
365    .global dvmMterpStdBail
366    .type   dvmMterpStdBail, %function
367
368/*
369 * Restore the stack pointer and PC from the save point established on entry.
370 * This is essentially the same as a longjmp, but should be cheaper.  The
371 * last instruction causes us to return to whoever called dvmMterpStdRun.
372 *
373 * We pushed some registers on the stack in dvmMterpStdRun, then saved
374 * SP and LR.  Here we restore SP, restore the registers, and then restore
375 * LR to PC.
376 *
377 * On entry:
378 *  r0  MterpGlue* glue
379 *  r1  bool changeInterp
380 */
381dvmMterpStdBail:
382    ldr     sp, [r0, #offGlue_bailPtr]      @ sp<- saved SP
383    mov     r0, r1                          @ return the changeInterp value
384    add     sp, sp, #4                      @ un-align 64
385    ldmfd   sp!, {r4-r10,fp,pc}             @ restore 9 regs and return
386
387
388/*
389 * String references.
390 */
391strBadEntryPoint:
392    .word   .LstrBadEntryPoint
393
394
395    .global dvmAsmInstructionStart
396    .type   dvmAsmInstructionStart, %function
397dvmAsmInstructionStart = .L_OP_NOP
398    .text
399
400/* ------------------------------ */
401    .balign 64
402.L_OP_NOP: /* 0x00 */
403/* File: armv5te/OP_NOP.S */
404    FETCH_ADVANCE_INST(1)               @ advance to next instr, load rINST
405    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
406    GOTO_OPCODE(ip)                     @ execute it
407
408#ifdef ASSIST_DEBUGGER
409    /* insert fake function header to help gdb find the stack frame */
410    .type   dalvik_inst, %function
411dalvik_inst:
412    .fnstart
413    MTERP_ENTRY1
414    MTERP_ENTRY2
415    .fnend
416#endif
417
418/* ------------------------------ */
419    .balign 64
420.L_OP_MOVE: /* 0x01 */
421/* File: armv5te/OP_MOVE.S */
422    /* for move, move-object, long-to-int */
423    /* op vA, vB */
424    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
425    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
426    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
427    GET_VREG(r2, r1)                    @ r2<- fp[B]
428    and     r0, r0, #15
429    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
430    SET_VREG(r2, r0)                    @ fp[A]<- r2
431    GOTO_OPCODE(ip)                     @ execute next instruction
432
433/* ------------------------------ */
434    .balign 64
435.L_OP_MOVE_FROM16: /* 0x02 */
436/* File: armv5te/OP_MOVE_FROM16.S */
437    /* for: move/from16, move-object/from16 */
438    /* op vAA, vBBBB */
439    FETCH(r1, 1)                        @ r1<- BBBB
440    mov     r0, rINST, lsr #8           @ r0<- AA
441    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
442    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
443    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
444    SET_VREG(r2, r0)                    @ fp[AA]<- r2
445    GOTO_OPCODE(ip)                     @ jump to next instruction
446
447/* ------------------------------ */
448    .balign 64
449.L_OP_MOVE_16: /* 0x03 */
450/* File: armv5te/OP_MOVE_16.S */
451    /* for: move/16, move-object/16 */
452    /* op vAAAA, vBBBB */
453    FETCH(r1, 2)                        @ r1<- BBBB
454    FETCH(r0, 1)                        @ r0<- AAAA
455    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
456    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
457    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
458    SET_VREG(r2, r0)                    @ fp[AAAA]<- r2
459    GOTO_OPCODE(ip)                     @ jump to next instruction
460
461/* ------------------------------ */
462    .balign 64
463.L_OP_MOVE_WIDE: /* 0x04 */
464/* File: armv5te/OP_MOVE_WIDE.S */
465    /* move-wide vA, vB */
466    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
467    mov     r2, rINST, lsr #8           @ r2<- A(+)
468    mov     r3, rINST, lsr #12          @ r3<- B
469    and     r2, r2, #15
470    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
471    add     r2, rFP, r2, lsl #2         @ r2<- &fp[A]
472    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[B]
473    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
474    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
475    stmia   r2, {r0-r1}                 @ fp[A]<- r0/r1
476    GOTO_OPCODE(ip)                     @ jump to next instruction
477
478/* ------------------------------ */
479    .balign 64
480.L_OP_MOVE_WIDE_FROM16: /* 0x05 */
481/* File: armv5te/OP_MOVE_WIDE_FROM16.S */
482    /* move-wide/from16 vAA, vBBBB */
483    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
484    FETCH(r3, 1)                        @ r3<- BBBB
485    mov     r2, rINST, lsr #8           @ r2<- AA
486    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BBBB]
487    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
488    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[BBBB]
489    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
490    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
491    stmia   r2, {r0-r1}                 @ fp[AA]<- r0/r1
492    GOTO_OPCODE(ip)                     @ jump to next instruction
493
494/* ------------------------------ */
495    .balign 64
496.L_OP_MOVE_WIDE_16: /* 0x06 */
497/* File: armv5te/OP_MOVE_WIDE_16.S */
498    /* move-wide/16 vAAAA, vBBBB */
499    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
500    FETCH(r3, 2)                        @ r3<- BBBB
501    FETCH(r2, 1)                        @ r2<- AAAA
502    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BBBB]
503    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AAAA]
504    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[BBBB]
505    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
506    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
507    stmia   r2, {r0-r1}                 @ fp[AAAA]<- r0/r1
508    GOTO_OPCODE(ip)                     @ jump to next instruction
509
510/* ------------------------------ */
511    .balign 64
512.L_OP_MOVE_OBJECT: /* 0x07 */
513/* File: armv5te/OP_MOVE_OBJECT.S */
514/* File: armv5te/OP_MOVE.S */
515    /* for move, move-object, long-to-int */
516    /* op vA, vB */
517    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
518    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
519    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
520    GET_VREG(r2, r1)                    @ r2<- fp[B]
521    and     r0, r0, #15
522    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
523    SET_VREG(r2, r0)                    @ fp[A]<- r2
524    GOTO_OPCODE(ip)                     @ execute next instruction
525
526
527/* ------------------------------ */
528    .balign 64
529.L_OP_MOVE_OBJECT_FROM16: /* 0x08 */
530/* File: armv5te/OP_MOVE_OBJECT_FROM16.S */
531/* File: armv5te/OP_MOVE_FROM16.S */
532    /* for: move/from16, move-object/from16 */
533    /* op vAA, vBBBB */
534    FETCH(r1, 1)                        @ r1<- BBBB
535    mov     r0, rINST, lsr #8           @ r0<- AA
536    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
537    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
538    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
539    SET_VREG(r2, r0)                    @ fp[AA]<- r2
540    GOTO_OPCODE(ip)                     @ jump to next instruction
541
542
543/* ------------------------------ */
544    .balign 64
545.L_OP_MOVE_OBJECT_16: /* 0x09 */
546/* File: armv5te/OP_MOVE_OBJECT_16.S */
547/* File: armv5te/OP_MOVE_16.S */
548    /* for: move/16, move-object/16 */
549    /* op vAAAA, vBBBB */
550    FETCH(r1, 2)                        @ r1<- BBBB
551    FETCH(r0, 1)                        @ r0<- AAAA
552    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
553    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
554    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
555    SET_VREG(r2, r0)                    @ fp[AAAA]<- r2
556    GOTO_OPCODE(ip)                     @ jump to next instruction
557
558
559/* ------------------------------ */
560    .balign 64
561.L_OP_MOVE_RESULT: /* 0x0a */
562/* File: armv5te/OP_MOVE_RESULT.S */
563    /* for: move-result, move-result-object */
564    /* op vAA */
565    mov     r2, rINST, lsr #8           @ r2<- AA
566    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
567    ldr     r0, [rGLUE, #offGlue_retval]    @ r0<- glue->retval.i
568    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
569    SET_VREG(r0, r2)                    @ fp[AA]<- r0
570    GOTO_OPCODE(ip)                     @ jump to next instruction
571
572/* ------------------------------ */
573    .balign 64
574.L_OP_MOVE_RESULT_WIDE: /* 0x0b */
575/* File: armv5te/OP_MOVE_RESULT_WIDE.S */
576    /* move-result-wide vAA */
577    mov     r2, rINST, lsr #8           @ r2<- AA
578    add     r3, rGLUE, #offGlue_retval  @ r3<- &glue->retval
579    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
580    ldmia   r3, {r0-r1}                 @ r0/r1<- retval.j
581    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
582    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
583    stmia   r2, {r0-r1}                 @ fp[AA]<- r0/r1
584    GOTO_OPCODE(ip)                     @ jump to next instruction
585
586/* ------------------------------ */
587    .balign 64
588.L_OP_MOVE_RESULT_OBJECT: /* 0x0c */
589/* File: armv5te/OP_MOVE_RESULT_OBJECT.S */
590/* File: armv5te/OP_MOVE_RESULT.S */
591    /* for: move-result, move-result-object */
592    /* op vAA */
593    mov     r2, rINST, lsr #8           @ r2<- AA
594    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
595    ldr     r0, [rGLUE, #offGlue_retval]    @ r0<- glue->retval.i
596    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
597    SET_VREG(r0, r2)                    @ fp[AA]<- r0
598    GOTO_OPCODE(ip)                     @ jump to next instruction
599
600
601/* ------------------------------ */
602    .balign 64
603.L_OP_MOVE_EXCEPTION: /* 0x0d */
604/* File: armv5te/OP_MOVE_EXCEPTION.S */
605    /* move-exception vAA */
606    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
607    mov     r2, rINST, lsr #8           @ r2<- AA
608    ldr     r3, [r0, #offThread_exception]  @ r3<- dvmGetException bypass
609    mov     r1, #0                      @ r1<- 0
610    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
611    SET_VREG(r3, r2)                    @ fp[AA]<- exception obj
612    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
613    str     r1, [r0, #offThread_exception]  @ dvmClearException bypass
614    GOTO_OPCODE(ip)                     @ jump to next instruction
615
616/* ------------------------------ */
617    .balign 64
618.L_OP_RETURN_VOID: /* 0x0e */
619/* File: armv5te/OP_RETURN_VOID.S */
620    b       common_returnFromMethod
621
622/* ------------------------------ */
623    .balign 64
624.L_OP_RETURN: /* 0x0f */
625/* File: armv5te/OP_RETURN.S */
626    /*
627     * Return a 32-bit value.  Copies the return value into the "glue"
628     * structure, then jumps to the return handler.
629     *
630     * for: return, return-object
631     */
632    /* op vAA */
633    mov     r2, rINST, lsr #8           @ r2<- AA
634    GET_VREG(r0, r2)                    @ r0<- vAA
635    str     r0, [rGLUE, #offGlue_retval] @ retval.i <- vAA
636    b       common_returnFromMethod
637
638/* ------------------------------ */
639    .balign 64
640.L_OP_RETURN_WIDE: /* 0x10 */
641/* File: armv5te/OP_RETURN_WIDE.S */
642    /*
643     * Return a 64-bit value.  Copies the return value into the "glue"
644     * structure, then jumps to the return handler.
645     */
646    /* return-wide vAA */
647    mov     r2, rINST, lsr #8           @ r2<- AA
648    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
649    add     r3, rGLUE, #offGlue_retval  @ r3<- &glue->retval
650    ldmia   r2, {r0-r1}                 @ r0/r1 <- vAA/vAA+1
651    stmia   r3, {r0-r1}                 @ retval<- r0/r1
652    b       common_returnFromMethod
653
654/* ------------------------------ */
655    .balign 64
656.L_OP_RETURN_OBJECT: /* 0x11 */
657/* File: armv5te/OP_RETURN_OBJECT.S */
658/* File: armv5te/OP_RETURN.S */
659    /*
660     * Return a 32-bit value.  Copies the return value into the "glue"
661     * structure, then jumps to the return handler.
662     *
663     * for: return, return-object
664     */
665    /* op vAA */
666    mov     r2, rINST, lsr #8           @ r2<- AA
667    GET_VREG(r0, r2)                    @ r0<- vAA
668    str     r0, [rGLUE, #offGlue_retval] @ retval.i <- vAA
669    b       common_returnFromMethod
670
671
672/* ------------------------------ */
673    .balign 64
674.L_OP_CONST_4: /* 0x12 */
675/* File: armv5te/OP_CONST_4.S */
676    /* const/4 vA, #+B */
677    mov     r1, rINST, lsl #16          @ r1<- Bxxx0000
678    mov     r0, rINST, lsr #8           @ r0<- A+
679    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
680    mov     r1, r1, asr #28             @ r1<- sssssssB (sign-extended)
681    and     r0, r0, #15
682    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
683    SET_VREG(r1, r0)                    @ fp[A]<- r1
684    GOTO_OPCODE(ip)                     @ execute next instruction
685
686/* ------------------------------ */
687    .balign 64
688.L_OP_CONST_16: /* 0x13 */
689/* File: armv5te/OP_CONST_16.S */
690    /* const/16 vAA, #+BBBB */
691    FETCH_S(r0, 1)                      @ r0<- ssssBBBB (sign-extended)
692    mov     r3, rINST, lsr #8           @ r3<- AA
693    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
694    SET_VREG(r0, r3)                    @ vAA<- r0
695    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
696    GOTO_OPCODE(ip)                     @ jump to next instruction
697
698/* ------------------------------ */
699    .balign 64
700.L_OP_CONST: /* 0x14 */
701/* File: armv5te/OP_CONST.S */
702    /* const vAA, #+BBBBbbbb */
703    mov     r3, rINST, lsr #8           @ r3<- AA
704    FETCH(r0, 1)                        @ r0<- bbbb (low)
705    FETCH(r1, 2)                        @ r1<- BBBB (high)
706    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
707    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
708    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
709    SET_VREG(r0, r3)                    @ vAA<- r0
710    GOTO_OPCODE(ip)                     @ jump to next instruction
711
712/* ------------------------------ */
713    .balign 64
714.L_OP_CONST_HIGH16: /* 0x15 */
715/* File: armv5te/OP_CONST_HIGH16.S */
716    /* const/high16 vAA, #+BBBB0000 */
717    FETCH(r0, 1)                        @ r0<- 0000BBBB (zero-extended)
718    mov     r3, rINST, lsr #8           @ r3<- AA
719    mov     r0, r0, lsl #16             @ r0<- BBBB0000
720    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
721    SET_VREG(r0, r3)                    @ vAA<- r0
722    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
723    GOTO_OPCODE(ip)                     @ jump to next instruction
724
725/* ------------------------------ */
726    .balign 64
727.L_OP_CONST_WIDE_16: /* 0x16 */
728/* File: armv5te/OP_CONST_WIDE_16.S */
729    /* const-wide/16 vAA, #+BBBB */
730    FETCH_S(r0, 1)                      @ r0<- ssssBBBB (sign-extended)
731    mov     r3, rINST, lsr #8           @ r3<- AA
732    mov     r1, r0, asr #31             @ r1<- ssssssss
733    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
734    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
735    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
736    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
737    GOTO_OPCODE(ip)                     @ jump to next instruction
738
739/* ------------------------------ */
740    .balign 64
741.L_OP_CONST_WIDE_32: /* 0x17 */
742/* File: armv5te/OP_CONST_WIDE_32.S */
743    /* const-wide/32 vAA, #+BBBBbbbb */
744    FETCH(r0, 1)                        @ r0<- 0000bbbb (low)
745    mov     r3, rINST, lsr #8           @ r3<- AA
746    FETCH_S(r2, 2)                      @ r2<- ssssBBBB (high)
747    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
748    orr     r0, r0, r2, lsl #16         @ r0<- BBBBbbbb
749    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
750    mov     r1, r0, asr #31             @ r1<- ssssssss
751    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
752    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
753    GOTO_OPCODE(ip)                     @ jump to next instruction
754
755/* ------------------------------ */
756    .balign 64
757.L_OP_CONST_WIDE: /* 0x18 */
758/* File: armv5te/OP_CONST_WIDE.S */
759    /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
760    FETCH(r0, 1)                        @ r0<- bbbb (low)
761    FETCH(r1, 2)                        @ r1<- BBBB (low middle)
762    FETCH(r2, 3)                        @ r2<- hhhh (high middle)
763    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb (low word)
764    FETCH(r3, 4)                        @ r3<- HHHH (high)
765    mov     r9, rINST, lsr #8           @ r9<- AA
766    orr     r1, r2, r3, lsl #16         @ r1<- HHHHhhhh (high word)
767    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
768    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
769    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
770    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
771    GOTO_OPCODE(ip)                     @ jump to next instruction
772
773/* ------------------------------ */
774    .balign 64
775.L_OP_CONST_WIDE_HIGH16: /* 0x19 */
776/* File: armv5te/OP_CONST_WIDE_HIGH16.S */
777    /* const-wide/high16 vAA, #+BBBB000000000000 */
778    FETCH(r1, 1)                        @ r1<- 0000BBBB (zero-extended)
779    mov     r3, rINST, lsr #8           @ r3<- AA
780    mov     r0, #0                      @ r0<- 00000000
781    mov     r1, r1, lsl #16             @ r1<- BBBB0000
782    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
783    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
784    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
785    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
786    GOTO_OPCODE(ip)                     @ jump to next instruction
787
788/* ------------------------------ */
789    .balign 64
790.L_OP_CONST_STRING: /* 0x1a */
791/* File: armv5te/OP_CONST_STRING.S */
792    /* const/string vAA, String@BBBB */
793    FETCH(r1, 1)                        @ r1<- BBBB
794    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- glue->methodClassDex
795    mov     r9, rINST, lsr #8           @ r9<- AA
796    ldr     r2, [r2, #offDvmDex_pResStrings]   @ r2<- dvmDex->pResStrings
797    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResStrings[BBBB]
798    cmp     r0, #0                      @ not yet resolved?
799    beq     .LOP_CONST_STRING_resolve
800    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
801    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
802    SET_VREG(r0, r9)                    @ vAA<- r0
803    GOTO_OPCODE(ip)                     @ jump to next instruction
804
805/* ------------------------------ */
806    .balign 64
807.L_OP_CONST_STRING_JUMBO: /* 0x1b */
808/* File: armv5te/OP_CONST_STRING_JUMBO.S */
809    /* const/string vAA, String@BBBBBBBB */
810    FETCH(r0, 1)                        @ r0<- bbbb (low)
811    FETCH(r1, 2)                        @ r1<- BBBB (high)
812    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- glue->methodClassDex
813    mov     r9, rINST, lsr #8           @ r9<- AA
814    ldr     r2, [r2, #offDvmDex_pResStrings]   @ r2<- dvmDex->pResStrings
815    orr     r1, r0, r1, lsl #16         @ r1<- BBBBbbbb
816    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResStrings[BBBB]
817    cmp     r0, #0
818    beq     .LOP_CONST_STRING_JUMBO_resolve
819    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
820    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
821    SET_VREG(r0, r9)                    @ vAA<- r0
822    GOTO_OPCODE(ip)                     @ jump to next instruction
823
824/* ------------------------------ */
825    .balign 64
826.L_OP_CONST_CLASS: /* 0x1c */
827/* File: armv5te/OP_CONST_CLASS.S */
828    /* const/class vAA, Class@BBBB */
829    FETCH(r1, 1)                        @ r1<- BBBB
830    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- glue->methodClassDex
831    mov     r9, rINST, lsr #8           @ r9<- AA
832    ldr     r2, [r2, #offDvmDex_pResClasses]   @ r2<- dvmDex->pResClasses
833    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResClasses[BBBB]
834    cmp     r0, #0                      @ not yet resolved?
835    beq     .LOP_CONST_CLASS_resolve
836    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
837    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
838    SET_VREG(r0, r9)                    @ vAA<- r0
839    GOTO_OPCODE(ip)                     @ jump to next instruction
840
841/* ------------------------------ */
842    .balign 64
843.L_OP_MONITOR_ENTER: /* 0x1d */
844/* File: armv5te/OP_MONITOR_ENTER.S */
845    /*
846     * Synchronize on an object.
847     */
848    /* monitor-enter vAA */
849    mov     r2, rINST, lsr #8           @ r2<- AA
850    GET_VREG(r1, r2)                    @ r1<- vAA (object)
851    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
852    cmp     r1, #0                      @ null object?
853    EXPORT_PC()                         @ need for precise GC
854    beq     common_errNullObject        @ null object, throw an exception
855    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
856    bl      dvmLockObject               @ call(self, obj)
857    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
858    GOTO_OPCODE(ip)                     @ jump to next instruction
859
860/* ------------------------------ */
861    .balign 64
862.L_OP_MONITOR_EXIT: /* 0x1e */
863/* File: armv5te/OP_MONITOR_EXIT.S */
864    /*
865     * Unlock an object.
866     *
867     * Exceptions that occur when unlocking a monitor need to appear as
868     * if they happened at the following instruction.  See the Dalvik
869     * instruction spec.
870     */
871    /* monitor-exit vAA */
872    mov     r2, rINST, lsr #8           @ r2<- AA
873    EXPORT_PC()                         @ before fetch: export the PC
874    GET_VREG(r1, r2)                    @ r1<- vAA (object)
875    cmp     r1, #0                      @ null object?
876    beq     1f                          @ yes
877    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
878    bl      dvmUnlockObject             @ r0<- success for unlock(self, obj)
879    cmp     r0, #0                      @ failed?
880    FETCH_ADVANCE_INST(1)               @ before throw: advance rPC, load rINST
881    beq     common_exceptionThrown      @ yes, exception is pending
882    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
883    GOTO_OPCODE(ip)                     @ jump to next instruction
8841:
885    FETCH_ADVANCE_INST(1)               @ advance before throw
886    b      common_errNullObject
887
888/* ------------------------------ */
889    .balign 64
890.L_OP_CHECK_CAST: /* 0x1f */
891/* File: armv5te/OP_CHECK_CAST.S */
892    /*
893     * Check to see if a cast from one class to another is allowed.
894     */
895    /* check-cast vAA, class@BBBB */
896    mov     r3, rINST, lsr #8           @ r3<- AA
897    FETCH(r2, 1)                        @ r2<- BBBB
898    GET_VREG(r9, r3)                    @ r9<- object
899    ldr     r0, [rGLUE, #offGlue_methodClassDex]    @ r0<- pDvmDex
900    cmp     r9, #0                      @ is object null?
901    ldr     r0, [r0, #offDvmDex_pResClasses]    @ r0<- pDvmDex->pResClasses
902    beq     .LOP_CHECK_CAST_okay            @ null obj, cast always succeeds
903    ldr     r1, [r0, r2, lsl #2]        @ r1<- resolved class
904    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
905    cmp     r1, #0                      @ have we resolved this before?
906    beq     .LOP_CHECK_CAST_resolve         @ not resolved, do it now
907.LOP_CHECK_CAST_resolved:
908    cmp     r0, r1                      @ same class (trivial success)?
909    bne     .LOP_CHECK_CAST_fullcheck       @ no, do full check
910.LOP_CHECK_CAST_okay:
911    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
912    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
913    GOTO_OPCODE(ip)                     @ jump to next instruction
914
915/* ------------------------------ */
916    .balign 64
917.L_OP_INSTANCE_OF: /* 0x20 */
918/* File: armv5te/OP_INSTANCE_OF.S */
919    /*
920     * Check to see if an object reference is an instance of a class.
921     *
922     * Most common situation is a non-null object, being compared against
923     * an already-resolved class.
924     */
925    /* instance-of vA, vB, class@CCCC */
926    mov     r3, rINST, lsr #12          @ r3<- B
927    mov     r9, rINST, lsr #8           @ r9<- A+
928    GET_VREG(r0, r3)                    @ r0<- vB (object)
929    and     r9, r9, #15                 @ r9<- A
930    cmp     r0, #0                      @ is object null?
931    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- pDvmDex
932    beq     .LOP_INSTANCE_OF_store           @ null obj, not an instance, store r0
933    FETCH(r3, 1)                        @ r3<- CCCC
934    ldr     r2, [r2, #offDvmDex_pResClasses]    @ r2<- pDvmDex->pResClasses
935    ldr     r1, [r2, r3, lsl #2]        @ r1<- resolved class
936    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
937    cmp     r1, #0                      @ have we resolved this before?
938    beq     .LOP_INSTANCE_OF_resolve         @ not resolved, do it now
939.LOP_INSTANCE_OF_resolved: @ r0=obj->clazz, r1=resolved class
940    cmp     r0, r1                      @ same class (trivial success)?
941    beq     .LOP_INSTANCE_OF_trivial         @ yes, trivial finish
942    b       .LOP_INSTANCE_OF_fullcheck       @ no, do full check
943
944/* ------------------------------ */
945    .balign 64
946.L_OP_ARRAY_LENGTH: /* 0x21 */
947/* File: armv5te/OP_ARRAY_LENGTH.S */
948    /*
949     * Return the length of an array.
950     */
951    mov     r1, rINST, lsr #12          @ r1<- B
952    mov     r2, rINST, lsr #8           @ r2<- A+
953    GET_VREG(r0, r1)                    @ r0<- vB (object ref)
954    and     r2, r2, #15                 @ r2<- A
955    cmp     r0, #0                      @ is object null?
956    beq     common_errNullObject        @ yup, fail
957    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
958    ldr     r3, [r0, #offArrayObject_length]    @ r3<- array length
959    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
960    SET_VREG(r3, r2)                    @ vB<- length
961    GOTO_OPCODE(ip)                     @ jump to next instruction
962
963/* ------------------------------ */
964    .balign 64
965.L_OP_NEW_INSTANCE: /* 0x22 */
966/* File: armv5te/OP_NEW_INSTANCE.S */
967    /*
968     * Create a new instance of a class.
969     */
970    /* new-instance vAA, class@BBBB */
971    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
972    FETCH(r1, 1)                        @ r1<- BBBB
973    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
974    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
975    EXPORT_PC()                         @ req'd for init, resolve, alloc
976    cmp     r0, #0                      @ already resolved?
977    beq     .LOP_NEW_INSTANCE_resolve         @ no, resolve it now
978.LOP_NEW_INSTANCE_resolved:   @ r0=class
979    ldrb    r1, [r0, #offClassObject_status]    @ r1<- ClassStatus enum
980    cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
981    bne     .LOP_NEW_INSTANCE_needinit        @ no, init class now
982.LOP_NEW_INSTANCE_initialized: @ r0=class
983    mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
984    bl      dvmAllocObject              @ r0<- new object
985    b       .LOP_NEW_INSTANCE_finish          @ continue
986
987/* ------------------------------ */
988    .balign 64
989.L_OP_NEW_ARRAY: /* 0x23 */
990/* File: armv5te/OP_NEW_ARRAY.S */
991    /*
992     * Allocate an array of objects, specified with the array class
993     * and a count.
994     *
995     * The verifier guarantees that this is an array class, so we don't
996     * check for it here.
997     */
998    /* new-array vA, vB, class@CCCC */
999    mov     r0, rINST, lsr #12          @ r0<- B
1000    FETCH(r2, 1)                        @ r2<- CCCC
1001    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
1002    GET_VREG(r1, r0)                    @ r1<- vB (array length)
1003    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1004    cmp     r1, #0                      @ check length
1005    ldr     r0, [r3, r2, lsl #2]        @ r0<- resolved class
1006    bmi     common_errNegativeArraySize @ negative length, bail
1007    cmp     r0, #0                      @ already resolved?
1008    EXPORT_PC()                         @ req'd for resolve, alloc
1009    bne     .LOP_NEW_ARRAY_finish          @ resolved, continue
1010    b       .LOP_NEW_ARRAY_resolve         @ do resolve now
1011
1012/* ------------------------------ */
1013    .balign 64
1014.L_OP_FILLED_NEW_ARRAY: /* 0x24 */
1015/* File: armv5te/OP_FILLED_NEW_ARRAY.S */
1016    /*
1017     * Create a new array with elements filled from registers.
1018     *
1019     * for: filled-new-array, filled-new-array/range
1020     */
1021    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1022    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1023    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
1024    FETCH(r1, 1)                        @ r1<- BBBB
1025    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1026    EXPORT_PC()                         @ need for resolve and alloc
1027    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
1028    mov     r10, rINST, lsr #8          @ r10<- AA or BA
1029    cmp     r0, #0                      @ already resolved?
1030    bne     .LOP_FILLED_NEW_ARRAY_continue        @ yes, continue on
10318:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
1032    mov     r2, #0                      @ r2<- false
1033    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
1034    bl      dvmResolveClass             @ r0<- call(clazz, ref)
1035    cmp     r0, #0                      @ got null?
1036    beq     common_exceptionThrown      @ yes, handle exception
1037    b       .LOP_FILLED_NEW_ARRAY_continue
1038
1039/* ------------------------------ */
1040    .balign 64
1041.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
1042/* File: armv5te/OP_FILLED_NEW_ARRAY_RANGE.S */
1043/* File: armv5te/OP_FILLED_NEW_ARRAY.S */
1044    /*
1045     * Create a new array with elements filled from registers.
1046     *
1047     * for: filled-new-array, filled-new-array/range
1048     */
1049    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1050    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1051    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
1052    FETCH(r1, 1)                        @ r1<- BBBB
1053    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1054    EXPORT_PC()                         @ need for resolve and alloc
1055    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
1056    mov     r10, rINST, lsr #8          @ r10<- AA or BA
1057    cmp     r0, #0                      @ already resolved?
1058    bne     .LOP_FILLED_NEW_ARRAY_RANGE_continue        @ yes, continue on
10598:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
1060    mov     r2, #0                      @ r2<- false
1061    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
1062    bl      dvmResolveClass             @ r0<- call(clazz, ref)
1063    cmp     r0, #0                      @ got null?
1064    beq     common_exceptionThrown      @ yes, handle exception
1065    b       .LOP_FILLED_NEW_ARRAY_RANGE_continue
1066
1067
1068/* ------------------------------ */
1069    .balign 64
1070.L_OP_FILL_ARRAY_DATA: /* 0x26 */
1071/* File: armv5te/OP_FILL_ARRAY_DATA.S */
1072    /* fill-array-data vAA, +BBBBBBBB */
1073    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1074    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1075    mov     r3, rINST, lsr #8           @ r3<- AA
1076    orr     r1, r0, r1, lsl #16         @ r1<- BBBBbbbb
1077    GET_VREG(r0, r3)                    @ r0<- vAA (array object)
1078    add     r1, rPC, r1, lsl #1         @ r1<- PC + BBBBbbbb*2 (array data off.)
1079    EXPORT_PC();
1080    bl      dvmInterpHandleFillArrayData@ fill the array with predefined data
1081    cmp     r0, #0                      @ 0 means an exception is thrown
1082    beq     common_exceptionThrown      @ has exception
1083    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
1084    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1085    GOTO_OPCODE(ip)                     @ jump to next instruction
1086
1087/* ------------------------------ */
1088    .balign 64
1089.L_OP_THROW: /* 0x27 */
1090/* File: armv5te/OP_THROW.S */
1091    /*
1092     * Throw an exception object in the current thread.
1093     */
1094    /* throw vAA */
1095    mov     r2, rINST, lsr #8           @ r2<- AA
1096    GET_VREG(r1, r2)                    @ r1<- vAA (exception object)
1097    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
1098    EXPORT_PC()                         @ exception handler can throw
1099    cmp     r1, #0                      @ null object?
1100    beq     common_errNullObject        @ yes, throw an NPE instead
1101    @ bypass dvmSetException, just store it
1102    str     r1, [r0, #offThread_exception]  @ thread->exception<- obj
1103    b       common_exceptionThrown
1104
1105/* ------------------------------ */
1106    .balign 64
1107.L_OP_GOTO: /* 0x28 */
1108/* File: armv5te/OP_GOTO.S */
1109    /*
1110     * Unconditional branch, 8-bit offset.
1111     *
1112     * The branch distance is a signed code-unit offset, which we need to
1113     * double to get a byte offset.
1114     */
1115    /* goto +AA */
1116    mov     r0, rINST, lsl #16          @ r0<- AAxx0000
1117    movs    r9, r0, asr #24             @ r9<- ssssssAA (sign-extended)
1118    mov     r9, r9, lsl #1              @ r9<- byte offset
1119    bmi     common_backwardBranch       @ backward branch, do periodic checks
1120#if defined(WITH_JIT)
1121    GET_JIT_PROF_TABLE(r0)
1122    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1123    cmp     r0,#0
1124    bne     common_updateProfile
1125    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1126    GOTO_OPCODE(ip)                     @ jump to next instruction
1127#else
1128    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1129    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1130    GOTO_OPCODE(ip)                     @ jump to next instruction
1131#endif
1132
1133/* ------------------------------ */
1134    .balign 64
1135.L_OP_GOTO_16: /* 0x29 */
1136/* File: armv5te/OP_GOTO_16.S */
1137    /*
1138     * Unconditional branch, 16-bit offset.
1139     *
1140     * The branch distance is a signed code-unit offset, which we need to
1141     * double to get a byte offset.
1142     */
1143    /* goto/16 +AAAA */
1144    FETCH_S(r0, 1)                      @ r0<- ssssAAAA (sign-extended)
1145    movs    r9, r0, asl #1              @ r9<- byte offset, check sign
1146    bmi     common_backwardBranch       @ backward branch, do periodic checks
1147#if defined(WITH_JIT)
1148    GET_JIT_PROF_TABLE(r0)
1149    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1150    cmp     r0,#0
1151    bne     common_updateProfile
1152    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1153    GOTO_OPCODE(ip)                     @ jump to next instruction
1154#else
1155    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1156    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1157    GOTO_OPCODE(ip)                     @ jump to next instruction
1158#endif
1159
1160/* ------------------------------ */
1161    .balign 64
1162.L_OP_GOTO_32: /* 0x2a */
1163/* File: armv5te/OP_GOTO_32.S */
1164    /*
1165     * Unconditional branch, 32-bit offset.
1166     *
1167     * The branch distance is a signed code-unit offset, which we need to
1168     * double to get a byte offset.
1169     *
1170     * Unlike most opcodes, this one is allowed to branch to itself, so
1171     * our "backward branch" test must be "<=0" instead of "<0".  The ORRS
1172     * instruction doesn't affect the V flag, so we need to clear it
1173     * explicitly.
1174     */
1175    /* goto/32 +AAAAAAAA */
1176    FETCH(r0, 1)                        @ r0<- aaaa (lo)
1177    FETCH(r1, 2)                        @ r1<- AAAA (hi)
1178    cmp     ip, ip                      @ (clear V flag during stall)
1179    orrs    r0, r0, r1, lsl #16         @ r0<- AAAAaaaa, check sign
1180    mov     r9, r0, asl #1              @ r9<- byte offset
1181    ble     common_backwardBranch       @ backward branch, do periodic checks
1182#if defined(WITH_JIT)
1183    GET_JIT_PROF_TABLE(r0)
1184    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1185    cmp     r0,#0
1186    bne     common_updateProfile
1187    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1188    GOTO_OPCODE(ip)                     @ jump to next instruction
1189#else
1190    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1191    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1192    GOTO_OPCODE(ip)                     @ jump to next instruction
1193#endif
1194
1195/* ------------------------------ */
1196    .balign 64
1197.L_OP_PACKED_SWITCH: /* 0x2b */
1198/* File: armv5te/OP_PACKED_SWITCH.S */
1199    /*
1200     * Handle a packed-switch or sparse-switch instruction.  In both cases
1201     * we decode it and hand it off to a helper function.
1202     *
1203     * We don't really expect backward branches in a switch statement, but
1204     * they're perfectly legal, so we check for them here.
1205     *
1206     * for: packed-switch, sparse-switch
1207     */
1208    /* op vAA, +BBBB */
1209    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1210    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1211    mov     r3, rINST, lsr #8           @ r3<- AA
1212    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
1213    GET_VREG(r1, r3)                    @ r1<- vAA
1214    add     r0, rPC, r0, lsl #1         @ r0<- PC + BBBBbbbb*2
1215    bl      dvmInterpHandlePackedSwitch                       @ r0<- code-unit branch offset
1216    movs    r9, r0, asl #1              @ r9<- branch byte offset, check sign
1217    bmi     common_backwardBranch       @ backward branch, do periodic checks
1218    beq     common_backwardBranch       @ (want to use BLE but V is unknown)
1219#if defined(WITH_JIT)
1220    GET_JIT_PROF_TABLE(r0)
1221    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1222    cmp     r0,#0
1223    bne     common_updateProfile
1224    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1225    GOTO_OPCODE(ip)                     @ jump to next instruction
1226#else
1227    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1228    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1229    GOTO_OPCODE(ip)                     @ jump to next instruction
1230#endif
1231
1232/* ------------------------------ */
1233    .balign 64
1234.L_OP_SPARSE_SWITCH: /* 0x2c */
1235/* File: armv5te/OP_SPARSE_SWITCH.S */
1236/* File: armv5te/OP_PACKED_SWITCH.S */
1237    /*
1238     * Handle a packed-switch or sparse-switch instruction.  In both cases
1239     * we decode it and hand it off to a helper function.
1240     *
1241     * We don't really expect backward branches in a switch statement, but
1242     * they're perfectly legal, so we check for them here.
1243     *
1244     * for: packed-switch, sparse-switch
1245     */
1246    /* op vAA, +BBBB */
1247    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1248    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1249    mov     r3, rINST, lsr #8           @ r3<- AA
1250    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
1251    GET_VREG(r1, r3)                    @ r1<- vAA
1252    add     r0, rPC, r0, lsl #1         @ r0<- PC + BBBBbbbb*2
1253    bl      dvmInterpHandleSparseSwitch                       @ r0<- code-unit branch offset
1254    movs    r9, r0, asl #1              @ r9<- branch byte offset, check sign
1255    bmi     common_backwardBranch       @ backward branch, do periodic checks
1256    beq     common_backwardBranch       @ (want to use BLE but V is unknown)
1257#if defined(WITH_JIT)
1258    GET_JIT_PROF_TABLE(r0)
1259    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1260    cmp     r0,#0
1261    bne     common_updateProfile
1262    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1263    GOTO_OPCODE(ip)                     @ jump to next instruction
1264#else
1265    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1266    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1267    GOTO_OPCODE(ip)                     @ jump to next instruction
1268#endif
1269
1270
1271/* ------------------------------ */
1272    .balign 64
1273.L_OP_CMPL_FLOAT: /* 0x2d */
1274/* File: arm-vfp/OP_CMPL_FLOAT.S */
1275    /*
1276     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1277     * destination register based on the results of the comparison.
1278     *
1279     * int compare(x, y) {
1280     *     if (x == y) {
1281     *         return 0;
1282     *     } else if (x > y) {
1283     *         return 1;
1284     *     } else if (x < y) {
1285     *         return -1;
1286     *     } else {
1287     *         return -1;
1288     *     }
1289     * }
1290     */
1291    /* op vAA, vBB, vCC */
1292    FETCH(r0, 1)                        @ r0<- CCBB
1293    mov     r9, rINST, lsr #8           @ r9<- AA
1294    and     r2, r0, #255                @ r2<- BB
1295    mov     r3, r0, lsr #8              @ r3<- CC
1296    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1297    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1298    flds    s0, [r2]                    @ s0<- vBB
1299    flds    s1, [r3]                    @ s1<- vCC
1300    fcmpes  s0, s1                      @ compare (vBB, vCC)
1301    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1302    mvn     r0, #0                      @ r0<- -1 (default)
1303    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1304    fmstat                              @ export status flags
1305    movgt   r0, #1                      @ (greater than) r1<- 1
1306    moveq   r0, #0                      @ (equal) r1<- 0
1307    b       .LOP_CMPL_FLOAT_finish          @ argh
1308
1309
1310/* ------------------------------ */
1311    .balign 64
1312.L_OP_CMPG_FLOAT: /* 0x2e */
1313/* File: arm-vfp/OP_CMPG_FLOAT.S */
1314    /*
1315     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1316     * destination register based on the results of the comparison.
1317     *
1318     * int compare(x, y) {
1319     *     if (x == y) {
1320     *         return 0;
1321     *     } else if (x < y) {
1322     *         return -1;
1323     *     } else if (x > y) {
1324     *         return 1;
1325     *     } else {
1326     *         return 1;
1327     *     }
1328     * }
1329     */
1330    /* op vAA, vBB, vCC */
1331    FETCH(r0, 1)                        @ r0<- CCBB
1332    mov     r9, rINST, lsr #8           @ r9<- AA
1333    and     r2, r0, #255                @ r2<- BB
1334    mov     r3, r0, lsr #8              @ r3<- CC
1335    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1336    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1337    flds    s0, [r2]                    @ s0<- vBB
1338    flds    s1, [r3]                    @ s1<- vCC
1339    fcmpes  s0, s1                      @ compare (vBB, vCC)
1340    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1341    mov     r0, #1                      @ r0<- 1 (default)
1342    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1343    fmstat                              @ export status flags
1344    mvnmi   r0, #0                      @ (less than) r1<- -1
1345    moveq   r0, #0                      @ (equal) r1<- 0
1346    b       .LOP_CMPG_FLOAT_finish          @ argh
1347
1348
1349/* ------------------------------ */
1350    .balign 64
1351.L_OP_CMPL_DOUBLE: /* 0x2f */
1352/* File: arm-vfp/OP_CMPL_DOUBLE.S */
1353    /*
1354     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1355     * destination register based on the results of the comparison.
1356     *
1357     * int compare(x, y) {
1358     *     if (x == y) {
1359     *         return 0;
1360     *     } else if (x > y) {
1361     *         return 1;
1362     *     } else if (x < y) {
1363     *         return -1;
1364     *     } else {
1365     *         return -1;
1366     *     }
1367     * }
1368     */
1369    /* op vAA, vBB, vCC */
1370    FETCH(r0, 1)                        @ r0<- CCBB
1371    mov     r9, rINST, lsr #8           @ r9<- AA
1372    and     r2, r0, #255                @ r2<- BB
1373    mov     r3, r0, lsr #8              @ r3<- CC
1374    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1375    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1376    fldd    d0, [r2]                    @ d0<- vBB
1377    fldd    d1, [r3]                    @ d1<- vCC
1378    fcmped  d0, d1                      @ compare (vBB, vCC)
1379    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1380    mvn     r0, #0                      @ r0<- -1 (default)
1381    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1382    fmstat                              @ export status flags
1383    movgt   r0, #1                      @ (greater than) r1<- 1
1384    moveq   r0, #0                      @ (equal) r1<- 0
1385    b       .LOP_CMPL_DOUBLE_finish          @ argh
1386
1387
1388/* ------------------------------ */
1389    .balign 64
1390.L_OP_CMPG_DOUBLE: /* 0x30 */
1391/* File: arm-vfp/OP_CMPG_DOUBLE.S */
1392    /*
1393     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1394     * destination register based on the results of the comparison.
1395     *
1396     * int compare(x, y) {
1397     *     if (x == y) {
1398     *         return 0;
1399     *     } else if (x < y) {
1400     *         return -1;
1401     *     } else if (x > y) {
1402     *         return 1;
1403     *     } else {
1404     *         return 1;
1405     *     }
1406     * }
1407     */
1408    /* op vAA, vBB, vCC */
1409    FETCH(r0, 1)                        @ r0<- CCBB
1410    mov     r9, rINST, lsr #8           @ r9<- AA
1411    and     r2, r0, #255                @ r2<- BB
1412    mov     r3, r0, lsr #8              @ r3<- CC
1413    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1414    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1415    fldd    d0, [r2]                    @ d0<- vBB
1416    fldd    d1, [r3]                    @ d1<- vCC
1417    fcmped  d0, d1                      @ compare (vBB, vCC)
1418    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1419    mov     r0, #1                      @ r0<- 1 (default)
1420    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1421    fmstat                              @ export status flags
1422    mvnmi   r0, #0                      @ (less than) r1<- -1
1423    moveq   r0, #0                      @ (equal) r1<- 0
1424    b       .LOP_CMPG_DOUBLE_finish          @ argh
1425
1426
1427/* ------------------------------ */
1428    .balign 64
1429.L_OP_CMP_LONG: /* 0x31 */
1430/* File: armv5te/OP_CMP_LONG.S */
1431    /*
1432     * Compare two 64-bit values.  Puts 0, 1, or -1 into the destination
1433     * register based on the results of the comparison.
1434     *
1435     * We load the full values with LDM, but in practice many values could
1436     * be resolved by only looking at the high word.  This could be made
1437     * faster or slower by splitting the LDM into a pair of LDRs.
1438     *
1439     * If we just wanted to set condition flags, we could do this:
1440     *  subs    ip, r0, r2
1441     *  sbcs    ip, r1, r3
1442     *  subeqs  ip, r0, r2
1443     * Leaving { <0, 0, >0 } in ip.  However, we have to set it to a specific
1444     * integer value, which we can do with 2 conditional mov/mvn instructions
1445     * (set 1, set -1; if they're equal we already have 0 in ip), giving
1446     * us a constant 5-cycle path plus a branch at the end to the
1447     * instruction epilogue code.  The multi-compare approach below needs
1448     * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch
1449     * in the worst case (the 64-bit values are equal).
1450     */
1451    /* cmp-long vAA, vBB, vCC */
1452    FETCH(r0, 1)                        @ r0<- CCBB
1453    mov     r9, rINST, lsr #8           @ r9<- AA
1454    and     r2, r0, #255                @ r2<- BB
1455    mov     r3, r0, lsr #8              @ r3<- CC
1456    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
1457    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
1458    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
1459    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
1460    cmp     r1, r3                      @ compare (vBB+1, vCC+1)
1461    blt     .LOP_CMP_LONG_less            @ signed compare on high part
1462    bgt     .LOP_CMP_LONG_greater
1463    subs    r1, r0, r2                  @ r1<- r0 - r2
1464    bhi     .LOP_CMP_LONG_greater         @ unsigned compare on low part
1465    bne     .LOP_CMP_LONG_less
1466    b       .LOP_CMP_LONG_finish          @ equal; r1 already holds 0
1467
1468/* ------------------------------ */
1469    .balign 64
1470.L_OP_IF_EQ: /* 0x32 */
1471/* File: armv5te/OP_IF_EQ.S */
1472/* File: armv5te/bincmp.S */
1473    /*
1474     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1475     * fragment that specifies the *reverse* comparison to perform, e.g.
1476     * for "if-le" you would use "gt".
1477     *
1478     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1479     */
1480    /* if-cmp vA, vB, +CCCC */
1481    mov     r0, rINST, lsr #8           @ r0<- A+
1482    mov     r1, rINST, lsr #12          @ r1<- B
1483    and     r0, r0, #15
1484    GET_VREG(r3, r1)                    @ r3<- vB
1485    GET_VREG(r2, r0)                    @ r2<- vA
1486    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1487    cmp     r2, r3                      @ compare (vA, vB)
1488    bne  1f                      @ branch to 1 if comparison failed
1489    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1490    movs    r9, r9, asl #1              @ convert to bytes, check sign
1491    bmi     common_backwardBranch       @ yes, do periodic checks
14921:
1493#if defined(WITH_JIT)
1494    GET_JIT_PROF_TABLE(r0)
1495    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1496    b        common_testUpdateProfile
1497#else
1498    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1499    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1500    GOTO_OPCODE(ip)                     @ jump to next instruction
1501#endif
1502
1503
1504/* ------------------------------ */
1505    .balign 64
1506.L_OP_IF_NE: /* 0x33 */
1507/* File: armv5te/OP_IF_NE.S */
1508/* File: armv5te/bincmp.S */
1509    /*
1510     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1511     * fragment that specifies the *reverse* comparison to perform, e.g.
1512     * for "if-le" you would use "gt".
1513     *
1514     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1515     */
1516    /* if-cmp vA, vB, +CCCC */
1517    mov     r0, rINST, lsr #8           @ r0<- A+
1518    mov     r1, rINST, lsr #12          @ r1<- B
1519    and     r0, r0, #15
1520    GET_VREG(r3, r1)                    @ r3<- vB
1521    GET_VREG(r2, r0)                    @ r2<- vA
1522    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1523    cmp     r2, r3                      @ compare (vA, vB)
1524    beq  1f                      @ branch to 1 if comparison failed
1525    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1526    movs    r9, r9, asl #1              @ convert to bytes, check sign
1527    bmi     common_backwardBranch       @ yes, do periodic checks
15281:
1529#if defined(WITH_JIT)
1530    GET_JIT_PROF_TABLE(r0)
1531    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1532    b        common_testUpdateProfile
1533#else
1534    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1535    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1536    GOTO_OPCODE(ip)                     @ jump to next instruction
1537#endif
1538
1539
1540/* ------------------------------ */
1541    .balign 64
1542.L_OP_IF_LT: /* 0x34 */
1543/* File: armv5te/OP_IF_LT.S */
1544/* File: armv5te/bincmp.S */
1545    /*
1546     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1547     * fragment that specifies the *reverse* comparison to perform, e.g.
1548     * for "if-le" you would use "gt".
1549     *
1550     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1551     */
1552    /* if-cmp vA, vB, +CCCC */
1553    mov     r0, rINST, lsr #8           @ r0<- A+
1554    mov     r1, rINST, lsr #12          @ r1<- B
1555    and     r0, r0, #15
1556    GET_VREG(r3, r1)                    @ r3<- vB
1557    GET_VREG(r2, r0)                    @ r2<- vA
1558    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1559    cmp     r2, r3                      @ compare (vA, vB)
1560    bge  1f                      @ branch to 1 if comparison failed
1561    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1562    movs    r9, r9, asl #1              @ convert to bytes, check sign
1563    bmi     common_backwardBranch       @ yes, do periodic checks
15641:
1565#if defined(WITH_JIT)
1566    GET_JIT_PROF_TABLE(r0)
1567    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1568    b        common_testUpdateProfile
1569#else
1570    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1571    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1572    GOTO_OPCODE(ip)                     @ jump to next instruction
1573#endif
1574
1575
1576/* ------------------------------ */
1577    .balign 64
1578.L_OP_IF_GE: /* 0x35 */
1579/* File: armv5te/OP_IF_GE.S */
1580/* File: armv5te/bincmp.S */
1581    /*
1582     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1583     * fragment that specifies the *reverse* comparison to perform, e.g.
1584     * for "if-le" you would use "gt".
1585     *
1586     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1587     */
1588    /* if-cmp vA, vB, +CCCC */
1589    mov     r0, rINST, lsr #8           @ r0<- A+
1590    mov     r1, rINST, lsr #12          @ r1<- B
1591    and     r0, r0, #15
1592    GET_VREG(r3, r1)                    @ r3<- vB
1593    GET_VREG(r2, r0)                    @ r2<- vA
1594    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1595    cmp     r2, r3                      @ compare (vA, vB)
1596    blt  1f                      @ branch to 1 if comparison failed
1597    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1598    movs    r9, r9, asl #1              @ convert to bytes, check sign
1599    bmi     common_backwardBranch       @ yes, do periodic checks
16001:
1601#if defined(WITH_JIT)
1602    GET_JIT_PROF_TABLE(r0)
1603    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1604    b        common_testUpdateProfile
1605#else
1606    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1607    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1608    GOTO_OPCODE(ip)                     @ jump to next instruction
1609#endif
1610
1611
1612/* ------------------------------ */
1613    .balign 64
1614.L_OP_IF_GT: /* 0x36 */
1615/* File: armv5te/OP_IF_GT.S */
1616/* File: armv5te/bincmp.S */
1617    /*
1618     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1619     * fragment that specifies the *reverse* comparison to perform, e.g.
1620     * for "if-le" you would use "gt".
1621     *
1622     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1623     */
1624    /* if-cmp vA, vB, +CCCC */
1625    mov     r0, rINST, lsr #8           @ r0<- A+
1626    mov     r1, rINST, lsr #12          @ r1<- B
1627    and     r0, r0, #15
1628    GET_VREG(r3, r1)                    @ r3<- vB
1629    GET_VREG(r2, r0)                    @ r2<- vA
1630    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1631    cmp     r2, r3                      @ compare (vA, vB)
1632    ble  1f                      @ branch to 1 if comparison failed
1633    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1634    movs    r9, r9, asl #1              @ convert to bytes, check sign
1635    bmi     common_backwardBranch       @ yes, do periodic checks
16361:
1637#if defined(WITH_JIT)
1638    GET_JIT_PROF_TABLE(r0)
1639    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1640    b        common_testUpdateProfile
1641#else
1642    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1643    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1644    GOTO_OPCODE(ip)                     @ jump to next instruction
1645#endif
1646
1647
1648/* ------------------------------ */
1649    .balign 64
1650.L_OP_IF_LE: /* 0x37 */
1651/* File: armv5te/OP_IF_LE.S */
1652/* File: armv5te/bincmp.S */
1653    /*
1654     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1655     * fragment that specifies the *reverse* comparison to perform, e.g.
1656     * for "if-le" you would use "gt".
1657     *
1658     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1659     */
1660    /* if-cmp vA, vB, +CCCC */
1661    mov     r0, rINST, lsr #8           @ r0<- A+
1662    mov     r1, rINST, lsr #12          @ r1<- B
1663    and     r0, r0, #15
1664    GET_VREG(r3, r1)                    @ r3<- vB
1665    GET_VREG(r2, r0)                    @ r2<- vA
1666    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1667    cmp     r2, r3                      @ compare (vA, vB)
1668    bgt  1f                      @ branch to 1 if comparison failed
1669    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1670    movs    r9, r9, asl #1              @ convert to bytes, check sign
1671    bmi     common_backwardBranch       @ yes, do periodic checks
16721:
1673#if defined(WITH_JIT)
1674    GET_JIT_PROF_TABLE(r0)
1675    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1676    b        common_testUpdateProfile
1677#else
1678    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1679    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1680    GOTO_OPCODE(ip)                     @ jump to next instruction
1681#endif
1682
1683
1684/* ------------------------------ */
1685    .balign 64
1686.L_OP_IF_EQZ: /* 0x38 */
1687/* File: armv5te/OP_IF_EQZ.S */
1688/* File: armv5te/zcmp.S */
1689    /*
1690     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1691     * fragment that specifies the *reverse* comparison to perform, e.g.
1692     * for "if-le" you would use "gt".
1693     *
1694     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1695     */
1696    /* if-cmp vAA, +BBBB */
1697    mov     r0, rINST, lsr #8           @ r0<- AA
1698    GET_VREG(r2, r0)                    @ r2<- vAA
1699    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1700    cmp     r2, #0                      @ compare (vA, 0)
1701    bne  1f                      @ branch to 1 if comparison failed
1702    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1703    movs    r9, r9, asl #1              @ convert to bytes, check sign
1704    bmi     common_backwardBranch       @ backward branch, do periodic checks
17051:
1706#if defined(WITH_JIT)
1707    GET_JIT_PROF_TABLE(r0)
1708    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1709    cmp     r0,#0
1710    bne     common_updateProfile
1711    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1712    GOTO_OPCODE(ip)                     @ jump to next instruction
1713#else
1714    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1715    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1716    GOTO_OPCODE(ip)                     @ jump to next instruction
1717#endif
1718
1719
1720/* ------------------------------ */
1721    .balign 64
1722.L_OP_IF_NEZ: /* 0x39 */
1723/* File: armv5te/OP_IF_NEZ.S */
1724/* File: armv5te/zcmp.S */
1725    /*
1726     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1727     * fragment that specifies the *reverse* comparison to perform, e.g.
1728     * for "if-le" you would use "gt".
1729     *
1730     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1731     */
1732    /* if-cmp vAA, +BBBB */
1733    mov     r0, rINST, lsr #8           @ r0<- AA
1734    GET_VREG(r2, r0)                    @ r2<- vAA
1735    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1736    cmp     r2, #0                      @ compare (vA, 0)
1737    beq  1f                      @ branch to 1 if comparison failed
1738    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1739    movs    r9, r9, asl #1              @ convert to bytes, check sign
1740    bmi     common_backwardBranch       @ backward branch, do periodic checks
17411:
1742#if defined(WITH_JIT)
1743    GET_JIT_PROF_TABLE(r0)
1744    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1745    cmp     r0,#0
1746    bne     common_updateProfile
1747    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1748    GOTO_OPCODE(ip)                     @ jump to next instruction
1749#else
1750    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1751    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1752    GOTO_OPCODE(ip)                     @ jump to next instruction
1753#endif
1754
1755
1756/* ------------------------------ */
1757    .balign 64
1758.L_OP_IF_LTZ: /* 0x3a */
1759/* File: armv5te/OP_IF_LTZ.S */
1760/* File: armv5te/zcmp.S */
1761    /*
1762     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1763     * fragment that specifies the *reverse* comparison to perform, e.g.
1764     * for "if-le" you would use "gt".
1765     *
1766     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1767     */
1768    /* if-cmp vAA, +BBBB */
1769    mov     r0, rINST, lsr #8           @ r0<- AA
1770    GET_VREG(r2, r0)                    @ r2<- vAA
1771    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1772    cmp     r2, #0                      @ compare (vA, 0)
1773    bge  1f                      @ branch to 1 if comparison failed
1774    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1775    movs    r9, r9, asl #1              @ convert to bytes, check sign
1776    bmi     common_backwardBranch       @ backward branch, do periodic checks
17771:
1778#if defined(WITH_JIT)
1779    GET_JIT_PROF_TABLE(r0)
1780    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1781    cmp     r0,#0
1782    bne     common_updateProfile
1783    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1784    GOTO_OPCODE(ip)                     @ jump to next instruction
1785#else
1786    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1787    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1788    GOTO_OPCODE(ip)                     @ jump to next instruction
1789#endif
1790
1791
1792/* ------------------------------ */
1793    .balign 64
1794.L_OP_IF_GEZ: /* 0x3b */
1795/* File: armv5te/OP_IF_GEZ.S */
1796/* File: armv5te/zcmp.S */
1797    /*
1798     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1799     * fragment that specifies the *reverse* comparison to perform, e.g.
1800     * for "if-le" you would use "gt".
1801     *
1802     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1803     */
1804    /* if-cmp vAA, +BBBB */
1805    mov     r0, rINST, lsr #8           @ r0<- AA
1806    GET_VREG(r2, r0)                    @ r2<- vAA
1807    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1808    cmp     r2, #0                      @ compare (vA, 0)
1809    blt  1f                      @ branch to 1 if comparison failed
1810    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1811    movs    r9, r9, asl #1              @ convert to bytes, check sign
1812    bmi     common_backwardBranch       @ backward branch, do periodic checks
18131:
1814#if defined(WITH_JIT)
1815    GET_JIT_PROF_TABLE(r0)
1816    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1817    cmp     r0,#0
1818    bne     common_updateProfile
1819    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1820    GOTO_OPCODE(ip)                     @ jump to next instruction
1821#else
1822    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1823    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1824    GOTO_OPCODE(ip)                     @ jump to next instruction
1825#endif
1826
1827
1828/* ------------------------------ */
1829    .balign 64
1830.L_OP_IF_GTZ: /* 0x3c */
1831/* File: armv5te/OP_IF_GTZ.S */
1832/* File: armv5te/zcmp.S */
1833    /*
1834     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1835     * fragment that specifies the *reverse* comparison to perform, e.g.
1836     * for "if-le" you would use "gt".
1837     *
1838     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1839     */
1840    /* if-cmp vAA, +BBBB */
1841    mov     r0, rINST, lsr #8           @ r0<- AA
1842    GET_VREG(r2, r0)                    @ r2<- vAA
1843    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1844    cmp     r2, #0                      @ compare (vA, 0)
1845    ble  1f                      @ branch to 1 if comparison failed
1846    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1847    movs    r9, r9, asl #1              @ convert to bytes, check sign
1848    bmi     common_backwardBranch       @ backward branch, do periodic checks
18491:
1850#if defined(WITH_JIT)
1851    GET_JIT_PROF_TABLE(r0)
1852    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1853    cmp     r0,#0
1854    bne     common_updateProfile
1855    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1856    GOTO_OPCODE(ip)                     @ jump to next instruction
1857#else
1858    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1859    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1860    GOTO_OPCODE(ip)                     @ jump to next instruction
1861#endif
1862
1863
1864/* ------------------------------ */
1865    .balign 64
1866.L_OP_IF_LEZ: /* 0x3d */
1867/* File: armv5te/OP_IF_LEZ.S */
1868/* File: armv5te/zcmp.S */
1869    /*
1870     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1871     * fragment that specifies the *reverse* comparison to perform, e.g.
1872     * for "if-le" you would use "gt".
1873     *
1874     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1875     */
1876    /* if-cmp vAA, +BBBB */
1877    mov     r0, rINST, lsr #8           @ r0<- AA
1878    GET_VREG(r2, r0)                    @ r2<- vAA
1879    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1880    cmp     r2, #0                      @ compare (vA, 0)
1881    bgt  1f                      @ branch to 1 if comparison failed
1882    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1883    movs    r9, r9, asl #1              @ convert to bytes, check sign
1884    bmi     common_backwardBranch       @ backward branch, do periodic checks
18851:
1886#if defined(WITH_JIT)
1887    GET_JIT_PROF_TABLE(r0)
1888    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1889    cmp     r0,#0
1890    bne     common_updateProfile
1891    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1892    GOTO_OPCODE(ip)                     @ jump to next instruction
1893#else
1894    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1895    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1896    GOTO_OPCODE(ip)                     @ jump to next instruction
1897#endif
1898
1899
1900/* ------------------------------ */
1901    .balign 64
1902.L_OP_UNUSED_3E: /* 0x3e */
1903/* File: armv5te/OP_UNUSED_3E.S */
1904/* File: armv5te/unused.S */
1905    bl      common_abort
1906
1907
1908/* ------------------------------ */
1909    .balign 64
1910.L_OP_UNUSED_3F: /* 0x3f */
1911/* File: armv5te/OP_UNUSED_3F.S */
1912/* File: armv5te/unused.S */
1913    bl      common_abort
1914
1915
1916/* ------------------------------ */
1917    .balign 64
1918.L_OP_UNUSED_40: /* 0x40 */
1919/* File: armv5te/OP_UNUSED_40.S */
1920/* File: armv5te/unused.S */
1921    bl      common_abort
1922
1923
1924/* ------------------------------ */
1925    .balign 64
1926.L_OP_UNUSED_41: /* 0x41 */
1927/* File: armv5te/OP_UNUSED_41.S */
1928/* File: armv5te/unused.S */
1929    bl      common_abort
1930
1931
1932/* ------------------------------ */
1933    .balign 64
1934.L_OP_UNUSED_42: /* 0x42 */
1935/* File: armv5te/OP_UNUSED_42.S */
1936/* File: armv5te/unused.S */
1937    bl      common_abort
1938
1939
1940/* ------------------------------ */
1941    .balign 64
1942.L_OP_UNUSED_43: /* 0x43 */
1943/* File: armv5te/OP_UNUSED_43.S */
1944/* File: armv5te/unused.S */
1945    bl      common_abort
1946
1947
1948/* ------------------------------ */
1949    .balign 64
1950.L_OP_AGET: /* 0x44 */
1951/* File: armv5te/OP_AGET.S */
1952    /*
1953     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1954     *
1955     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
1956     * instructions.  We use a pair of FETCH_Bs instead.
1957     *
1958     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1959     */
1960    /* op vAA, vBB, vCC */
1961    FETCH_B(r2, 1, 0)                   @ r2<- BB
1962    mov     r9, rINST, lsr #8           @ r9<- AA
1963    FETCH_B(r3, 1, 1)                   @ r3<- CC
1964    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1965    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1966    cmp     r0, #0                      @ null array object?
1967    beq     common_errNullObject        @ yes, bail
1968    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1969    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
1970    cmp     r1, r3                      @ compare unsigned index, length
1971    bcs     common_errArrayIndex        @ index >= length, bail
1972    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1973    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
1974    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1975    SET_VREG(r2, r9)                    @ vAA<- r2
1976    GOTO_OPCODE(ip)                     @ jump to next instruction
1977
1978/* ------------------------------ */
1979    .balign 64
1980.L_OP_AGET_WIDE: /* 0x45 */
1981/* File: armv5te/OP_AGET_WIDE.S */
1982    /*
1983     * Array get, 64 bits.  vAA <- vBB[vCC].
1984     *
1985     * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD.
1986     */
1987    /* aget-wide vAA, vBB, vCC */
1988    FETCH(r0, 1)                        @ r0<- CCBB
1989    mov     r9, rINST, lsr #8           @ r9<- AA
1990    and     r2, r0, #255                @ r2<- BB
1991    mov     r3, r0, lsr #8              @ r3<- CC
1992    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1993    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1994    cmp     r0, #0                      @ null array object?
1995    beq     common_errNullObject        @ yes, bail
1996    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1997    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
1998    cmp     r1, r3                      @ compare unsigned index, length
1999    bcc     .LOP_AGET_WIDE_finish          @ okay, continue below
2000    b       common_errArrayIndex        @ index >= length, bail
2001    @ May want to swap the order of these two branches depending on how the
2002    @ branch prediction (if any) handles conditional forward branches vs.
2003    @ unconditional forward branches.
2004
2005/* ------------------------------ */
2006    .balign 64
2007.L_OP_AGET_OBJECT: /* 0x46 */
2008/* File: armv5te/OP_AGET_OBJECT.S */
2009/* File: armv5te/OP_AGET.S */
2010    /*
2011     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2012     *
2013     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2014     * instructions.  We use a pair of FETCH_Bs instead.
2015     *
2016     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2017     */
2018    /* op vAA, vBB, vCC */
2019    FETCH_B(r2, 1, 0)                   @ r2<- BB
2020    mov     r9, rINST, lsr #8           @ r9<- AA
2021    FETCH_B(r3, 1, 1)                   @ r3<- CC
2022    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2023    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2024    cmp     r0, #0                      @ null array object?
2025    beq     common_errNullObject        @ yes, bail
2026    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2027    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
2028    cmp     r1, r3                      @ compare unsigned index, length
2029    bcs     common_errArrayIndex        @ index >= length, bail
2030    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2031    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2032    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2033    SET_VREG(r2, r9)                    @ vAA<- r2
2034    GOTO_OPCODE(ip)                     @ jump to next instruction
2035
2036
2037/* ------------------------------ */
2038    .balign 64
2039.L_OP_AGET_BOOLEAN: /* 0x47 */
2040/* File: armv5te/OP_AGET_BOOLEAN.S */
2041/* File: armv5te/OP_AGET.S */
2042    /*
2043     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2044     *
2045     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2046     * instructions.  We use a pair of FETCH_Bs instead.
2047     *
2048     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2049     */
2050    /* op vAA, vBB, vCC */
2051    FETCH_B(r2, 1, 0)                   @ r2<- BB
2052    mov     r9, rINST, lsr #8           @ r9<- AA
2053    FETCH_B(r3, 1, 1)                   @ r3<- CC
2054    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2055    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2056    cmp     r0, #0                      @ null array object?
2057    beq     common_errNullObject        @ yes, bail
2058    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2059    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2060    cmp     r1, r3                      @ compare unsigned index, length
2061    bcs     common_errArrayIndex        @ index >= length, bail
2062    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2063    ldrb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2064    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2065    SET_VREG(r2, r9)                    @ vAA<- r2
2066    GOTO_OPCODE(ip)                     @ jump to next instruction
2067
2068
2069/* ------------------------------ */
2070    .balign 64
2071.L_OP_AGET_BYTE: /* 0x48 */
2072/* File: armv5te/OP_AGET_BYTE.S */
2073/* File: armv5te/OP_AGET.S */
2074    /*
2075     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2076     *
2077     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2078     * instructions.  We use a pair of FETCH_Bs instead.
2079     *
2080     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2081     */
2082    /* op vAA, vBB, vCC */
2083    FETCH_B(r2, 1, 0)                   @ r2<- BB
2084    mov     r9, rINST, lsr #8           @ r9<- AA
2085    FETCH_B(r3, 1, 1)                   @ r3<- CC
2086    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2087    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2088    cmp     r0, #0                      @ null array object?
2089    beq     common_errNullObject        @ yes, bail
2090    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2091    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2092    cmp     r1, r3                      @ compare unsigned index, length
2093    bcs     common_errArrayIndex        @ index >= length, bail
2094    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2095    ldrsb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2096    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2097    SET_VREG(r2, r9)                    @ vAA<- r2
2098    GOTO_OPCODE(ip)                     @ jump to next instruction
2099
2100
2101/* ------------------------------ */
2102    .balign 64
2103.L_OP_AGET_CHAR: /* 0x49 */
2104/* File: armv5te/OP_AGET_CHAR.S */
2105/* File: armv5te/OP_AGET.S */
2106    /*
2107     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2108     *
2109     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2110     * instructions.  We use a pair of FETCH_Bs instead.
2111     *
2112     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2113     */
2114    /* op vAA, vBB, vCC */
2115    FETCH_B(r2, 1, 0)                   @ r2<- BB
2116    mov     r9, rINST, lsr #8           @ r9<- AA
2117    FETCH_B(r3, 1, 1)                   @ r3<- CC
2118    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2119    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2120    cmp     r0, #0                      @ null array object?
2121    beq     common_errNullObject        @ yes, bail
2122    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2123    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2124    cmp     r1, r3                      @ compare unsigned index, length
2125    bcs     common_errArrayIndex        @ index >= length, bail
2126    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2127    ldrh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2128    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2129    SET_VREG(r2, r9)                    @ vAA<- r2
2130    GOTO_OPCODE(ip)                     @ jump to next instruction
2131
2132
2133/* ------------------------------ */
2134    .balign 64
2135.L_OP_AGET_SHORT: /* 0x4a */
2136/* File: armv5te/OP_AGET_SHORT.S */
2137/* File: armv5te/OP_AGET.S */
2138    /*
2139     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2140     *
2141     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2142     * instructions.  We use a pair of FETCH_Bs instead.
2143     *
2144     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2145     */
2146    /* op vAA, vBB, vCC */
2147    FETCH_B(r2, 1, 0)                   @ r2<- BB
2148    mov     r9, rINST, lsr #8           @ r9<- AA
2149    FETCH_B(r3, 1, 1)                   @ r3<- CC
2150    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2151    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2152    cmp     r0, #0                      @ null array object?
2153    beq     common_errNullObject        @ yes, bail
2154    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2155    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2156    cmp     r1, r3                      @ compare unsigned index, length
2157    bcs     common_errArrayIndex        @ index >= length, bail
2158    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2159    ldrsh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2160    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2161    SET_VREG(r2, r9)                    @ vAA<- r2
2162    GOTO_OPCODE(ip)                     @ jump to next instruction
2163
2164
2165/* ------------------------------ */
2166    .balign 64
2167.L_OP_APUT: /* 0x4b */
2168/* File: armv5te/OP_APUT.S */
2169    /*
2170     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2171     *
2172     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2173     * instructions.  We use a pair of FETCH_Bs instead.
2174     *
2175     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2176     */
2177    /* op vAA, vBB, vCC */
2178    FETCH_B(r2, 1, 0)                   @ r2<- BB
2179    mov     r9, rINST, lsr #8           @ r9<- AA
2180    FETCH_B(r3, 1, 1)                   @ r3<- CC
2181    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2182    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2183    cmp     r0, #0                      @ null array object?
2184    beq     common_errNullObject        @ yes, bail
2185    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2186    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
2187    cmp     r1, r3                      @ compare unsigned index, length
2188    bcs     common_errArrayIndex        @ index >= length, bail
2189    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2190    GET_VREG(r2, r9)                    @ r2<- vAA
2191    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2192    str  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2193    GOTO_OPCODE(ip)                     @ jump to next instruction
2194
2195/* ------------------------------ */
2196    .balign 64
2197.L_OP_APUT_WIDE: /* 0x4c */
2198/* File: armv5te/OP_APUT_WIDE.S */
2199    /*
2200     * Array put, 64 bits.  vBB[vCC] <- vAA.
2201     *
2202     * Arrays of long/double are 64-bit aligned, so it's okay to use STRD.
2203     */
2204    /* aput-wide vAA, vBB, vCC */
2205    FETCH(r0, 1)                        @ r0<- CCBB
2206    mov     r9, rINST, lsr #8           @ r9<- AA
2207    and     r2, r0, #255                @ r2<- BB
2208    mov     r3, r0, lsr #8              @ r3<- CC
2209    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2210    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2211    cmp     r0, #0                      @ null array object?
2212    beq     common_errNullObject        @ yes, bail
2213    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2214    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
2215    cmp     r1, r3                      @ compare unsigned index, length
2216    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2217    bcc     .LOP_APUT_WIDE_finish          @ okay, continue below
2218    b       common_errArrayIndex        @ index >= length, bail
2219    @ May want to swap the order of these two branches depending on how the
2220    @ branch prediction (if any) handles conditional forward branches vs.
2221    @ unconditional forward branches.
2222
2223/* ------------------------------ */
2224    .balign 64
2225.L_OP_APUT_OBJECT: /* 0x4d */
2226/* File: armv5te/OP_APUT_OBJECT.S */
2227    /*
2228     * Store an object into an array.  vBB[vCC] <- vAA.
2229     */
2230    /* op vAA, vBB, vCC */
2231    FETCH(r0, 1)                        @ r0<- CCBB
2232    mov     r9, rINST, lsr #8           @ r9<- AA
2233    and     r2, r0, #255                @ r2<- BB
2234    mov     r3, r0, lsr #8              @ r3<- CC
2235    GET_VREG(rINST, r2)                 @ rINST<- vBB (array object)
2236    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2237    cmp     rINST, #0                   @ null array object?
2238    GET_VREG(r9, r9)                    @ r9<- vAA
2239    beq     common_errNullObject        @ yes, bail
2240    ldr     r3, [rINST, #offArrayObject_length]   @ r3<- arrayObj->length
2241    add     r10, rINST, r1, lsl #2      @ r10<- arrayObj + index*width
2242    cmp     r1, r3                      @ compare unsigned index, length
2243    bcc     .LOP_APUT_OBJECT_finish          @ we're okay, continue on
2244    b       common_errArrayIndex        @ index >= length, bail
2245
2246
2247/* ------------------------------ */
2248    .balign 64
2249.L_OP_APUT_BOOLEAN: /* 0x4e */
2250/* File: armv5te/OP_APUT_BOOLEAN.S */
2251/* File: armv5te/OP_APUT.S */
2252    /*
2253     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2254     *
2255     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2256     * instructions.  We use a pair of FETCH_Bs instead.
2257     *
2258     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2259     */
2260    /* op vAA, vBB, vCC */
2261    FETCH_B(r2, 1, 0)                   @ r2<- BB
2262    mov     r9, rINST, lsr #8           @ r9<- AA
2263    FETCH_B(r3, 1, 1)                   @ r3<- CC
2264    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2265    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2266    cmp     r0, #0                      @ null array object?
2267    beq     common_errNullObject        @ yes, bail
2268    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2269    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2270    cmp     r1, r3                      @ compare unsigned index, length
2271    bcs     common_errArrayIndex        @ index >= length, bail
2272    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2273    GET_VREG(r2, r9)                    @ r2<- vAA
2274    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2275    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2276    GOTO_OPCODE(ip)                     @ jump to next instruction
2277
2278
2279/* ------------------------------ */
2280    .balign 64
2281.L_OP_APUT_BYTE: /* 0x4f */
2282/* File: armv5te/OP_APUT_BYTE.S */
2283/* File: armv5te/OP_APUT.S */
2284    /*
2285     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2286     *
2287     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2288     * instructions.  We use a pair of FETCH_Bs instead.
2289     *
2290     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2291     */
2292    /* op vAA, vBB, vCC */
2293    FETCH_B(r2, 1, 0)                   @ r2<- BB
2294    mov     r9, rINST, lsr #8           @ r9<- AA
2295    FETCH_B(r3, 1, 1)                   @ r3<- CC
2296    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2297    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2298    cmp     r0, #0                      @ null array object?
2299    beq     common_errNullObject        @ yes, bail
2300    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2301    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2302    cmp     r1, r3                      @ compare unsigned index, length
2303    bcs     common_errArrayIndex        @ index >= length, bail
2304    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2305    GET_VREG(r2, r9)                    @ r2<- vAA
2306    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2307    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2308    GOTO_OPCODE(ip)                     @ jump to next instruction
2309
2310
2311/* ------------------------------ */
2312    .balign 64
2313.L_OP_APUT_CHAR: /* 0x50 */
2314/* File: armv5te/OP_APUT_CHAR.S */
2315/* File: armv5te/OP_APUT.S */
2316    /*
2317     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2318     *
2319     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2320     * instructions.  We use a pair of FETCH_Bs instead.
2321     *
2322     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2323     */
2324    /* op vAA, vBB, vCC */
2325    FETCH_B(r2, 1, 0)                   @ r2<- BB
2326    mov     r9, rINST, lsr #8           @ r9<- AA
2327    FETCH_B(r3, 1, 1)                   @ r3<- CC
2328    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2329    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2330    cmp     r0, #0                      @ null array object?
2331    beq     common_errNullObject        @ yes, bail
2332    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2333    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2334    cmp     r1, r3                      @ compare unsigned index, length
2335    bcs     common_errArrayIndex        @ index >= length, bail
2336    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2337    GET_VREG(r2, r9)                    @ r2<- vAA
2338    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2339    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2340    GOTO_OPCODE(ip)                     @ jump to next instruction
2341
2342
2343/* ------------------------------ */
2344    .balign 64
2345.L_OP_APUT_SHORT: /* 0x51 */
2346/* File: armv5te/OP_APUT_SHORT.S */
2347/* File: armv5te/OP_APUT.S */
2348    /*
2349     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2350     *
2351     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2352     * instructions.  We use a pair of FETCH_Bs instead.
2353     *
2354     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2355     */
2356    /* op vAA, vBB, vCC */
2357    FETCH_B(r2, 1, 0)                   @ r2<- BB
2358    mov     r9, rINST, lsr #8           @ r9<- AA
2359    FETCH_B(r3, 1, 1)                   @ r3<- CC
2360    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2361    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2362    cmp     r0, #0                      @ null array object?
2363    beq     common_errNullObject        @ yes, bail
2364    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2365    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2366    cmp     r1, r3                      @ compare unsigned index, length
2367    bcs     common_errArrayIndex        @ index >= length, bail
2368    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2369    GET_VREG(r2, r9)                    @ r2<- vAA
2370    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2371    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2372    GOTO_OPCODE(ip)                     @ jump to next instruction
2373
2374
2375/* ------------------------------ */
2376    .balign 64
2377.L_OP_IGET: /* 0x52 */
2378/* File: armv5te/OP_IGET.S */
2379    /*
2380     * General 32-bit instance field get.
2381     *
2382     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2383     */
2384    /* op vA, vB, field@CCCC */
2385    mov     r0, rINST, lsr #12          @ r0<- B
2386    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2387    FETCH(r1, 1)                        @ r1<- field ref CCCC
2388    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2389    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2390    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2391    cmp     r0, #0                      @ is resolved entry null?
2392    bne     .LOP_IGET_finish          @ no, already resolved
23938:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2394    EXPORT_PC()                         @ resolve() could throw
2395    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2396    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2397    cmp     r0, #0
2398    bne     .LOP_IGET_finish
2399    b       common_exceptionThrown
2400
2401/* ------------------------------ */
2402    .balign 64
2403.L_OP_IGET_WIDE: /* 0x53 */
2404/* File: armv5te/OP_IGET_WIDE.S */
2405    /*
2406     * Wide 32-bit instance field get.
2407     */
2408    /* iget-wide vA, vB, field@CCCC */
2409    mov     r0, rINST, lsr #12          @ r0<- B
2410    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2411    FETCH(r1, 1)                        @ r1<- field ref CCCC
2412    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
2413    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2414    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2415    cmp     r0, #0                      @ is resolved entry null?
2416    bne     .LOP_IGET_WIDE_finish          @ no, already resolved
24178:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
2418    EXPORT_PC()                         @ resolve() could throw
2419    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2420    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2421    cmp     r0, #0
2422    bne     .LOP_IGET_WIDE_finish
2423    b       common_exceptionThrown
2424
2425/* ------------------------------ */
2426    .balign 64
2427.L_OP_IGET_OBJECT: /* 0x54 */
2428/* File: armv5te/OP_IGET_OBJECT.S */
2429/* File: armv5te/OP_IGET.S */
2430    /*
2431     * General 32-bit instance field get.
2432     *
2433     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2434     */
2435    /* op vA, vB, field@CCCC */
2436    mov     r0, rINST, lsr #12          @ r0<- B
2437    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2438    FETCH(r1, 1)                        @ r1<- field ref CCCC
2439    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2440    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2441    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2442    cmp     r0, #0                      @ is resolved entry null?
2443    bne     .LOP_IGET_OBJECT_finish          @ no, already resolved
24448:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2445    EXPORT_PC()                         @ resolve() could throw
2446    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2447    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2448    cmp     r0, #0
2449    bne     .LOP_IGET_OBJECT_finish
2450    b       common_exceptionThrown
2451
2452
2453/* ------------------------------ */
2454    .balign 64
2455.L_OP_IGET_BOOLEAN: /* 0x55 */
2456/* File: armv5te/OP_IGET_BOOLEAN.S */
2457@include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" }
2458/* File: armv5te/OP_IGET.S */
2459    /*
2460     * General 32-bit instance field get.
2461     *
2462     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2463     */
2464    /* op vA, vB, field@CCCC */
2465    mov     r0, rINST, lsr #12          @ r0<- B
2466    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2467    FETCH(r1, 1)                        @ r1<- field ref CCCC
2468    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2469    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2470    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2471    cmp     r0, #0                      @ is resolved entry null?
2472    bne     .LOP_IGET_BOOLEAN_finish          @ no, already resolved
24738:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2474    EXPORT_PC()                         @ resolve() could throw
2475    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2476    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2477    cmp     r0, #0
2478    bne     .LOP_IGET_BOOLEAN_finish
2479    b       common_exceptionThrown
2480
2481
2482/* ------------------------------ */
2483    .balign 64
2484.L_OP_IGET_BYTE: /* 0x56 */
2485/* File: armv5te/OP_IGET_BYTE.S */
2486@include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" }
2487/* File: armv5te/OP_IGET.S */
2488    /*
2489     * General 32-bit instance field get.
2490     *
2491     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2492     */
2493    /* op vA, vB, field@CCCC */
2494    mov     r0, rINST, lsr #12          @ r0<- B
2495    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2496    FETCH(r1, 1)                        @ r1<- field ref CCCC
2497    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2498    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2499    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2500    cmp     r0, #0                      @ is resolved entry null?
2501    bne     .LOP_IGET_BYTE_finish          @ no, already resolved
25028:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2503    EXPORT_PC()                         @ resolve() could throw
2504    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2505    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2506    cmp     r0, #0
2507    bne     .LOP_IGET_BYTE_finish
2508    b       common_exceptionThrown
2509
2510
2511/* ------------------------------ */
2512    .balign 64
2513.L_OP_IGET_CHAR: /* 0x57 */
2514/* File: armv5te/OP_IGET_CHAR.S */
2515@include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" }
2516/* File: armv5te/OP_IGET.S */
2517    /*
2518     * General 32-bit instance field get.
2519     *
2520     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2521     */
2522    /* op vA, vB, field@CCCC */
2523    mov     r0, rINST, lsr #12          @ r0<- B
2524    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2525    FETCH(r1, 1)                        @ r1<- field ref CCCC
2526    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2527    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2528    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2529    cmp     r0, #0                      @ is resolved entry null?
2530    bne     .LOP_IGET_CHAR_finish          @ no, already resolved
25318:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2532    EXPORT_PC()                         @ resolve() could throw
2533    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2534    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2535    cmp     r0, #0
2536    bne     .LOP_IGET_CHAR_finish
2537    b       common_exceptionThrown
2538
2539
2540/* ------------------------------ */
2541    .balign 64
2542.L_OP_IGET_SHORT: /* 0x58 */
2543/* File: armv5te/OP_IGET_SHORT.S */
2544@include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" }
2545/* File: armv5te/OP_IGET.S */
2546    /*
2547     * General 32-bit instance field get.
2548     *
2549     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2550     */
2551    /* op vA, vB, field@CCCC */
2552    mov     r0, rINST, lsr #12          @ r0<- B
2553    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2554    FETCH(r1, 1)                        @ r1<- field ref CCCC
2555    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2556    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2557    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2558    cmp     r0, #0                      @ is resolved entry null?
2559    bne     .LOP_IGET_SHORT_finish          @ no, already resolved
25608:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2561    EXPORT_PC()                         @ resolve() could throw
2562    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2563    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2564    cmp     r0, #0
2565    bne     .LOP_IGET_SHORT_finish
2566    b       common_exceptionThrown
2567
2568
2569/* ------------------------------ */
2570    .balign 64
2571.L_OP_IPUT: /* 0x59 */
2572/* File: armv5te/OP_IPUT.S */
2573    /*
2574     * General 32-bit instance field put.
2575     *
2576     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2577     */
2578    /* op vA, vB, field@CCCC */
2579    mov     r0, rINST, lsr #12          @ r0<- B
2580    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2581    FETCH(r1, 1)                        @ r1<- field ref CCCC
2582    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2583    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2584    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2585    cmp     r0, #0                      @ is resolved entry null?
2586    bne     .LOP_IPUT_finish          @ no, already resolved
25878:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2588    EXPORT_PC()                         @ resolve() could throw
2589    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2590    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2591    cmp     r0, #0                      @ success?
2592    bne     .LOP_IPUT_finish          @ yes, finish up
2593    b       common_exceptionThrown
2594
2595/* ------------------------------ */
2596    .balign 64
2597.L_OP_IPUT_WIDE: /* 0x5a */
2598/* File: armv5te/OP_IPUT_WIDE.S */
2599    /* iput-wide 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<- 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_WIDE_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_WIDE_finish          @ yes, finish up
2614    b       common_exceptionThrown
2615
2616/* ------------------------------ */
2617    .balign 64
2618.L_OP_IPUT_OBJECT: /* 0x5b */
2619/* File: armv5te/OP_IPUT_OBJECT.S */
2620    /*
2621     * 32-bit instance field put.
2622     *
2623     * for: iput-object, iput-object-volatile
2624     */
2625    /* op vA, vB, field@CCCC */
2626    mov     r0, rINST, lsr #12          @ r0<- B
2627    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2628    FETCH(r1, 1)                        @ r1<- field ref CCCC
2629    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2630    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2631    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2632    cmp     r0, #0                      @ is resolved entry null?
2633    bne     .LOP_IPUT_OBJECT_finish          @ no, already resolved
26348:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2635    EXPORT_PC()                         @ resolve() could throw
2636    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2637    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2638    cmp     r0, #0                      @ success?
2639    bne     .LOP_IPUT_OBJECT_finish          @ yes, finish up
2640    b       common_exceptionThrown
2641
2642/* ------------------------------ */
2643    .balign 64
2644.L_OP_IPUT_BOOLEAN: /* 0x5c */
2645/* File: armv5te/OP_IPUT_BOOLEAN.S */
2646@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" }
2647/* File: armv5te/OP_IPUT.S */
2648    /*
2649     * General 32-bit instance field put.
2650     *
2651     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2652     */
2653    /* op vA, vB, field@CCCC */
2654    mov     r0, rINST, lsr #12          @ r0<- B
2655    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2656    FETCH(r1, 1)                        @ r1<- field ref CCCC
2657    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2658    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2659    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2660    cmp     r0, #0                      @ is resolved entry null?
2661    bne     .LOP_IPUT_BOOLEAN_finish          @ no, already resolved
26628:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2663    EXPORT_PC()                         @ resolve() could throw
2664    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2665    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2666    cmp     r0, #0                      @ success?
2667    bne     .LOP_IPUT_BOOLEAN_finish          @ yes, finish up
2668    b       common_exceptionThrown
2669
2670
2671/* ------------------------------ */
2672    .balign 64
2673.L_OP_IPUT_BYTE: /* 0x5d */
2674/* File: armv5te/OP_IPUT_BYTE.S */
2675@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" }
2676/* File: armv5te/OP_IPUT.S */
2677    /*
2678     * General 32-bit instance field put.
2679     *
2680     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2681     */
2682    /* op vA, vB, field@CCCC */
2683    mov     r0, rINST, lsr #12          @ r0<- B
2684    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2685    FETCH(r1, 1)                        @ r1<- field ref CCCC
2686    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2687    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2688    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2689    cmp     r0, #0                      @ is resolved entry null?
2690    bne     .LOP_IPUT_BYTE_finish          @ no, already resolved
26918:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2692    EXPORT_PC()                         @ resolve() could throw
2693    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2694    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2695    cmp     r0, #0                      @ success?
2696    bne     .LOP_IPUT_BYTE_finish          @ yes, finish up
2697    b       common_exceptionThrown
2698
2699
2700/* ------------------------------ */
2701    .balign 64
2702.L_OP_IPUT_CHAR: /* 0x5e */
2703/* File: armv5te/OP_IPUT_CHAR.S */
2704@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" }
2705/* File: armv5te/OP_IPUT.S */
2706    /*
2707     * General 32-bit instance field put.
2708     *
2709     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2710     */
2711    /* op vA, vB, field@CCCC */
2712    mov     r0, rINST, lsr #12          @ r0<- B
2713    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2714    FETCH(r1, 1)                        @ r1<- field ref CCCC
2715    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2716    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2717    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2718    cmp     r0, #0                      @ is resolved entry null?
2719    bne     .LOP_IPUT_CHAR_finish          @ no, already resolved
27208:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2721    EXPORT_PC()                         @ resolve() could throw
2722    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2723    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2724    cmp     r0, #0                      @ success?
2725    bne     .LOP_IPUT_CHAR_finish          @ yes, finish up
2726    b       common_exceptionThrown
2727
2728
2729/* ------------------------------ */
2730    .balign 64
2731.L_OP_IPUT_SHORT: /* 0x5f */
2732/* File: armv5te/OP_IPUT_SHORT.S */
2733@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" }
2734/* File: armv5te/OP_IPUT.S */
2735    /*
2736     * General 32-bit instance field put.
2737     *
2738     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2739     */
2740    /* op vA, vB, field@CCCC */
2741    mov     r0, rINST, lsr #12          @ r0<- B
2742    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
2743    FETCH(r1, 1)                        @ r1<- field ref CCCC
2744    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2745    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2746    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2747    cmp     r0, #0                      @ is resolved entry null?
2748    bne     .LOP_IPUT_SHORT_finish          @ no, already resolved
27498:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
2750    EXPORT_PC()                         @ resolve() could throw
2751    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2752    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2753    cmp     r0, #0                      @ success?
2754    bne     .LOP_IPUT_SHORT_finish          @ yes, finish up
2755    b       common_exceptionThrown
2756
2757
2758/* ------------------------------ */
2759    .balign 64
2760.L_OP_SGET: /* 0x60 */
2761/* File: armv5te/OP_SGET.S */
2762    /*
2763     * General 32-bit SGET handler.
2764     *
2765     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2766     */
2767    /* op vAA, field@BBBB */
2768    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2769    FETCH(r1, 1)                        @ r1<- field ref BBBB
2770    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2771    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2772    cmp     r0, #0                      @ is resolved entry null?
2773    beq     .LOP_SGET_resolve         @ yes, do resolve
2774.LOP_SGET_finish: @ field ptr in r0
2775    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2776    @ no-op                             @ acquiring load
2777    mov     r2, rINST, lsr #8           @ r2<- AA
2778    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2779    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2780    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2781    GOTO_OPCODE(ip)                     @ jump to next instruction
2782
2783/* ------------------------------ */
2784    .balign 64
2785.L_OP_SGET_WIDE: /* 0x61 */
2786/* File: armv5te/OP_SGET_WIDE.S */
2787    /*
2788     * 64-bit SGET handler.
2789     */
2790    /* sget-wide vAA, field@BBBB */
2791    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2792    FETCH(r1, 1)                        @ r1<- field ref BBBB
2793    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2794    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2795    cmp     r0, #0                      @ is resolved entry null?
2796    beq     .LOP_SGET_WIDE_resolve         @ yes, do resolve
2797.LOP_SGET_WIDE_finish:
2798    mov     r9, rINST, lsr #8           @ r9<- AA
2799    .if 0
2800    add     r0, r0, #offStaticField_value @ r0<- pointer to data
2801    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
2802    .else
2803    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
2804    .endif
2805    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2806    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2807    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
2808    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2809    GOTO_OPCODE(ip)                     @ jump to next instruction
2810
2811/* ------------------------------ */
2812    .balign 64
2813.L_OP_SGET_OBJECT: /* 0x62 */
2814/* File: armv5te/OP_SGET_OBJECT.S */
2815/* File: armv5te/OP_SGET.S */
2816    /*
2817     * General 32-bit SGET handler.
2818     *
2819     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2820     */
2821    /* op vAA, field@BBBB */
2822    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2823    FETCH(r1, 1)                        @ r1<- field ref BBBB
2824    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2825    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2826    cmp     r0, #0                      @ is resolved entry null?
2827    beq     .LOP_SGET_OBJECT_resolve         @ yes, do resolve
2828.LOP_SGET_OBJECT_finish: @ field ptr in r0
2829    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2830    @ no-op                             @ acquiring load
2831    mov     r2, rINST, lsr #8           @ r2<- AA
2832    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2833    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2834    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2835    GOTO_OPCODE(ip)                     @ jump to next instruction
2836
2837
2838/* ------------------------------ */
2839    .balign 64
2840.L_OP_SGET_BOOLEAN: /* 0x63 */
2841/* File: armv5te/OP_SGET_BOOLEAN.S */
2842/* File: armv5te/OP_SGET.S */
2843    /*
2844     * General 32-bit SGET handler.
2845     *
2846     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2847     */
2848    /* op vAA, field@BBBB */
2849    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2850    FETCH(r1, 1)                        @ r1<- field ref BBBB
2851    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2852    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2853    cmp     r0, #0                      @ is resolved entry null?
2854    beq     .LOP_SGET_BOOLEAN_resolve         @ yes, do resolve
2855.LOP_SGET_BOOLEAN_finish: @ field ptr in r0
2856    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2857    @ no-op                             @ acquiring load
2858    mov     r2, rINST, lsr #8           @ r2<- AA
2859    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2860    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2861    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2862    GOTO_OPCODE(ip)                     @ jump to next instruction
2863
2864
2865/* ------------------------------ */
2866    .balign 64
2867.L_OP_SGET_BYTE: /* 0x64 */
2868/* File: armv5te/OP_SGET_BYTE.S */
2869/* File: armv5te/OP_SGET.S */
2870    /*
2871     * General 32-bit SGET handler.
2872     *
2873     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2874     */
2875    /* op vAA, field@BBBB */
2876    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2877    FETCH(r1, 1)                        @ r1<- field ref BBBB
2878    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2879    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2880    cmp     r0, #0                      @ is resolved entry null?
2881    beq     .LOP_SGET_BYTE_resolve         @ yes, do resolve
2882.LOP_SGET_BYTE_finish: @ field ptr in r0
2883    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2884    @ no-op                             @ acquiring load
2885    mov     r2, rINST, lsr #8           @ r2<- AA
2886    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2887    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2888    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2889    GOTO_OPCODE(ip)                     @ jump to next instruction
2890
2891
2892/* ------------------------------ */
2893    .balign 64
2894.L_OP_SGET_CHAR: /* 0x65 */
2895/* File: armv5te/OP_SGET_CHAR.S */
2896/* File: armv5te/OP_SGET.S */
2897    /*
2898     * General 32-bit SGET handler.
2899     *
2900     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2901     */
2902    /* op vAA, field@BBBB */
2903    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2904    FETCH(r1, 1)                        @ r1<- field ref BBBB
2905    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2906    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2907    cmp     r0, #0                      @ is resolved entry null?
2908    beq     .LOP_SGET_CHAR_resolve         @ yes, do resolve
2909.LOP_SGET_CHAR_finish: @ field ptr in r0
2910    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2911    @ no-op                             @ acquiring load
2912    mov     r2, rINST, lsr #8           @ r2<- AA
2913    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2914    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2915    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2916    GOTO_OPCODE(ip)                     @ jump to next instruction
2917
2918
2919/* ------------------------------ */
2920    .balign 64
2921.L_OP_SGET_SHORT: /* 0x66 */
2922/* File: armv5te/OP_SGET_SHORT.S */
2923/* File: armv5te/OP_SGET.S */
2924    /*
2925     * General 32-bit SGET handler.
2926     *
2927     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2928     */
2929    /* op vAA, field@BBBB */
2930    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2931    FETCH(r1, 1)                        @ r1<- field ref BBBB
2932    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2933    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2934    cmp     r0, #0                      @ is resolved entry null?
2935    beq     .LOP_SGET_SHORT_resolve         @ yes, do resolve
2936.LOP_SGET_SHORT_finish: @ field ptr in r0
2937    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2938    @ no-op                             @ acquiring load
2939    mov     r2, rINST, lsr #8           @ r2<- AA
2940    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2941    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2942    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2943    GOTO_OPCODE(ip)                     @ jump to next instruction
2944
2945
2946/* ------------------------------ */
2947    .balign 64
2948.L_OP_SPUT: /* 0x67 */
2949/* File: armv5te/OP_SPUT.S */
2950    /*
2951     * General 32-bit SPUT handler.
2952     *
2953     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2954     */
2955    /* op vAA, field@BBBB */
2956    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
2957    FETCH(r1, 1)                        @ r1<- field ref BBBB
2958    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2959    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2960    cmp     r0, #0                      @ is resolved entry null?
2961    beq     .LOP_SPUT_resolve         @ yes, do resolve
2962.LOP_SPUT_finish:   @ field ptr in r0
2963    mov     r2, rINST, lsr #8           @ r2<- AA
2964    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2965    GET_VREG(r1, r2)                    @ r1<- fp[AA]
2966    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2967    @ no-op                             @ releasing store
2968    str     r1, [r0, #offStaticField_value] @ field<- vAA
2969    GOTO_OPCODE(ip)                     @ jump to next instruction
2970
2971/* ------------------------------ */
2972    .balign 64
2973.L_OP_SPUT_WIDE: /* 0x68 */
2974/* File: armv5te/OP_SPUT_WIDE.S */
2975    /*
2976     * 64-bit SPUT handler.
2977     */
2978    /* sput-wide vAA, field@BBBB */
2979    ldr     r0, [rGLUE, #offGlue_methodClassDex]  @ r0<- DvmDex
2980    FETCH(r1, 1)                        @ r1<- field ref BBBB
2981    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
2982    mov     r9, rINST, lsr #8           @ r9<- AA
2983    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
2984    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2985    cmp     r2, #0                      @ is resolved entry null?
2986    beq     .LOP_SPUT_WIDE_resolve         @ yes, do resolve
2987.LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9
2988    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2989    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
2990    GET_INST_OPCODE(r10)                @ extract opcode from rINST
2991    .if 0
2992    add     r2, r2, #offStaticField_value @ r2<- pointer to data
2993    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
2994    .else
2995    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
2996    .endif
2997    GOTO_OPCODE(r10)                    @ jump to next instruction
2998
2999/* ------------------------------ */
3000    .balign 64
3001.L_OP_SPUT_OBJECT: /* 0x69 */
3002/* File: armv5te/OP_SPUT_OBJECT.S */
3003    /*
3004     * 32-bit SPUT handler for objects
3005     *
3006     * for: sput-object, sput-object-volatile
3007     */
3008    /* op vAA, field@BBBB */
3009    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3010    FETCH(r1, 1)                        @ r1<- field ref BBBB
3011    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3012    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3013    cmp     r0, #0                      @ is resolved entry null?
3014    bne     .LOP_SPUT_OBJECT_finish          @ no, continue
3015    ldr     r9, [rGLUE, #offGlue_method]    @ r9<- current method
3016    EXPORT_PC()                         @ resolve() could throw, so export now
3017    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
3018    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
3019    cmp     r0, #0                      @ success?
3020    bne     .LOP_SPUT_OBJECT_finish          @ yes, finish
3021    b       common_exceptionThrown      @ no, handle exception
3022
3023
3024/* ------------------------------ */
3025    .balign 64
3026.L_OP_SPUT_BOOLEAN: /* 0x6a */
3027/* File: armv5te/OP_SPUT_BOOLEAN.S */
3028/* File: armv5te/OP_SPUT.S */
3029    /*
3030     * General 32-bit SPUT handler.
3031     *
3032     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3033     */
3034    /* op vAA, field@BBBB */
3035    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3036    FETCH(r1, 1)                        @ r1<- field ref BBBB
3037    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3038    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3039    cmp     r0, #0                      @ is resolved entry null?
3040    beq     .LOP_SPUT_BOOLEAN_resolve         @ yes, do resolve
3041.LOP_SPUT_BOOLEAN_finish:   @ field ptr in r0
3042    mov     r2, rINST, lsr #8           @ r2<- AA
3043    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3044    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3045    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3046    @ no-op                             @ releasing store
3047    str     r1, [r0, #offStaticField_value] @ field<- vAA
3048    GOTO_OPCODE(ip)                     @ jump to next instruction
3049
3050
3051/* ------------------------------ */
3052    .balign 64
3053.L_OP_SPUT_BYTE: /* 0x6b */
3054/* File: armv5te/OP_SPUT_BYTE.S */
3055/* File: armv5te/OP_SPUT.S */
3056    /*
3057     * General 32-bit SPUT handler.
3058     *
3059     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3060     */
3061    /* op vAA, field@BBBB */
3062    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3063    FETCH(r1, 1)                        @ r1<- field ref BBBB
3064    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3065    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3066    cmp     r0, #0                      @ is resolved entry null?
3067    beq     .LOP_SPUT_BYTE_resolve         @ yes, do resolve
3068.LOP_SPUT_BYTE_finish:   @ field ptr in r0
3069    mov     r2, rINST, lsr #8           @ r2<- AA
3070    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3071    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3072    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3073    @ no-op                             @ releasing store
3074    str     r1, [r0, #offStaticField_value] @ field<- vAA
3075    GOTO_OPCODE(ip)                     @ jump to next instruction
3076
3077
3078/* ------------------------------ */
3079    .balign 64
3080.L_OP_SPUT_CHAR: /* 0x6c */
3081/* File: armv5te/OP_SPUT_CHAR.S */
3082/* File: armv5te/OP_SPUT.S */
3083    /*
3084     * General 32-bit SPUT handler.
3085     *
3086     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3087     */
3088    /* op vAA, field@BBBB */
3089    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3090    FETCH(r1, 1)                        @ r1<- field ref BBBB
3091    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3092    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3093    cmp     r0, #0                      @ is resolved entry null?
3094    beq     .LOP_SPUT_CHAR_resolve         @ yes, do resolve
3095.LOP_SPUT_CHAR_finish:   @ field ptr in r0
3096    mov     r2, rINST, lsr #8           @ r2<- AA
3097    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3098    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3099    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3100    @ no-op                             @ releasing store
3101    str     r1, [r0, #offStaticField_value] @ field<- vAA
3102    GOTO_OPCODE(ip)                     @ jump to next instruction
3103
3104
3105/* ------------------------------ */
3106    .balign 64
3107.L_OP_SPUT_SHORT: /* 0x6d */
3108/* File: armv5te/OP_SPUT_SHORT.S */
3109/* File: armv5te/OP_SPUT.S */
3110    /*
3111     * General 32-bit SPUT handler.
3112     *
3113     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3114     */
3115    /* op vAA, field@BBBB */
3116    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
3117    FETCH(r1, 1)                        @ r1<- field ref BBBB
3118    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3119    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3120    cmp     r0, #0                      @ is resolved entry null?
3121    beq     .LOP_SPUT_SHORT_resolve         @ yes, do resolve
3122.LOP_SPUT_SHORT_finish:   @ field ptr in r0
3123    mov     r2, rINST, lsr #8           @ r2<- AA
3124    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3125    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3126    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3127    @ no-op                             @ releasing store
3128    str     r1, [r0, #offStaticField_value] @ field<- vAA
3129    GOTO_OPCODE(ip)                     @ jump to next instruction
3130
3131
3132/* ------------------------------ */
3133    .balign 64
3134.L_OP_INVOKE_VIRTUAL: /* 0x6e */
3135/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3136    /*
3137     * Handle a virtual method call.
3138     *
3139     * for: invoke-virtual, invoke-virtual/range
3140     */
3141    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3142    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3143    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3144    FETCH(r1, 1)                        @ r1<- BBBB
3145    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3146    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3147    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3148    .if     (!0)
3149    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3150    .endif
3151    cmp     r0, #0                      @ already resolved?
3152    EXPORT_PC()                         @ must export for invoke
3153    bne     .LOP_INVOKE_VIRTUAL_continue        @ yes, continue on
3154    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
3155    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3156    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3157    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3158    cmp     r0, #0                      @ got null?
3159    bne     .LOP_INVOKE_VIRTUAL_continue        @ no, continue
3160    b       common_exceptionThrown      @ yes, handle exception
3161
3162/* ------------------------------ */
3163    .balign 64
3164.L_OP_INVOKE_SUPER: /* 0x6f */
3165/* File: armv5te/OP_INVOKE_SUPER.S */
3166    /*
3167     * Handle a "super" method call.
3168     *
3169     * for: invoke-super, invoke-super/range
3170     */
3171    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3172    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3173    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3174    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3175    .if     (!0)
3176    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3177    .endif
3178    FETCH(r1, 1)                        @ r1<- BBBB
3179    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3180    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3181    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3182    cmp     r2, #0                      @ null "this"?
3183    ldr     r9, [rGLUE, #offGlue_method] @ r9<- current method
3184    beq     common_errNullObject        @ null "this", throw exception
3185    cmp     r0, #0                      @ already resolved?
3186    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
3187    EXPORT_PC()                         @ must export for invoke
3188    bne     .LOP_INVOKE_SUPER_continue        @ resolved, continue on
3189    b       .LOP_INVOKE_SUPER_resolve         @ do resolve now
3190
3191/* ------------------------------ */
3192    .balign 64
3193.L_OP_INVOKE_DIRECT: /* 0x70 */
3194/* File: armv5te/OP_INVOKE_DIRECT.S */
3195    /*
3196     * Handle a direct method call.
3197     *
3198     * (We could defer the "is 'this' pointer null" test to the common
3199     * method invocation code, and use a flag to indicate that static
3200     * calls don't count.  If we do this as part of copying the arguments
3201     * out we could avoiding loading the first arg twice.)
3202     *
3203     * for: invoke-direct, invoke-direct/range
3204     */
3205    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3206    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3207    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3208    FETCH(r1, 1)                        @ r1<- BBBB
3209    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3210    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3211    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3212    .if     (!0)
3213    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3214    .endif
3215    cmp     r0, #0                      @ already resolved?
3216    EXPORT_PC()                         @ must export for invoke
3217    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3218    beq     .LOP_INVOKE_DIRECT_resolve         @ not resolved, do it now
3219.LOP_INVOKE_DIRECT_finish:
3220    cmp     r2, #0                      @ null "this" ref?
3221    bne     common_invokeMethodNoRange   @ no, continue on
3222    b       common_errNullObject        @ yes, throw exception
3223
3224/* ------------------------------ */
3225    .balign 64
3226.L_OP_INVOKE_STATIC: /* 0x71 */
3227/* File: armv5te/OP_INVOKE_STATIC.S */
3228    /*
3229     * Handle a static method call.
3230     *
3231     * for: invoke-static, invoke-static/range
3232     */
3233    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3234    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3235    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3236    FETCH(r1, 1)                        @ r1<- BBBB
3237    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3238    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3239    cmp     r0, #0                      @ already resolved?
3240    EXPORT_PC()                         @ must export for invoke
3241    bne     common_invokeMethodNoRange @ yes, continue on
32420:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
3243    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3244    mov     r2, #METHOD_STATIC          @ resolver method type
3245    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3246    cmp     r0, #0                      @ got null?
3247    bne     common_invokeMethodNoRange @ no, continue
3248    b       common_exceptionThrown      @ yes, handle exception
3249
3250/* ------------------------------ */
3251    .balign 64
3252.L_OP_INVOKE_INTERFACE: /* 0x72 */
3253/* File: armv5te/OP_INVOKE_INTERFACE.S */
3254    /*
3255     * Handle an interface method call.
3256     *
3257     * for: invoke-interface, invoke-interface/range
3258     */
3259    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3260    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3261    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3262    FETCH(r1, 1)                        @ r1<- BBBB
3263    .if     (!0)
3264    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3265    .endif
3266    EXPORT_PC()                         @ must export for invoke
3267    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
3268    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- methodClassDex
3269    cmp     r0, #0                      @ null obj?
3270    ldr     r2, [rGLUE, #offGlue_method]  @ r2<- method
3271    beq     common_errNullObject        @ yes, fail
3272    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
3273    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3274    cmp     r0, #0                      @ failed?
3275    beq     common_exceptionThrown      @ yes, handle exception
3276    b       common_invokeMethodNoRange @ jump to common handler
3277
3278/* ------------------------------ */
3279    .balign 64
3280.L_OP_UNUSED_73: /* 0x73 */
3281/* File: armv5te/OP_UNUSED_73.S */
3282/* File: armv5te/unused.S */
3283    bl      common_abort
3284
3285
3286/* ------------------------------ */
3287    .balign 64
3288.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
3289/* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */
3290/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3291    /*
3292     * Handle a virtual method call.
3293     *
3294     * for: invoke-virtual, invoke-virtual/range
3295     */
3296    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3297    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3298    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3299    FETCH(r1, 1)                        @ r1<- BBBB
3300    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3301    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3302    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3303    .if     (!1)
3304    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3305    .endif
3306    cmp     r0, #0                      @ already resolved?
3307    EXPORT_PC()                         @ must export for invoke
3308    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ yes, continue on
3309    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
3310    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3311    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3312    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3313    cmp     r0, #0                      @ got null?
3314    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ no, continue
3315    b       common_exceptionThrown      @ yes, handle exception
3316
3317
3318/* ------------------------------ */
3319    .balign 64
3320.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */
3321/* File: armv5te/OP_INVOKE_SUPER_RANGE.S */
3322/* File: armv5te/OP_INVOKE_SUPER.S */
3323    /*
3324     * Handle a "super" method call.
3325     *
3326     * for: invoke-super, invoke-super/range
3327     */
3328    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3329    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3330    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3331    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3332    .if     (!1)
3333    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3334    .endif
3335    FETCH(r1, 1)                        @ r1<- BBBB
3336    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3337    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3338    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3339    cmp     r2, #0                      @ null "this"?
3340    ldr     r9, [rGLUE, #offGlue_method] @ r9<- current method
3341    beq     common_errNullObject        @ null "this", throw exception
3342    cmp     r0, #0                      @ already resolved?
3343    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
3344    EXPORT_PC()                         @ must export for invoke
3345    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ resolved, continue on
3346    b       .LOP_INVOKE_SUPER_RANGE_resolve         @ do resolve now
3347
3348
3349/* ------------------------------ */
3350    .balign 64
3351.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
3352/* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */
3353/* File: armv5te/OP_INVOKE_DIRECT.S */
3354    /*
3355     * Handle a direct method call.
3356     *
3357     * (We could defer the "is 'this' pointer null" test to the common
3358     * method invocation code, and use a flag to indicate that static
3359     * calls don't count.  If we do this as part of copying the arguments
3360     * out we could avoiding loading the first arg twice.)
3361     *
3362     * for: invoke-direct, invoke-direct/range
3363     */
3364    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3365    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3366    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3367    FETCH(r1, 1)                        @ r1<- BBBB
3368    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3369    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3370    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3371    .if     (!1)
3372    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3373    .endif
3374    cmp     r0, #0                      @ already resolved?
3375    EXPORT_PC()                         @ must export for invoke
3376    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3377    beq     .LOP_INVOKE_DIRECT_RANGE_resolve         @ not resolved, do it now
3378.LOP_INVOKE_DIRECT_RANGE_finish:
3379    cmp     r2, #0                      @ null "this" ref?
3380    bne     common_invokeMethodRange   @ no, continue on
3381    b       common_errNullObject        @ yes, throw exception
3382
3383
3384/* ------------------------------ */
3385    .balign 64
3386.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */
3387/* File: armv5te/OP_INVOKE_STATIC_RANGE.S */
3388/* File: armv5te/OP_INVOKE_STATIC.S */
3389    /*
3390     * Handle a static method call.
3391     *
3392     * for: invoke-static, invoke-static/range
3393     */
3394    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3395    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3396    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
3397    FETCH(r1, 1)                        @ r1<- BBBB
3398    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3399    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3400    cmp     r0, #0                      @ already resolved?
3401    EXPORT_PC()                         @ must export for invoke
3402    bne     common_invokeMethodRange @ yes, continue on
34030:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
3404    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3405    mov     r2, #METHOD_STATIC          @ resolver method type
3406    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3407    cmp     r0, #0                      @ got null?
3408    bne     common_invokeMethodRange @ no, continue
3409    b       common_exceptionThrown      @ yes, handle exception
3410
3411
3412/* ------------------------------ */
3413    .balign 64
3414.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
3415/* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */
3416/* File: armv5te/OP_INVOKE_INTERFACE.S */
3417    /*
3418     * Handle an interface method call.
3419     *
3420     * for: invoke-interface, invoke-interface/range
3421     */
3422    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3423    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3424    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3425    FETCH(r1, 1)                        @ r1<- BBBB
3426    .if     (!1)
3427    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3428    .endif
3429    EXPORT_PC()                         @ must export for invoke
3430    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
3431    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- methodClassDex
3432    cmp     r0, #0                      @ null obj?
3433    ldr     r2, [rGLUE, #offGlue_method]  @ r2<- method
3434    beq     common_errNullObject        @ yes, fail
3435    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
3436    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3437    cmp     r0, #0                      @ failed?
3438    beq     common_exceptionThrown      @ yes, handle exception
3439    b       common_invokeMethodRange @ jump to common handler
3440
3441
3442/* ------------------------------ */
3443    .balign 64
3444.L_OP_UNUSED_79: /* 0x79 */
3445/* File: armv5te/OP_UNUSED_79.S */
3446/* File: armv5te/unused.S */
3447    bl      common_abort
3448
3449
3450/* ------------------------------ */
3451    .balign 64
3452.L_OP_UNUSED_7A: /* 0x7a */
3453/* File: armv5te/OP_UNUSED_7A.S */
3454/* File: armv5te/unused.S */
3455    bl      common_abort
3456
3457
3458/* ------------------------------ */
3459    .balign 64
3460.L_OP_NEG_INT: /* 0x7b */
3461/* File: armv5te/OP_NEG_INT.S */
3462/* File: armv5te/unop.S */
3463    /*
3464     * Generic 32-bit unary operation.  Provide an "instr" line that
3465     * specifies an instruction that performs "result = op r0".
3466     * This could be an ARM instruction or a function call.
3467     *
3468     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3469     *      int-to-byte, int-to-char, int-to-short
3470     */
3471    /* unop vA, vB */
3472    mov     r3, rINST, lsr #12          @ r3<- B
3473    mov     r9, rINST, lsr #8           @ r9<- A+
3474    GET_VREG(r0, r3)                    @ r0<- vB
3475    and     r9, r9, #15
3476                               @ optional op; may set condition codes
3477    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3478    rsb     r0, r0, #0                              @ r0<- op, r0-r3 changed
3479    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3480    SET_VREG(r0, r9)                    @ vAA<- r0
3481    GOTO_OPCODE(ip)                     @ jump to next instruction
3482    /* 9-10 instructions */
3483
3484
3485/* ------------------------------ */
3486    .balign 64
3487.L_OP_NOT_INT: /* 0x7c */
3488/* File: armv5te/OP_NOT_INT.S */
3489/* File: armv5te/unop.S */
3490    /*
3491     * Generic 32-bit unary operation.  Provide an "instr" line that
3492     * specifies an instruction that performs "result = op r0".
3493     * This could be an ARM instruction or a function call.
3494     *
3495     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3496     *      int-to-byte, int-to-char, int-to-short
3497     */
3498    /* unop vA, vB */
3499    mov     r3, rINST, lsr #12          @ r3<- B
3500    mov     r9, rINST, lsr #8           @ r9<- A+
3501    GET_VREG(r0, r3)                    @ r0<- vB
3502    and     r9, r9, #15
3503                               @ optional op; may set condition codes
3504    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3505    mvn     r0, r0                              @ r0<- op, r0-r3 changed
3506    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3507    SET_VREG(r0, r9)                    @ vAA<- r0
3508    GOTO_OPCODE(ip)                     @ jump to next instruction
3509    /* 9-10 instructions */
3510
3511
3512/* ------------------------------ */
3513    .balign 64
3514.L_OP_NEG_LONG: /* 0x7d */
3515/* File: armv5te/OP_NEG_LONG.S */
3516/* File: armv5te/unopWide.S */
3517    /*
3518     * Generic 64-bit unary operation.  Provide an "instr" line that
3519     * specifies an instruction that performs "result = op r0/r1".
3520     * This could be an ARM instruction or a function call.
3521     *
3522     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3523     */
3524    /* unop vA, vB */
3525    mov     r9, rINST, lsr #8           @ r9<- A+
3526    mov     r3, rINST, lsr #12          @ r3<- B
3527    and     r9, r9, #15
3528    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3529    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3530    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3531    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3532    rsbs    r0, r0, #0                           @ optional op; may set condition codes
3533    rsc     r1, r1, #0                              @ r0/r1<- op, r2-r3 changed
3534    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3535    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3536    GOTO_OPCODE(ip)                     @ jump to next instruction
3537    /* 12-13 instructions */
3538
3539
3540/* ------------------------------ */
3541    .balign 64
3542.L_OP_NOT_LONG: /* 0x7e */
3543/* File: armv5te/OP_NOT_LONG.S */
3544/* File: armv5te/unopWide.S */
3545    /*
3546     * Generic 64-bit unary operation.  Provide an "instr" line that
3547     * specifies an instruction that performs "result = op r0/r1".
3548     * This could be an ARM instruction or a function call.
3549     *
3550     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3551     */
3552    /* unop vA, vB */
3553    mov     r9, rINST, lsr #8           @ r9<- A+
3554    mov     r3, rINST, lsr #12          @ r3<- B
3555    and     r9, r9, #15
3556    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3557    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3558    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3559    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3560    mvn     r0, r0                           @ optional op; may set condition codes
3561    mvn     r1, r1                              @ r0/r1<- op, r2-r3 changed
3562    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3563    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3564    GOTO_OPCODE(ip)                     @ jump to next instruction
3565    /* 12-13 instructions */
3566
3567
3568/* ------------------------------ */
3569    .balign 64
3570.L_OP_NEG_FLOAT: /* 0x7f */
3571/* File: armv5te/OP_NEG_FLOAT.S */
3572/* File: armv5te/unop.S */
3573    /*
3574     * Generic 32-bit unary operation.  Provide an "instr" line that
3575     * specifies an instruction that performs "result = op r0".
3576     * This could be an ARM instruction or a function call.
3577     *
3578     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3579     *      int-to-byte, int-to-char, int-to-short
3580     */
3581    /* unop vA, vB */
3582    mov     r3, rINST, lsr #12          @ r3<- B
3583    mov     r9, rINST, lsr #8           @ r9<- A+
3584    GET_VREG(r0, r3)                    @ r0<- vB
3585    and     r9, r9, #15
3586                               @ optional op; may set condition codes
3587    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3588    add     r0, r0, #0x80000000                              @ r0<- op, r0-r3 changed
3589    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3590    SET_VREG(r0, r9)                    @ vAA<- r0
3591    GOTO_OPCODE(ip)                     @ jump to next instruction
3592    /* 9-10 instructions */
3593
3594
3595/* ------------------------------ */
3596    .balign 64
3597.L_OP_NEG_DOUBLE: /* 0x80 */
3598/* File: armv5te/OP_NEG_DOUBLE.S */
3599/* File: armv5te/unopWide.S */
3600    /*
3601     * Generic 64-bit unary operation.  Provide an "instr" line that
3602     * specifies an instruction that performs "result = op r0/r1".
3603     * This could be an ARM instruction or a function call.
3604     *
3605     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3606     */
3607    /* unop vA, vB */
3608    mov     r9, rINST, lsr #8           @ r9<- A+
3609    mov     r3, rINST, lsr #12          @ r3<- B
3610    and     r9, r9, #15
3611    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3612    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3613    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3614    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3615                               @ optional op; may set condition codes
3616    add     r1, r1, #0x80000000                              @ r0/r1<- op, r2-r3 changed
3617    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3618    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3619    GOTO_OPCODE(ip)                     @ jump to next instruction
3620    /* 12-13 instructions */
3621
3622
3623/* ------------------------------ */
3624    .balign 64
3625.L_OP_INT_TO_LONG: /* 0x81 */
3626/* File: armv5te/OP_INT_TO_LONG.S */
3627/* File: armv5te/unopWider.S */
3628    /*
3629     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3630     * that specifies an instruction that performs "result = op r0", where
3631     * "result" is a 64-bit quantity in r0/r1.
3632     *
3633     * For: int-to-long, int-to-double, float-to-long, float-to-double
3634     */
3635    /* unop vA, vB */
3636    mov     r9, rINST, lsr #8           @ r9<- A+
3637    mov     r3, rINST, lsr #12          @ r3<- B
3638    and     r9, r9, #15
3639    GET_VREG(r0, r3)                    @ r0<- vB
3640    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3641                               @ optional op; may set condition codes
3642    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3643    mov     r1, r0, asr #31                              @ r0<- op, r0-r3 changed
3644    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3645    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3646    GOTO_OPCODE(ip)                     @ jump to next instruction
3647    /* 10-11 instructions */
3648
3649
3650/* ------------------------------ */
3651    .balign 64
3652.L_OP_INT_TO_FLOAT: /* 0x82 */
3653/* File: arm-vfp/OP_INT_TO_FLOAT.S */
3654/* File: arm-vfp/funop.S */
3655    /*
3656     * Generic 32-bit unary floating-point operation.  Provide an "instr"
3657     * line that specifies an instruction that performs "s1 = op s0".
3658     *
3659     * for: int-to-float, float-to-int
3660     */
3661    /* unop vA, vB */
3662    mov     r3, rINST, lsr #12          @ r3<- B
3663    mov     r9, rINST, lsr #8           @ r9<- A+
3664    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3665    flds    s0, [r3]                    @ s0<- vB
3666    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3667    and     r9, r9, #15                 @ r9<- A
3668    fsitos  s1, s0                              @ s1<- op
3669    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3670    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3671    fsts    s1, [r9]                    @ vA<- s1
3672    GOTO_OPCODE(ip)                     @ jump to next instruction
3673
3674
3675/* ------------------------------ */
3676    .balign 64
3677.L_OP_INT_TO_DOUBLE: /* 0x83 */
3678/* File: arm-vfp/OP_INT_TO_DOUBLE.S */
3679/* File: arm-vfp/funopWider.S */
3680    /*
3681     * Generic 32bit-to-64bit floating point unary operation.  Provide an
3682     * "instr" line that specifies an instruction that performs "d0 = op s0".
3683     *
3684     * For: int-to-double, float-to-double
3685     */
3686    /* unop vA, vB */
3687    mov     r3, rINST, lsr #12          @ r3<- B
3688    mov     r9, rINST, lsr #8           @ r9<- A+
3689    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3690    flds    s0, [r3]                    @ s0<- vB
3691    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3692    and     r9, r9, #15                 @ r9<- A
3693    fsitod  d0, s0                              @ d0<- op
3694    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3695    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3696    fstd    d0, [r9]                    @ vA<- d0
3697    GOTO_OPCODE(ip)                     @ jump to next instruction
3698
3699
3700/* ------------------------------ */
3701    .balign 64
3702.L_OP_LONG_TO_INT: /* 0x84 */
3703/* File: armv5te/OP_LONG_TO_INT.S */
3704/* we ignore the high word, making this equivalent to a 32-bit reg move */
3705/* File: armv5te/OP_MOVE.S */
3706    /* for move, move-object, long-to-int */
3707    /* op vA, vB */
3708    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
3709    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
3710    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3711    GET_VREG(r2, r1)                    @ r2<- fp[B]
3712    and     r0, r0, #15
3713    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
3714    SET_VREG(r2, r0)                    @ fp[A]<- r2
3715    GOTO_OPCODE(ip)                     @ execute next instruction
3716
3717
3718/* ------------------------------ */
3719    .balign 64
3720.L_OP_LONG_TO_FLOAT: /* 0x85 */
3721/* File: armv5te/OP_LONG_TO_FLOAT.S */
3722/* File: armv5te/unopNarrower.S */
3723    /*
3724     * Generic 64bit-to-32bit unary operation.  Provide an "instr" line
3725     * that specifies an instruction that performs "result = op r0/r1", where
3726     * "result" is a 32-bit quantity in r0.
3727     *
3728     * For: long-to-float, double-to-int, double-to-float
3729     *
3730     * (This would work for long-to-int, but that instruction is actually
3731     * an exact match for OP_MOVE.)
3732     */
3733    /* unop vA, vB */
3734    mov     r3, rINST, lsr #12          @ r3<- B
3735    mov     r9, rINST, lsr #8           @ r9<- A+
3736    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3737    and     r9, r9, #15
3738    ldmia   r3, {r0-r1}                 @ r0/r1<- vB/vB+1
3739    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3740                               @ optional op; may set condition codes
3741    bl      __aeabi_l2f                              @ r0<- op, r0-r3 changed
3742    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3743    SET_VREG(r0, r9)                    @ vA<- r0
3744    GOTO_OPCODE(ip)                     @ jump to next instruction
3745    /* 10-11 instructions */
3746
3747
3748/* ------------------------------ */
3749    .balign 64
3750.L_OP_LONG_TO_DOUBLE: /* 0x86 */
3751/* File: armv5te/OP_LONG_TO_DOUBLE.S */
3752/* File: armv5te/unopWide.S */
3753    /*
3754     * Generic 64-bit unary operation.  Provide an "instr" line that
3755     * specifies an instruction that performs "result = op r0/r1".
3756     * This could be an ARM instruction or a function call.
3757     *
3758     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3759     */
3760    /* unop vA, vB */
3761    mov     r9, rINST, lsr #8           @ r9<- A+
3762    mov     r3, rINST, lsr #12          @ r3<- B
3763    and     r9, r9, #15
3764    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3765    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3766    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3767    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3768                               @ optional op; may set condition codes
3769    bl      __aeabi_l2d                              @ r0/r1<- op, r2-r3 changed
3770    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3771    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3772    GOTO_OPCODE(ip)                     @ jump to next instruction
3773    /* 12-13 instructions */
3774
3775
3776/* ------------------------------ */
3777    .balign 64
3778.L_OP_FLOAT_TO_INT: /* 0x87 */
3779/* File: arm-vfp/OP_FLOAT_TO_INT.S */
3780/* File: arm-vfp/funop.S */
3781    /*
3782     * Generic 32-bit unary floating-point operation.  Provide an "instr"
3783     * line that specifies an instruction that performs "s1 = op s0".
3784     *
3785     * for: int-to-float, float-to-int
3786     */
3787    /* unop vA, vB */
3788    mov     r3, rINST, lsr #12          @ r3<- B
3789    mov     r9, rINST, lsr #8           @ r9<- A+
3790    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3791    flds    s0, [r3]                    @ s0<- vB
3792    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3793    and     r9, r9, #15                 @ r9<- A
3794    ftosizs s1, s0                              @ s1<- op
3795    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3796    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3797    fsts    s1, [r9]                    @ vA<- s1
3798    GOTO_OPCODE(ip)                     @ jump to next instruction
3799
3800
3801/* ------------------------------ */
3802    .balign 64
3803.L_OP_FLOAT_TO_LONG: /* 0x88 */
3804/* File: armv5te/OP_FLOAT_TO_LONG.S */
3805@include "armv5te/unopWider.S" {"instr":"bl      __aeabi_f2lz"}
3806/* File: armv5te/unopWider.S */
3807    /*
3808     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3809     * that specifies an instruction that performs "result = op r0", where
3810     * "result" is a 64-bit quantity in r0/r1.
3811     *
3812     * For: int-to-long, int-to-double, float-to-long, float-to-double
3813     */
3814    /* unop vA, vB */
3815    mov     r9, rINST, lsr #8           @ r9<- A+
3816    mov     r3, rINST, lsr #12          @ r3<- B
3817    and     r9, r9, #15
3818    GET_VREG(r0, r3)                    @ r0<- vB
3819    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3820                               @ optional op; may set condition codes
3821    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3822    bl      f2l_doconv                              @ r0<- op, r0-r3 changed
3823    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3824    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3825    GOTO_OPCODE(ip)                     @ jump to next instruction
3826    /* 10-11 instructions */
3827
3828
3829
3830/* ------------------------------ */
3831    .balign 64
3832.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */
3833/* File: arm-vfp/OP_FLOAT_TO_DOUBLE.S */
3834/* File: arm-vfp/funopWider.S */
3835    /*
3836     * Generic 32bit-to-64bit floating point unary operation.  Provide an
3837     * "instr" line that specifies an instruction that performs "d0 = op s0".
3838     *
3839     * For: int-to-double, float-to-double
3840     */
3841    /* unop vA, vB */
3842    mov     r3, rINST, lsr #12          @ r3<- B
3843    mov     r9, rINST, lsr #8           @ r9<- A+
3844    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3845    flds    s0, [r3]                    @ s0<- vB
3846    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3847    and     r9, r9, #15                 @ r9<- A
3848    fcvtds  d0, s0                              @ d0<- op
3849    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3850    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3851    fstd    d0, [r9]                    @ vA<- d0
3852    GOTO_OPCODE(ip)                     @ jump to next instruction
3853
3854
3855/* ------------------------------ */
3856    .balign 64
3857.L_OP_DOUBLE_TO_INT: /* 0x8a */
3858/* File: arm-vfp/OP_DOUBLE_TO_INT.S */
3859/* File: arm-vfp/funopNarrower.S */
3860    /*
3861     * Generic 64bit-to-32bit unary floating point operation.  Provide an
3862     * "instr" line that specifies an instruction that performs "s0 = op d0".
3863     *
3864     * For: double-to-int, double-to-float
3865     */
3866    /* unop vA, vB */
3867    mov     r3, rINST, lsr #12          @ r3<- B
3868    mov     r9, rINST, lsr #8           @ r9<- A+
3869    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3870    fldd    d0, [r3]                    @ d0<- vB
3871    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3872    and     r9, r9, #15                 @ r9<- A
3873    ftosizd  s0, d0                              @ s0<- op
3874    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3875    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3876    fsts    s0, [r9]                    @ vA<- s0
3877    GOTO_OPCODE(ip)                     @ jump to next instruction
3878
3879
3880/* ------------------------------ */
3881    .balign 64
3882.L_OP_DOUBLE_TO_LONG: /* 0x8b */
3883/* File: armv5te/OP_DOUBLE_TO_LONG.S */
3884@include "armv5te/unopWide.S" {"instr":"bl      __aeabi_d2lz"}
3885/* File: armv5te/unopWide.S */
3886    /*
3887     * Generic 64-bit unary operation.  Provide an "instr" line that
3888     * specifies an instruction that performs "result = op r0/r1".
3889     * This could be an ARM instruction or a function call.
3890     *
3891     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3892     */
3893    /* unop vA, vB */
3894    mov     r9, rINST, lsr #8           @ r9<- A+
3895    mov     r3, rINST, lsr #12          @ r3<- B
3896    and     r9, r9, #15
3897    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3898    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3899    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3900    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3901                               @ optional op; may set condition codes
3902    bl      d2l_doconv                              @ r0/r1<- op, r2-r3 changed
3903    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3904    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3905    GOTO_OPCODE(ip)                     @ jump to next instruction
3906    /* 12-13 instructions */
3907
3908
3909
3910/* ------------------------------ */
3911    .balign 64
3912.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */
3913/* File: arm-vfp/OP_DOUBLE_TO_FLOAT.S */
3914/* File: arm-vfp/funopNarrower.S */
3915    /*
3916     * Generic 64bit-to-32bit unary floating point operation.  Provide an
3917     * "instr" line that specifies an instruction that performs "s0 = op d0".
3918     *
3919     * For: double-to-int, double-to-float
3920     */
3921    /* unop vA, vB */
3922    mov     r3, rINST, lsr #12          @ r3<- B
3923    mov     r9, rINST, lsr #8           @ r9<- A+
3924    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3925    fldd    d0, [r3]                    @ d0<- vB
3926    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3927    and     r9, r9, #15                 @ r9<- A
3928    fcvtsd  s0, d0                              @ s0<- op
3929    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3930    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3931    fsts    s0, [r9]                    @ vA<- s0
3932    GOTO_OPCODE(ip)                     @ jump to next instruction
3933
3934
3935/* ------------------------------ */
3936    .balign 64
3937.L_OP_INT_TO_BYTE: /* 0x8d */
3938/* File: armv5te/OP_INT_TO_BYTE.S */
3939/* File: armv5te/unop.S */
3940    /*
3941     * Generic 32-bit unary operation.  Provide an "instr" line that
3942     * specifies an instruction that performs "result = op r0".
3943     * This could be an ARM instruction or a function call.
3944     *
3945     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3946     *      int-to-byte, int-to-char, int-to-short
3947     */
3948    /* unop vA, vB */
3949    mov     r3, rINST, lsr #12          @ r3<- B
3950    mov     r9, rINST, lsr #8           @ r9<- A+
3951    GET_VREG(r0, r3)                    @ r0<- vB
3952    and     r9, r9, #15
3953    mov     r0, r0, asl #24                           @ optional op; may set condition codes
3954    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3955    mov     r0, r0, asr #24                              @ r0<- op, r0-r3 changed
3956    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3957    SET_VREG(r0, r9)                    @ vAA<- r0
3958    GOTO_OPCODE(ip)                     @ jump to next instruction
3959    /* 9-10 instructions */
3960
3961
3962/* ------------------------------ */
3963    .balign 64
3964.L_OP_INT_TO_CHAR: /* 0x8e */
3965/* File: armv5te/OP_INT_TO_CHAR.S */
3966/* File: armv5te/unop.S */
3967    /*
3968     * Generic 32-bit unary operation.  Provide an "instr" line that
3969     * specifies an instruction that performs "result = op r0".
3970     * This could be an ARM instruction or a function call.
3971     *
3972     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3973     *      int-to-byte, int-to-char, int-to-short
3974     */
3975    /* unop vA, vB */
3976    mov     r3, rINST, lsr #12          @ r3<- B
3977    mov     r9, rINST, lsr #8           @ r9<- A+
3978    GET_VREG(r0, r3)                    @ r0<- vB
3979    and     r9, r9, #15
3980    mov     r0, r0, asl #16                           @ optional op; may set condition codes
3981    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3982    mov     r0, r0, lsr #16                              @ r0<- op, r0-r3 changed
3983    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3984    SET_VREG(r0, r9)                    @ vAA<- r0
3985    GOTO_OPCODE(ip)                     @ jump to next instruction
3986    /* 9-10 instructions */
3987
3988
3989/* ------------------------------ */
3990    .balign 64
3991.L_OP_INT_TO_SHORT: /* 0x8f */
3992/* File: armv5te/OP_INT_TO_SHORT.S */
3993/* File: armv5te/unop.S */
3994    /*
3995     * Generic 32-bit unary operation.  Provide an "instr" line that
3996     * specifies an instruction that performs "result = op r0".
3997     * This could be an ARM instruction or a function call.
3998     *
3999     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
4000     *      int-to-byte, int-to-char, int-to-short
4001     */
4002    /* unop vA, vB */
4003    mov     r3, rINST, lsr #12          @ r3<- B
4004    mov     r9, rINST, lsr #8           @ r9<- A+
4005    GET_VREG(r0, r3)                    @ r0<- vB
4006    and     r9, r9, #15
4007    mov     r0, r0, asl #16                           @ optional op; may set condition codes
4008    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
4009    mov     r0, r0, asr #16                              @ r0<- op, r0-r3 changed
4010    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4011    SET_VREG(r0, r9)                    @ vAA<- r0
4012    GOTO_OPCODE(ip)                     @ jump to next instruction
4013    /* 9-10 instructions */
4014
4015
4016/* ------------------------------ */
4017    .balign 64
4018.L_OP_ADD_INT: /* 0x90 */
4019/* File: armv5te/OP_ADD_INT.S */
4020/* File: armv5te/binop.S */
4021    /*
4022     * Generic 32-bit binary operation.  Provide an "instr" line that
4023     * specifies an instruction that performs "result = r0 op r1".
4024     * This could be an ARM instruction or a function call.  (If the result
4025     * comes back in a register other than r0, you can override "result".)
4026     *
4027     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4028     * vCC (r1).  Useful for integer division and modulus.  Note that we
4029     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4030     * handles it correctly.
4031     *
4032     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4033     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4034     *      mul-float, div-float, rem-float
4035     */
4036    /* binop vAA, vBB, vCC */
4037    FETCH(r0, 1)                        @ r0<- CCBB
4038    mov     r9, rINST, lsr #8           @ r9<- AA
4039    mov     r3, r0, lsr #8              @ r3<- CC
4040    and     r2, r0, #255                @ r2<- BB
4041    GET_VREG(r1, r3)                    @ r1<- vCC
4042    GET_VREG(r0, r2)                    @ r0<- vBB
4043    .if 0
4044    cmp     r1, #0                      @ is second operand zero?
4045    beq     common_errDivideByZero
4046    .endif
4047
4048    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4049                               @ optional op; may set condition codes
4050    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
4051    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4052    SET_VREG(r0, r9)               @ vAA<- r0
4053    GOTO_OPCODE(ip)                     @ jump to next instruction
4054    /* 11-14 instructions */
4055
4056
4057/* ------------------------------ */
4058    .balign 64
4059.L_OP_SUB_INT: /* 0x91 */
4060/* File: armv5te/OP_SUB_INT.S */
4061/* File: armv5te/binop.S */
4062    /*
4063     * Generic 32-bit binary operation.  Provide an "instr" line that
4064     * specifies an instruction that performs "result = r0 op r1".
4065     * This could be an ARM instruction or a function call.  (If the result
4066     * comes back in a register other than r0, you can override "result".)
4067     *
4068     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4069     * vCC (r1).  Useful for integer division and modulus.  Note that we
4070     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4071     * handles it correctly.
4072     *
4073     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4074     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4075     *      mul-float, div-float, rem-float
4076     */
4077    /* binop vAA, vBB, vCC */
4078    FETCH(r0, 1)                        @ r0<- CCBB
4079    mov     r9, rINST, lsr #8           @ r9<- AA
4080    mov     r3, r0, lsr #8              @ r3<- CC
4081    and     r2, r0, #255                @ r2<- BB
4082    GET_VREG(r1, r3)                    @ r1<- vCC
4083    GET_VREG(r0, r2)                    @ r0<- vBB
4084    .if 0
4085    cmp     r1, #0                      @ is second operand zero?
4086    beq     common_errDivideByZero
4087    .endif
4088
4089    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4090                               @ optional op; may set condition codes
4091    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
4092    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4093    SET_VREG(r0, r9)               @ vAA<- r0
4094    GOTO_OPCODE(ip)                     @ jump to next instruction
4095    /* 11-14 instructions */
4096
4097
4098/* ------------------------------ */
4099    .balign 64
4100.L_OP_MUL_INT: /* 0x92 */
4101/* File: armv5te/OP_MUL_INT.S */
4102/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
4103/* File: armv5te/binop.S */
4104    /*
4105     * Generic 32-bit binary operation.  Provide an "instr" line that
4106     * specifies an instruction that performs "result = r0 op r1".
4107     * This could be an ARM instruction or a function call.  (If the result
4108     * comes back in a register other than r0, you can override "result".)
4109     *
4110     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4111     * vCC (r1).  Useful for integer division and modulus.  Note that we
4112     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4113     * handles it correctly.
4114     *
4115     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4116     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4117     *      mul-float, div-float, rem-float
4118     */
4119    /* binop vAA, vBB, vCC */
4120    FETCH(r0, 1)                        @ r0<- CCBB
4121    mov     r9, rINST, lsr #8           @ r9<- AA
4122    mov     r3, r0, lsr #8              @ r3<- CC
4123    and     r2, r0, #255                @ r2<- BB
4124    GET_VREG(r1, r3)                    @ r1<- vCC
4125    GET_VREG(r0, r2)                    @ r0<- vBB
4126    .if 0
4127    cmp     r1, #0                      @ is second operand zero?
4128    beq     common_errDivideByZero
4129    .endif
4130
4131    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4132                               @ optional op; may set condition codes
4133    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
4134    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4135    SET_VREG(r0, r9)               @ vAA<- r0
4136    GOTO_OPCODE(ip)                     @ jump to next instruction
4137    /* 11-14 instructions */
4138
4139
4140/* ------------------------------ */
4141    .balign 64
4142.L_OP_DIV_INT: /* 0x93 */
4143/* File: armv5te/OP_DIV_INT.S */
4144/* File: armv5te/binop.S */
4145    /*
4146     * Generic 32-bit binary operation.  Provide an "instr" line that
4147     * specifies an instruction that performs "result = r0 op r1".
4148     * This could be an ARM instruction or a function call.  (If the result
4149     * comes back in a register other than r0, you can override "result".)
4150     *
4151     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4152     * vCC (r1).  Useful for integer division and modulus.  Note that we
4153     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4154     * handles it correctly.
4155     *
4156     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4157     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4158     *      mul-float, div-float, rem-float
4159     */
4160    /* binop vAA, vBB, vCC */
4161    FETCH(r0, 1)                        @ r0<- CCBB
4162    mov     r9, rINST, lsr #8           @ r9<- AA
4163    mov     r3, r0, lsr #8              @ r3<- CC
4164    and     r2, r0, #255                @ r2<- BB
4165    GET_VREG(r1, r3)                    @ r1<- vCC
4166    GET_VREG(r0, r2)                    @ r0<- vBB
4167    .if 1
4168    cmp     r1, #0                      @ is second operand zero?
4169    beq     common_errDivideByZero
4170    .endif
4171
4172    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4173                               @ optional op; may set condition codes
4174    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
4175    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4176    SET_VREG(r0, r9)               @ vAA<- r0
4177    GOTO_OPCODE(ip)                     @ jump to next instruction
4178    /* 11-14 instructions */
4179
4180
4181/* ------------------------------ */
4182    .balign 64
4183.L_OP_REM_INT: /* 0x94 */
4184/* File: armv5te/OP_REM_INT.S */
4185/* idivmod returns quotient in r0 and remainder in r1 */
4186/* File: armv5te/binop.S */
4187    /*
4188     * Generic 32-bit binary operation.  Provide an "instr" line that
4189     * specifies an instruction that performs "result = r0 op r1".
4190     * This could be an ARM instruction or a function call.  (If the result
4191     * comes back in a register other than r0, you can override "result".)
4192     *
4193     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4194     * vCC (r1).  Useful for integer division and modulus.  Note that we
4195     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4196     * handles it correctly.
4197     *
4198     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4199     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4200     *      mul-float, div-float, rem-float
4201     */
4202    /* binop vAA, vBB, vCC */
4203    FETCH(r0, 1)                        @ r0<- CCBB
4204    mov     r9, rINST, lsr #8           @ r9<- AA
4205    mov     r3, r0, lsr #8              @ r3<- CC
4206    and     r2, r0, #255                @ r2<- BB
4207    GET_VREG(r1, r3)                    @ r1<- vCC
4208    GET_VREG(r0, r2)                    @ r0<- vBB
4209    .if 1
4210    cmp     r1, #0                      @ is second operand zero?
4211    beq     common_errDivideByZero
4212    .endif
4213
4214    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4215                               @ optional op; may set condition codes
4216    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
4217    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4218    SET_VREG(r1, r9)               @ vAA<- r1
4219    GOTO_OPCODE(ip)                     @ jump to next instruction
4220    /* 11-14 instructions */
4221
4222
4223/* ------------------------------ */
4224    .balign 64
4225.L_OP_AND_INT: /* 0x95 */
4226/* File: armv5te/OP_AND_INT.S */
4227/* File: armv5te/binop.S */
4228    /*
4229     * Generic 32-bit binary operation.  Provide an "instr" line that
4230     * specifies an instruction that performs "result = r0 op r1".
4231     * This could be an ARM instruction or a function call.  (If the result
4232     * comes back in a register other than r0, you can override "result".)
4233     *
4234     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4235     * vCC (r1).  Useful for integer division and modulus.  Note that we
4236     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4237     * handles it correctly.
4238     *
4239     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4240     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4241     *      mul-float, div-float, rem-float
4242     */
4243    /* binop vAA, vBB, vCC */
4244    FETCH(r0, 1)                        @ r0<- CCBB
4245    mov     r9, rINST, lsr #8           @ r9<- AA
4246    mov     r3, r0, lsr #8              @ r3<- CC
4247    and     r2, r0, #255                @ r2<- BB
4248    GET_VREG(r1, r3)                    @ r1<- vCC
4249    GET_VREG(r0, r2)                    @ r0<- vBB
4250    .if 0
4251    cmp     r1, #0                      @ is second operand zero?
4252    beq     common_errDivideByZero
4253    .endif
4254
4255    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4256                               @ optional op; may set condition codes
4257    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
4258    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4259    SET_VREG(r0, r9)               @ vAA<- r0
4260    GOTO_OPCODE(ip)                     @ jump to next instruction
4261    /* 11-14 instructions */
4262
4263
4264/* ------------------------------ */
4265    .balign 64
4266.L_OP_OR_INT: /* 0x96 */
4267/* File: armv5te/OP_OR_INT.S */
4268/* File: armv5te/binop.S */
4269    /*
4270     * Generic 32-bit binary operation.  Provide an "instr" line that
4271     * specifies an instruction that performs "result = r0 op r1".
4272     * This could be an ARM instruction or a function call.  (If the result
4273     * comes back in a register other than r0, you can override "result".)
4274     *
4275     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4276     * vCC (r1).  Useful for integer division and modulus.  Note that we
4277     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4278     * handles it correctly.
4279     *
4280     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4281     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4282     *      mul-float, div-float, rem-float
4283     */
4284    /* binop vAA, vBB, vCC */
4285    FETCH(r0, 1)                        @ r0<- CCBB
4286    mov     r9, rINST, lsr #8           @ r9<- AA
4287    mov     r3, r0, lsr #8              @ r3<- CC
4288    and     r2, r0, #255                @ r2<- BB
4289    GET_VREG(r1, r3)                    @ r1<- vCC
4290    GET_VREG(r0, r2)                    @ r0<- vBB
4291    .if 0
4292    cmp     r1, #0                      @ is second operand zero?
4293    beq     common_errDivideByZero
4294    .endif
4295
4296    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4297                               @ optional op; may set condition codes
4298    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
4299    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4300    SET_VREG(r0, r9)               @ vAA<- r0
4301    GOTO_OPCODE(ip)                     @ jump to next instruction
4302    /* 11-14 instructions */
4303
4304
4305/* ------------------------------ */
4306    .balign 64
4307.L_OP_XOR_INT: /* 0x97 */
4308/* File: armv5te/OP_XOR_INT.S */
4309/* File: armv5te/binop.S */
4310    /*
4311     * Generic 32-bit binary operation.  Provide an "instr" line that
4312     * specifies an instruction that performs "result = r0 op r1".
4313     * This could be an ARM instruction or a function call.  (If the result
4314     * comes back in a register other than r0, you can override "result".)
4315     *
4316     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4317     * vCC (r1).  Useful for integer division and modulus.  Note that we
4318     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4319     * handles it correctly.
4320     *
4321     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4322     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4323     *      mul-float, div-float, rem-float
4324     */
4325    /* binop vAA, vBB, vCC */
4326    FETCH(r0, 1)                        @ r0<- CCBB
4327    mov     r9, rINST, lsr #8           @ r9<- AA
4328    mov     r3, r0, lsr #8              @ r3<- CC
4329    and     r2, r0, #255                @ r2<- BB
4330    GET_VREG(r1, r3)                    @ r1<- vCC
4331    GET_VREG(r0, r2)                    @ r0<- vBB
4332    .if 0
4333    cmp     r1, #0                      @ is second operand zero?
4334    beq     common_errDivideByZero
4335    .endif
4336
4337    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4338                               @ optional op; may set condition codes
4339    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
4340    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4341    SET_VREG(r0, r9)               @ vAA<- r0
4342    GOTO_OPCODE(ip)                     @ jump to next instruction
4343    /* 11-14 instructions */
4344
4345
4346/* ------------------------------ */
4347    .balign 64
4348.L_OP_SHL_INT: /* 0x98 */
4349/* File: armv5te/OP_SHL_INT.S */
4350/* File: armv5te/binop.S */
4351    /*
4352     * Generic 32-bit binary operation.  Provide an "instr" line that
4353     * specifies an instruction that performs "result = r0 op r1".
4354     * This could be an ARM instruction or a function call.  (If the result
4355     * comes back in a register other than r0, you can override "result".)
4356     *
4357     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4358     * vCC (r1).  Useful for integer division and modulus.  Note that we
4359     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4360     * handles it correctly.
4361     *
4362     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4363     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4364     *      mul-float, div-float, rem-float
4365     */
4366    /* binop vAA, vBB, vCC */
4367    FETCH(r0, 1)                        @ r0<- CCBB
4368    mov     r9, rINST, lsr #8           @ r9<- AA
4369    mov     r3, r0, lsr #8              @ r3<- CC
4370    and     r2, r0, #255                @ r2<- BB
4371    GET_VREG(r1, r3)                    @ r1<- vCC
4372    GET_VREG(r0, r2)                    @ r0<- vBB
4373    .if 0
4374    cmp     r1, #0                      @ is second operand zero?
4375    beq     common_errDivideByZero
4376    .endif
4377
4378    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4379    and     r1, r1, #31                           @ optional op; may set condition codes
4380    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
4381    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4382    SET_VREG(r0, r9)               @ vAA<- r0
4383    GOTO_OPCODE(ip)                     @ jump to next instruction
4384    /* 11-14 instructions */
4385
4386
4387/* ------------------------------ */
4388    .balign 64
4389.L_OP_SHR_INT: /* 0x99 */
4390/* File: armv5te/OP_SHR_INT.S */
4391/* File: armv5te/binop.S */
4392    /*
4393     * Generic 32-bit binary operation.  Provide an "instr" line that
4394     * specifies an instruction that performs "result = r0 op r1".
4395     * This could be an ARM instruction or a function call.  (If the result
4396     * comes back in a register other than r0, you can override "result".)
4397     *
4398     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4399     * vCC (r1).  Useful for integer division and modulus.  Note that we
4400     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4401     * handles it correctly.
4402     *
4403     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4404     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4405     *      mul-float, div-float, rem-float
4406     */
4407    /* binop vAA, vBB, vCC */
4408    FETCH(r0, 1)                        @ r0<- CCBB
4409    mov     r9, rINST, lsr #8           @ r9<- AA
4410    mov     r3, r0, lsr #8              @ r3<- CC
4411    and     r2, r0, #255                @ r2<- BB
4412    GET_VREG(r1, r3)                    @ r1<- vCC
4413    GET_VREG(r0, r2)                    @ r0<- vBB
4414    .if 0
4415    cmp     r1, #0                      @ is second operand zero?
4416    beq     common_errDivideByZero
4417    .endif
4418
4419    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4420    and     r1, r1, #31                           @ optional op; may set condition codes
4421    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
4422    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4423    SET_VREG(r0, r9)               @ vAA<- r0
4424    GOTO_OPCODE(ip)                     @ jump to next instruction
4425    /* 11-14 instructions */
4426
4427
4428/* ------------------------------ */
4429    .balign 64
4430.L_OP_USHR_INT: /* 0x9a */
4431/* File: armv5te/OP_USHR_INT.S */
4432/* File: armv5te/binop.S */
4433    /*
4434     * Generic 32-bit binary operation.  Provide an "instr" line that
4435     * specifies an instruction that performs "result = r0 op r1".
4436     * This could be an ARM instruction or a function call.  (If the result
4437     * comes back in a register other than r0, you can override "result".)
4438     *
4439     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4440     * vCC (r1).  Useful for integer division and modulus.  Note that we
4441     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4442     * handles it correctly.
4443     *
4444     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4445     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4446     *      mul-float, div-float, rem-float
4447     */
4448    /* binop vAA, vBB, vCC */
4449    FETCH(r0, 1)                        @ r0<- CCBB
4450    mov     r9, rINST, lsr #8           @ r9<- AA
4451    mov     r3, r0, lsr #8              @ r3<- CC
4452    and     r2, r0, #255                @ r2<- BB
4453    GET_VREG(r1, r3)                    @ r1<- vCC
4454    GET_VREG(r0, r2)                    @ r0<- vBB
4455    .if 0
4456    cmp     r1, #0                      @ is second operand zero?
4457    beq     common_errDivideByZero
4458    .endif
4459
4460    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4461    and     r1, r1, #31                           @ optional op; may set condition codes
4462    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
4463    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4464    SET_VREG(r0, r9)               @ vAA<- r0
4465    GOTO_OPCODE(ip)                     @ jump to next instruction
4466    /* 11-14 instructions */
4467
4468
4469/* ------------------------------ */
4470    .balign 64
4471.L_OP_ADD_LONG: /* 0x9b */
4472/* File: armv5te/OP_ADD_LONG.S */
4473/* File: armv5te/binopWide.S */
4474    /*
4475     * Generic 64-bit binary operation.  Provide an "instr" line that
4476     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4477     * This could be an ARM instruction or a function call.  (If the result
4478     * comes back in a register other than r0, you can override "result".)
4479     *
4480     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4481     * vCC (r1).  Useful for integer division and modulus.
4482     *
4483     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4484     *      xor-long, add-double, sub-double, mul-double, div-double,
4485     *      rem-double
4486     *
4487     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4488     */
4489    /* binop vAA, vBB, vCC */
4490    FETCH(r0, 1)                        @ r0<- CCBB
4491    mov     r9, rINST, lsr #8           @ r9<- AA
4492    and     r2, r0, #255                @ r2<- BB
4493    mov     r3, r0, lsr #8              @ r3<- CC
4494    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4495    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4496    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4497    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4498    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4499    .if 0
4500    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4501    beq     common_errDivideByZero
4502    .endif
4503    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4504
4505    adds    r0, r0, r2                           @ optional op; may set condition codes
4506    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
4507    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4508    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4509    GOTO_OPCODE(ip)                     @ jump to next instruction
4510    /* 14-17 instructions */
4511
4512
4513/* ------------------------------ */
4514    .balign 64
4515.L_OP_SUB_LONG: /* 0x9c */
4516/* File: armv5te/OP_SUB_LONG.S */
4517/* File: armv5te/binopWide.S */
4518    /*
4519     * Generic 64-bit binary operation.  Provide an "instr" line that
4520     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4521     * This could be an ARM instruction or a function call.  (If the result
4522     * comes back in a register other than r0, you can override "result".)
4523     *
4524     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4525     * vCC (r1).  Useful for integer division and modulus.
4526     *
4527     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4528     *      xor-long, add-double, sub-double, mul-double, div-double,
4529     *      rem-double
4530     *
4531     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4532     */
4533    /* binop vAA, vBB, vCC */
4534    FETCH(r0, 1)                        @ r0<- CCBB
4535    mov     r9, rINST, lsr #8           @ r9<- AA
4536    and     r2, r0, #255                @ r2<- BB
4537    mov     r3, r0, lsr #8              @ r3<- CC
4538    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4539    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4540    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4541    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4542    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4543    .if 0
4544    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4545    beq     common_errDivideByZero
4546    .endif
4547    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4548
4549    subs    r0, r0, r2                           @ optional op; may set condition codes
4550    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
4551    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4552    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4553    GOTO_OPCODE(ip)                     @ jump to next instruction
4554    /* 14-17 instructions */
4555
4556
4557/* ------------------------------ */
4558    .balign 64
4559.L_OP_MUL_LONG: /* 0x9d */
4560/* File: armv5te/OP_MUL_LONG.S */
4561    /*
4562     * Signed 64-bit integer multiply.
4563     *
4564     * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
4565     *        WX
4566     *      x YZ
4567     *  --------
4568     *     ZW ZX
4569     *  YW YX
4570     *
4571     * The low word of the result holds ZX, the high word holds
4572     * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
4573     * it doesn't fit in the low 64 bits.
4574     *
4575     * Unlike most ARM math operations, multiply instructions have
4576     * restrictions on using the same register more than once (Rd and Rm
4577     * cannot be the same).
4578     */
4579    /* mul-long vAA, vBB, vCC */
4580    FETCH(r0, 1)                        @ r0<- CCBB
4581    and     r2, r0, #255                @ r2<- BB
4582    mov     r3, r0, lsr #8              @ r3<- CC
4583    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4584    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4585    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4586    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4587    mul     ip, r2, r1                  @  ip<- ZxW
4588    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
4589    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
4590    mov     r0, rINST, lsr #8           @ r0<- AA
4591    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
4592    add     r0, rFP, r0, lsl #2         @ r0<- &fp[AA]
4593    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4594    b       .LOP_MUL_LONG_finish
4595
4596/* ------------------------------ */
4597    .balign 64
4598.L_OP_DIV_LONG: /* 0x9e */
4599/* File: armv5te/OP_DIV_LONG.S */
4600/* File: armv5te/binopWide.S */
4601    /*
4602     * Generic 64-bit binary operation.  Provide an "instr" line that
4603     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4604     * This could be an ARM instruction or a function call.  (If the result
4605     * comes back in a register other than r0, you can override "result".)
4606     *
4607     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4608     * vCC (r1).  Useful for integer division and modulus.
4609     *
4610     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4611     *      xor-long, add-double, sub-double, mul-double, div-double,
4612     *      rem-double
4613     *
4614     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4615     */
4616    /* binop vAA, vBB, vCC */
4617    FETCH(r0, 1)                        @ r0<- CCBB
4618    mov     r9, rINST, lsr #8           @ r9<- AA
4619    and     r2, r0, #255                @ r2<- BB
4620    mov     r3, r0, lsr #8              @ r3<- CC
4621    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4622    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4623    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4624    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4625    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4626    .if 1
4627    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4628    beq     common_errDivideByZero
4629    .endif
4630    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4631
4632                               @ optional op; may set condition codes
4633    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4634    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4635    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4636    GOTO_OPCODE(ip)                     @ jump to next instruction
4637    /* 14-17 instructions */
4638
4639
4640/* ------------------------------ */
4641    .balign 64
4642.L_OP_REM_LONG: /* 0x9f */
4643/* File: armv5te/OP_REM_LONG.S */
4644/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
4645/* File: armv5te/binopWide.S */
4646    /*
4647     * Generic 64-bit binary operation.  Provide an "instr" line that
4648     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4649     * This could be an ARM instruction or a function call.  (If the result
4650     * comes back in a register other than r0, you can override "result".)
4651     *
4652     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4653     * vCC (r1).  Useful for integer division and modulus.
4654     *
4655     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4656     *      xor-long, add-double, sub-double, mul-double, div-double,
4657     *      rem-double
4658     *
4659     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4660     */
4661    /* binop vAA, vBB, vCC */
4662    FETCH(r0, 1)                        @ r0<- CCBB
4663    mov     r9, rINST, lsr #8           @ r9<- AA
4664    and     r2, r0, #255                @ r2<- BB
4665    mov     r3, r0, lsr #8              @ r3<- CC
4666    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4667    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4668    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4669    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4670    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4671    .if 1
4672    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4673    beq     common_errDivideByZero
4674    .endif
4675    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4676
4677                               @ optional op; may set condition codes
4678    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4679    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4680    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
4681    GOTO_OPCODE(ip)                     @ jump to next instruction
4682    /* 14-17 instructions */
4683
4684
4685/* ------------------------------ */
4686    .balign 64
4687.L_OP_AND_LONG: /* 0xa0 */
4688/* File: armv5te/OP_AND_LONG.S */
4689/* File: armv5te/binopWide.S */
4690    /*
4691     * Generic 64-bit binary operation.  Provide an "instr" line that
4692     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4693     * This could be an ARM instruction or a function call.  (If the result
4694     * comes back in a register other than r0, you can override "result".)
4695     *
4696     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4697     * vCC (r1).  Useful for integer division and modulus.
4698     *
4699     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4700     *      xor-long, add-double, sub-double, mul-double, div-double,
4701     *      rem-double
4702     *
4703     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4704     */
4705    /* binop vAA, vBB, vCC */
4706    FETCH(r0, 1)                        @ r0<- CCBB
4707    mov     r9, rINST, lsr #8           @ r9<- AA
4708    and     r2, r0, #255                @ r2<- BB
4709    mov     r3, r0, lsr #8              @ r3<- CC
4710    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4711    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4712    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4713    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4714    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4715    .if 0
4716    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4717    beq     common_errDivideByZero
4718    .endif
4719    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4720
4721    and     r0, r0, r2                           @ optional op; may set condition codes
4722    and     r1, r1, r3                              @ result<- op, r0-r3 changed
4723    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4724    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4725    GOTO_OPCODE(ip)                     @ jump to next instruction
4726    /* 14-17 instructions */
4727
4728
4729/* ------------------------------ */
4730    .balign 64
4731.L_OP_OR_LONG: /* 0xa1 */
4732/* File: armv5te/OP_OR_LONG.S */
4733/* File: armv5te/binopWide.S */
4734    /*
4735     * Generic 64-bit binary operation.  Provide an "instr" line that
4736     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4737     * This could be an ARM instruction or a function call.  (If the result
4738     * comes back in a register other than r0, you can override "result".)
4739     *
4740     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4741     * vCC (r1).  Useful for integer division and modulus.
4742     *
4743     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4744     *      xor-long, add-double, sub-double, mul-double, div-double,
4745     *      rem-double
4746     *
4747     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4748     */
4749    /* binop vAA, vBB, vCC */
4750    FETCH(r0, 1)                        @ r0<- CCBB
4751    mov     r9, rINST, lsr #8           @ r9<- AA
4752    and     r2, r0, #255                @ r2<- BB
4753    mov     r3, r0, lsr #8              @ r3<- CC
4754    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4755    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4756    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4757    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4758    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4759    .if 0
4760    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4761    beq     common_errDivideByZero
4762    .endif
4763    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4764
4765    orr     r0, r0, r2                           @ optional op; may set condition codes
4766    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
4767    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4768    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4769    GOTO_OPCODE(ip)                     @ jump to next instruction
4770    /* 14-17 instructions */
4771
4772
4773/* ------------------------------ */
4774    .balign 64
4775.L_OP_XOR_LONG: /* 0xa2 */
4776/* File: armv5te/OP_XOR_LONG.S */
4777/* File: armv5te/binopWide.S */
4778    /*
4779     * Generic 64-bit binary operation.  Provide an "instr" line that
4780     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4781     * This could be an ARM instruction or a function call.  (If the result
4782     * comes back in a register other than r0, you can override "result".)
4783     *
4784     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4785     * vCC (r1).  Useful for integer division and modulus.
4786     *
4787     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4788     *      xor-long, add-double, sub-double, mul-double, div-double,
4789     *      rem-double
4790     *
4791     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4792     */
4793    /* binop vAA, vBB, vCC */
4794    FETCH(r0, 1)                        @ r0<- CCBB
4795    mov     r9, rINST, lsr #8           @ r9<- AA
4796    and     r2, r0, #255                @ r2<- BB
4797    mov     r3, r0, lsr #8              @ r3<- CC
4798    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4799    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4800    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4801    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4802    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4803    .if 0
4804    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4805    beq     common_errDivideByZero
4806    .endif
4807    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4808
4809    eor     r0, r0, r2                           @ optional op; may set condition codes
4810    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
4811    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4812    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4813    GOTO_OPCODE(ip)                     @ jump to next instruction
4814    /* 14-17 instructions */
4815
4816
4817/* ------------------------------ */
4818    .balign 64
4819.L_OP_SHL_LONG: /* 0xa3 */
4820/* File: armv5te/OP_SHL_LONG.S */
4821    /*
4822     * Long integer shift.  This is different from the generic 32/64-bit
4823     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4824     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4825     * 6 bits of the shift distance.
4826     */
4827    /* shl-long vAA, vBB, vCC */
4828    FETCH(r0, 1)                        @ r0<- CCBB
4829    mov     r9, rINST, lsr #8           @ r9<- AA
4830    and     r3, r0, #255                @ r3<- BB
4831    mov     r0, r0, lsr #8              @ r0<- CC
4832    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4833    GET_VREG(r2, r0)                    @ r2<- vCC
4834    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4835    and     r2, r2, #63                 @ r2<- r2 & 0x3f
4836    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4837
4838    mov     r1, r1, asl r2              @  r1<- r1 << r2
4839    rsb     r3, r2, #32                 @  r3<- 32 - r2
4840    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
4841    subs    ip, r2, #32                 @  ip<- r2 - 32
4842    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
4843    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4844    b       .LOP_SHL_LONG_finish
4845
4846/* ------------------------------ */
4847    .balign 64
4848.L_OP_SHR_LONG: /* 0xa4 */
4849/* File: armv5te/OP_SHR_LONG.S */
4850    /*
4851     * Long integer shift.  This is different from the generic 32/64-bit
4852     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4853     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4854     * 6 bits of the shift distance.
4855     */
4856    /* shr-long vAA, vBB, vCC */
4857    FETCH(r0, 1)                        @ r0<- CCBB
4858    mov     r9, rINST, lsr #8           @ r9<- AA
4859    and     r3, r0, #255                @ r3<- BB
4860    mov     r0, r0, lsr #8              @ r0<- CC
4861    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4862    GET_VREG(r2, r0)                    @ r2<- vCC
4863    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4864    and     r2, r2, #63                 @ r0<- r0 & 0x3f
4865    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4866
4867    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
4868    rsb     r3, r2, #32                 @  r3<- 32 - r2
4869    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
4870    subs    ip, r2, #32                 @  ip<- r2 - 32
4871    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
4872    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4873    b       .LOP_SHR_LONG_finish
4874
4875/* ------------------------------ */
4876    .balign 64
4877.L_OP_USHR_LONG: /* 0xa5 */
4878/* File: armv5te/OP_USHR_LONG.S */
4879    /*
4880     * Long integer shift.  This is different from the generic 32/64-bit
4881     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4882     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4883     * 6 bits of the shift distance.
4884     */
4885    /* ushr-long vAA, vBB, vCC */
4886    FETCH(r0, 1)                        @ r0<- CCBB
4887    mov     r9, rINST, lsr #8           @ r9<- AA
4888    and     r3, r0, #255                @ r3<- BB
4889    mov     r0, r0, lsr #8              @ r0<- CC
4890    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4891    GET_VREG(r2, r0)                    @ r2<- vCC
4892    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4893    and     r2, r2, #63                 @ r0<- r0 & 0x3f
4894    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4895
4896    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
4897    rsb     r3, r2, #32                 @  r3<- 32 - r2
4898    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
4899    subs    ip, r2, #32                 @  ip<- r2 - 32
4900    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
4901    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4902    b       .LOP_USHR_LONG_finish
4903
4904/* ------------------------------ */
4905    .balign 64
4906.L_OP_ADD_FLOAT: /* 0xa6 */
4907/* File: arm-vfp/OP_ADD_FLOAT.S */
4908/* File: arm-vfp/fbinop.S */
4909    /*
4910     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4911     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4912     * use the "softfp" ABI, this must be an instruction, not a function call.
4913     *
4914     * For: add-float, sub-float, mul-float, div-float
4915     */
4916    /* floatop vAA, vBB, vCC */
4917    FETCH(r0, 1)                        @ r0<- CCBB
4918    mov     r9, rINST, lsr #8           @ r9<- AA
4919    mov     r3, r0, lsr #8              @ r3<- CC
4920    and     r2, r0, #255                @ r2<- BB
4921    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4922    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4923    flds    s1, [r3]                    @ s1<- vCC
4924    flds    s0, [r2]                    @ s0<- vBB
4925
4926    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4927    fadds   s2, s0, s1                              @ s2<- op
4928    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4929    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4930    fsts    s2, [r9]                    @ vAA<- s2
4931    GOTO_OPCODE(ip)                     @ jump to next instruction
4932
4933
4934/* ------------------------------ */
4935    .balign 64
4936.L_OP_SUB_FLOAT: /* 0xa7 */
4937/* File: arm-vfp/OP_SUB_FLOAT.S */
4938/* File: arm-vfp/fbinop.S */
4939    /*
4940     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4941     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4942     * use the "softfp" ABI, this must be an instruction, not a function call.
4943     *
4944     * For: add-float, sub-float, mul-float, div-float
4945     */
4946    /* floatop vAA, vBB, vCC */
4947    FETCH(r0, 1)                        @ r0<- CCBB
4948    mov     r9, rINST, lsr #8           @ r9<- AA
4949    mov     r3, r0, lsr #8              @ r3<- CC
4950    and     r2, r0, #255                @ r2<- BB
4951    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4952    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4953    flds    s1, [r3]                    @ s1<- vCC
4954    flds    s0, [r2]                    @ s0<- vBB
4955
4956    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4957    fsubs   s2, s0, s1                              @ s2<- op
4958    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4959    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4960    fsts    s2, [r9]                    @ vAA<- s2
4961    GOTO_OPCODE(ip)                     @ jump to next instruction
4962
4963
4964/* ------------------------------ */
4965    .balign 64
4966.L_OP_MUL_FLOAT: /* 0xa8 */
4967/* File: arm-vfp/OP_MUL_FLOAT.S */
4968/* File: arm-vfp/fbinop.S */
4969    /*
4970     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4971     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4972     * use the "softfp" ABI, this must be an instruction, not a function call.
4973     *
4974     * For: add-float, sub-float, mul-float, div-float
4975     */
4976    /* floatop vAA, vBB, vCC */
4977    FETCH(r0, 1)                        @ r0<- CCBB
4978    mov     r9, rINST, lsr #8           @ r9<- AA
4979    mov     r3, r0, lsr #8              @ r3<- CC
4980    and     r2, r0, #255                @ r2<- BB
4981    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4982    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4983    flds    s1, [r3]                    @ s1<- vCC
4984    flds    s0, [r2]                    @ s0<- vBB
4985
4986    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4987    fmuls   s2, s0, s1                              @ s2<- op
4988    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4989    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4990    fsts    s2, [r9]                    @ vAA<- s2
4991    GOTO_OPCODE(ip)                     @ jump to next instruction
4992
4993
4994/* ------------------------------ */
4995    .balign 64
4996.L_OP_DIV_FLOAT: /* 0xa9 */
4997/* File: arm-vfp/OP_DIV_FLOAT.S */
4998/* File: arm-vfp/fbinop.S */
4999    /*
5000     * Generic 32-bit floating-point operation.  Provide an "instr" line that
5001     * specifies an instruction that performs "s2 = s0 op s1".  Because we
5002     * use the "softfp" ABI, this must be an instruction, not a function call.
5003     *
5004     * For: add-float, sub-float, mul-float, div-float
5005     */
5006    /* floatop vAA, vBB, vCC */
5007    FETCH(r0, 1)                        @ r0<- CCBB
5008    mov     r9, rINST, lsr #8           @ r9<- AA
5009    mov     r3, r0, lsr #8              @ r3<- CC
5010    and     r2, r0, #255                @ r2<- BB
5011    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5012    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5013    flds    s1, [r3]                    @ s1<- vCC
5014    flds    s0, [r2]                    @ s0<- vBB
5015
5016    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5017    fdivs   s2, s0, s1                              @ s2<- op
5018    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5019    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5020    fsts    s2, [r9]                    @ vAA<- s2
5021    GOTO_OPCODE(ip)                     @ jump to next instruction
5022
5023
5024/* ------------------------------ */
5025    .balign 64
5026.L_OP_REM_FLOAT: /* 0xaa */
5027/* File: armv5te/OP_REM_FLOAT.S */
5028/* EABI doesn't define a float remainder function, but libm does */
5029/* File: armv5te/binop.S */
5030    /*
5031     * Generic 32-bit binary operation.  Provide an "instr" line that
5032     * specifies an instruction that performs "result = r0 op r1".
5033     * This could be an ARM instruction or a function call.  (If the result
5034     * comes back in a register other than r0, you can override "result".)
5035     *
5036     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5037     * vCC (r1).  Useful for integer division and modulus.  Note that we
5038     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
5039     * handles it correctly.
5040     *
5041     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
5042     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
5043     *      mul-float, div-float, rem-float
5044     */
5045    /* binop vAA, vBB, vCC */
5046    FETCH(r0, 1)                        @ r0<- CCBB
5047    mov     r9, rINST, lsr #8           @ r9<- AA
5048    mov     r3, r0, lsr #8              @ r3<- CC
5049    and     r2, r0, #255                @ r2<- BB
5050    GET_VREG(r1, r3)                    @ r1<- vCC
5051    GET_VREG(r0, r2)                    @ r0<- vBB
5052    .if 0
5053    cmp     r1, #0                      @ is second operand zero?
5054    beq     common_errDivideByZero
5055    .endif
5056
5057    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5058                               @ optional op; may set condition codes
5059    bl      fmodf                              @ r0<- op, r0-r3 changed
5060    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5061    SET_VREG(r0, r9)               @ vAA<- r0
5062    GOTO_OPCODE(ip)                     @ jump to next instruction
5063    /* 11-14 instructions */
5064
5065
5066/* ------------------------------ */
5067    .balign 64
5068.L_OP_ADD_DOUBLE: /* 0xab */
5069/* File: arm-vfp/OP_ADD_DOUBLE.S */
5070/* File: arm-vfp/fbinopWide.S */
5071    /*
5072     * Generic 64-bit double-precision floating point binary operation.
5073     * Provide an "instr" line that specifies an instruction that performs
5074     * "d2 = d0 op d1".
5075     *
5076     * for: add-double, sub-double, mul-double, div-double
5077     */
5078    /* doubleop vAA, vBB, vCC */
5079    FETCH(r0, 1)                        @ r0<- CCBB
5080    mov     r9, rINST, lsr #8           @ r9<- AA
5081    mov     r3, r0, lsr #8              @ r3<- CC
5082    and     r2, r0, #255                @ r2<- BB
5083    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5084    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5085    fldd    d1, [r3]                    @ d1<- vCC
5086    fldd    d0, [r2]                    @ d0<- vBB
5087
5088    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5089    faddd   d2, d0, d1                              @ s2<- op
5090    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5091    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5092    fstd    d2, [r9]                    @ vAA<- d2
5093    GOTO_OPCODE(ip)                     @ jump to next instruction
5094
5095
5096/* ------------------------------ */
5097    .balign 64
5098.L_OP_SUB_DOUBLE: /* 0xac */
5099/* File: arm-vfp/OP_SUB_DOUBLE.S */
5100/* File: arm-vfp/fbinopWide.S */
5101    /*
5102     * Generic 64-bit double-precision floating point binary operation.
5103     * Provide an "instr" line that specifies an instruction that performs
5104     * "d2 = d0 op d1".
5105     *
5106     * for: add-double, sub-double, mul-double, div-double
5107     */
5108    /* doubleop vAA, vBB, vCC */
5109    FETCH(r0, 1)                        @ r0<- CCBB
5110    mov     r9, rINST, lsr #8           @ r9<- AA
5111    mov     r3, r0, lsr #8              @ r3<- CC
5112    and     r2, r0, #255                @ r2<- BB
5113    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5114    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5115    fldd    d1, [r3]                    @ d1<- vCC
5116    fldd    d0, [r2]                    @ d0<- vBB
5117
5118    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5119    fsubd   d2, d0, d1                              @ s2<- op
5120    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5121    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5122    fstd    d2, [r9]                    @ vAA<- d2
5123    GOTO_OPCODE(ip)                     @ jump to next instruction
5124
5125
5126/* ------------------------------ */
5127    .balign 64
5128.L_OP_MUL_DOUBLE: /* 0xad */
5129/* File: arm-vfp/OP_MUL_DOUBLE.S */
5130/* File: arm-vfp/fbinopWide.S */
5131    /*
5132     * Generic 64-bit double-precision floating point binary operation.
5133     * Provide an "instr" line that specifies an instruction that performs
5134     * "d2 = d0 op d1".
5135     *
5136     * for: add-double, sub-double, mul-double, div-double
5137     */
5138    /* doubleop vAA, vBB, vCC */
5139    FETCH(r0, 1)                        @ r0<- CCBB
5140    mov     r9, rINST, lsr #8           @ r9<- AA
5141    mov     r3, r0, lsr #8              @ r3<- CC
5142    and     r2, r0, #255                @ r2<- BB
5143    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5144    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5145    fldd    d1, [r3]                    @ d1<- vCC
5146    fldd    d0, [r2]                    @ d0<- vBB
5147
5148    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5149    fmuld   d2, d0, d1                              @ s2<- op
5150    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5151    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5152    fstd    d2, [r9]                    @ vAA<- d2
5153    GOTO_OPCODE(ip)                     @ jump to next instruction
5154
5155
5156/* ------------------------------ */
5157    .balign 64
5158.L_OP_DIV_DOUBLE: /* 0xae */
5159/* File: arm-vfp/OP_DIV_DOUBLE.S */
5160/* File: arm-vfp/fbinopWide.S */
5161    /*
5162     * Generic 64-bit double-precision floating point binary operation.
5163     * Provide an "instr" line that specifies an instruction that performs
5164     * "d2 = d0 op d1".
5165     *
5166     * for: add-double, sub-double, mul-double, div-double
5167     */
5168    /* doubleop vAA, vBB, vCC */
5169    FETCH(r0, 1)                        @ r0<- CCBB
5170    mov     r9, rINST, lsr #8           @ r9<- AA
5171    mov     r3, r0, lsr #8              @ r3<- CC
5172    and     r2, r0, #255                @ r2<- BB
5173    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5174    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5175    fldd    d1, [r3]                    @ d1<- vCC
5176    fldd    d0, [r2]                    @ d0<- vBB
5177
5178    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5179    fdivd   d2, d0, d1                              @ s2<- op
5180    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5181    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5182    fstd    d2, [r9]                    @ vAA<- d2
5183    GOTO_OPCODE(ip)                     @ jump to next instruction
5184
5185
5186/* ------------------------------ */
5187    .balign 64
5188.L_OP_REM_DOUBLE: /* 0xaf */
5189/* File: armv5te/OP_REM_DOUBLE.S */
5190/* EABI doesn't define a double remainder function, but libm does */
5191/* File: armv5te/binopWide.S */
5192    /*
5193     * Generic 64-bit binary operation.  Provide an "instr" line that
5194     * specifies an instruction that performs "result = r0-r1 op r2-r3".
5195     * This could be an ARM instruction or a function call.  (If the result
5196     * comes back in a register other than r0, you can override "result".)
5197     *
5198     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5199     * vCC (r1).  Useful for integer division and modulus.
5200     *
5201     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
5202     *      xor-long, add-double, sub-double, mul-double, div-double,
5203     *      rem-double
5204     *
5205     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
5206     */
5207    /* binop vAA, vBB, vCC */
5208    FETCH(r0, 1)                        @ r0<- CCBB
5209    mov     r9, rINST, lsr #8           @ r9<- AA
5210    and     r2, r0, #255                @ r2<- BB
5211    mov     r3, r0, lsr #8              @ r3<- CC
5212    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5213    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
5214    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
5215    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5216    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
5217    .if 0
5218    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5219    beq     common_errDivideByZero
5220    .endif
5221    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5222
5223                               @ optional op; may set condition codes
5224    bl      fmod                              @ result<- op, r0-r3 changed
5225    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5226    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5227    GOTO_OPCODE(ip)                     @ jump to next instruction
5228    /* 14-17 instructions */
5229
5230
5231/* ------------------------------ */
5232    .balign 64
5233.L_OP_ADD_INT_2ADDR: /* 0xb0 */
5234/* File: armv5te/OP_ADD_INT_2ADDR.S */
5235/* File: armv5te/binop2addr.S */
5236    /*
5237     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5238     * that specifies an instruction that performs "result = r0 op r1".
5239     * This could be an ARM instruction or a function call.  (If the result
5240     * comes back in a register other than r0, you can override "result".)
5241     *
5242     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5243     * vCC (r1).  Useful for integer division and modulus.
5244     *
5245     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5246     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5247     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5248     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5249     */
5250    /* binop/2addr vA, vB */
5251    mov     r9, rINST, lsr #8           @ r9<- A+
5252    mov     r3, rINST, lsr #12          @ r3<- B
5253    and     r9, r9, #15
5254    GET_VREG(r1, r3)                    @ r1<- vB
5255    GET_VREG(r0, r9)                    @ r0<- vA
5256    .if 0
5257    cmp     r1, #0                      @ is second operand zero?
5258    beq     common_errDivideByZero
5259    .endif
5260    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5261
5262                               @ optional op; may set condition codes
5263    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
5264    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5265    SET_VREG(r0, r9)               @ vAA<- r0
5266    GOTO_OPCODE(ip)                     @ jump to next instruction
5267    /* 10-13 instructions */
5268
5269
5270/* ------------------------------ */
5271    .balign 64
5272.L_OP_SUB_INT_2ADDR: /* 0xb1 */
5273/* File: armv5te/OP_SUB_INT_2ADDR.S */
5274/* File: armv5te/binop2addr.S */
5275    /*
5276     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5277     * that specifies an instruction that performs "result = r0 op r1".
5278     * This could be an ARM instruction or a function call.  (If the result
5279     * comes back in a register other than r0, you can override "result".)
5280     *
5281     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5282     * vCC (r1).  Useful for integer division and modulus.
5283     *
5284     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5285     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5286     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5287     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5288     */
5289    /* binop/2addr vA, vB */
5290    mov     r9, rINST, lsr #8           @ r9<- A+
5291    mov     r3, rINST, lsr #12          @ r3<- B
5292    and     r9, r9, #15
5293    GET_VREG(r1, r3)                    @ r1<- vB
5294    GET_VREG(r0, r9)                    @ r0<- vA
5295    .if 0
5296    cmp     r1, #0                      @ is second operand zero?
5297    beq     common_errDivideByZero
5298    .endif
5299    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5300
5301                               @ optional op; may set condition codes
5302    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
5303    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5304    SET_VREG(r0, r9)               @ vAA<- r0
5305    GOTO_OPCODE(ip)                     @ jump to next instruction
5306    /* 10-13 instructions */
5307
5308
5309/* ------------------------------ */
5310    .balign 64
5311.L_OP_MUL_INT_2ADDR: /* 0xb2 */
5312/* File: armv5te/OP_MUL_INT_2ADDR.S */
5313/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
5314/* File: armv5te/binop2addr.S */
5315    /*
5316     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5317     * that specifies an instruction that performs "result = r0 op r1".
5318     * This could be an ARM instruction or a function call.  (If the result
5319     * comes back in a register other than r0, you can override "result".)
5320     *
5321     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5322     * vCC (r1).  Useful for integer division and modulus.
5323     *
5324     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5325     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5326     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5327     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5328     */
5329    /* binop/2addr vA, vB */
5330    mov     r9, rINST, lsr #8           @ r9<- A+
5331    mov     r3, rINST, lsr #12          @ r3<- B
5332    and     r9, r9, #15
5333    GET_VREG(r1, r3)                    @ r1<- vB
5334    GET_VREG(r0, r9)                    @ r0<- vA
5335    .if 0
5336    cmp     r1, #0                      @ is second operand zero?
5337    beq     common_errDivideByZero
5338    .endif
5339    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5340
5341                               @ optional op; may set condition codes
5342    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
5343    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5344    SET_VREG(r0, r9)               @ vAA<- r0
5345    GOTO_OPCODE(ip)                     @ jump to next instruction
5346    /* 10-13 instructions */
5347
5348
5349/* ------------------------------ */
5350    .balign 64
5351.L_OP_DIV_INT_2ADDR: /* 0xb3 */
5352/* File: armv5te/OP_DIV_INT_2ADDR.S */
5353/* File: armv5te/binop2addr.S */
5354    /*
5355     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5356     * that specifies an instruction that performs "result = r0 op r1".
5357     * This could be an ARM instruction or a function call.  (If the result
5358     * comes back in a register other than r0, you can override "result".)
5359     *
5360     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5361     * vCC (r1).  Useful for integer division and modulus.
5362     *
5363     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5364     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5365     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5366     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5367     */
5368    /* binop/2addr vA, vB */
5369    mov     r9, rINST, lsr #8           @ r9<- A+
5370    mov     r3, rINST, lsr #12          @ r3<- B
5371    and     r9, r9, #15
5372    GET_VREG(r1, r3)                    @ r1<- vB
5373    GET_VREG(r0, r9)                    @ r0<- vA
5374    .if 1
5375    cmp     r1, #0                      @ is second operand zero?
5376    beq     common_errDivideByZero
5377    .endif
5378    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5379
5380                               @ optional op; may set condition codes
5381    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
5382    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5383    SET_VREG(r0, r9)               @ vAA<- r0
5384    GOTO_OPCODE(ip)                     @ jump to next instruction
5385    /* 10-13 instructions */
5386
5387
5388/* ------------------------------ */
5389    .balign 64
5390.L_OP_REM_INT_2ADDR: /* 0xb4 */
5391/* File: armv5te/OP_REM_INT_2ADDR.S */
5392/* idivmod returns quotient in r0 and remainder in r1 */
5393/* File: armv5te/binop2addr.S */
5394    /*
5395     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5396     * that specifies an instruction that performs "result = r0 op r1".
5397     * This could be an ARM instruction or a function call.  (If the result
5398     * comes back in a register other than r0, you can override "result".)
5399     *
5400     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5401     * vCC (r1).  Useful for integer division and modulus.
5402     *
5403     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5404     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5405     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5406     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5407     */
5408    /* binop/2addr vA, vB */
5409    mov     r9, rINST, lsr #8           @ r9<- A+
5410    mov     r3, rINST, lsr #12          @ r3<- B
5411    and     r9, r9, #15
5412    GET_VREG(r1, r3)                    @ r1<- vB
5413    GET_VREG(r0, r9)                    @ r0<- vA
5414    .if 1
5415    cmp     r1, #0                      @ is second operand zero?
5416    beq     common_errDivideByZero
5417    .endif
5418    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5419
5420                               @ optional op; may set condition codes
5421    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
5422    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5423    SET_VREG(r1, r9)               @ vAA<- r1
5424    GOTO_OPCODE(ip)                     @ jump to next instruction
5425    /* 10-13 instructions */
5426
5427
5428/* ------------------------------ */
5429    .balign 64
5430.L_OP_AND_INT_2ADDR: /* 0xb5 */
5431/* File: armv5te/OP_AND_INT_2ADDR.S */
5432/* File: armv5te/binop2addr.S */
5433    /*
5434     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5435     * that specifies an instruction that performs "result = r0 op r1".
5436     * This could be an ARM instruction or a function call.  (If the result
5437     * comes back in a register other than r0, you can override "result".)
5438     *
5439     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5440     * vCC (r1).  Useful for integer division and modulus.
5441     *
5442     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5443     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5444     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5445     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5446     */
5447    /* binop/2addr vA, vB */
5448    mov     r9, rINST, lsr #8           @ r9<- A+
5449    mov     r3, rINST, lsr #12          @ r3<- B
5450    and     r9, r9, #15
5451    GET_VREG(r1, r3)                    @ r1<- vB
5452    GET_VREG(r0, r9)                    @ r0<- vA
5453    .if 0
5454    cmp     r1, #0                      @ is second operand zero?
5455    beq     common_errDivideByZero
5456    .endif
5457    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5458
5459                               @ optional op; may set condition codes
5460    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
5461    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5462    SET_VREG(r0, r9)               @ vAA<- r0
5463    GOTO_OPCODE(ip)                     @ jump to next instruction
5464    /* 10-13 instructions */
5465
5466
5467/* ------------------------------ */
5468    .balign 64
5469.L_OP_OR_INT_2ADDR: /* 0xb6 */
5470/* File: armv5te/OP_OR_INT_2ADDR.S */
5471/* File: armv5te/binop2addr.S */
5472    /*
5473     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5474     * that specifies an instruction that performs "result = r0 op r1".
5475     * This could be an ARM instruction or a function call.  (If the result
5476     * comes back in a register other than r0, you can override "result".)
5477     *
5478     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5479     * vCC (r1).  Useful for integer division and modulus.
5480     *
5481     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5482     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5483     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5484     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5485     */
5486    /* binop/2addr vA, vB */
5487    mov     r9, rINST, lsr #8           @ r9<- A+
5488    mov     r3, rINST, lsr #12          @ r3<- B
5489    and     r9, r9, #15
5490    GET_VREG(r1, r3)                    @ r1<- vB
5491    GET_VREG(r0, r9)                    @ r0<- vA
5492    .if 0
5493    cmp     r1, #0                      @ is second operand zero?
5494    beq     common_errDivideByZero
5495    .endif
5496    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5497
5498                               @ optional op; may set condition codes
5499    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
5500    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5501    SET_VREG(r0, r9)               @ vAA<- r0
5502    GOTO_OPCODE(ip)                     @ jump to next instruction
5503    /* 10-13 instructions */
5504
5505
5506/* ------------------------------ */
5507    .balign 64
5508.L_OP_XOR_INT_2ADDR: /* 0xb7 */
5509/* File: armv5te/OP_XOR_INT_2ADDR.S */
5510/* File: armv5te/binop2addr.S */
5511    /*
5512     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5513     * that specifies an instruction that performs "result = r0 op r1".
5514     * This could be an ARM instruction or a function call.  (If the result
5515     * comes back in a register other than r0, you can override "result".)
5516     *
5517     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5518     * vCC (r1).  Useful for integer division and modulus.
5519     *
5520     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5521     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5522     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5523     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5524     */
5525    /* binop/2addr vA, vB */
5526    mov     r9, rINST, lsr #8           @ r9<- A+
5527    mov     r3, rINST, lsr #12          @ r3<- B
5528    and     r9, r9, #15
5529    GET_VREG(r1, r3)                    @ r1<- vB
5530    GET_VREG(r0, r9)                    @ r0<- vA
5531    .if 0
5532    cmp     r1, #0                      @ is second operand zero?
5533    beq     common_errDivideByZero
5534    .endif
5535    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5536
5537                               @ optional op; may set condition codes
5538    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
5539    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5540    SET_VREG(r0, r9)               @ vAA<- r0
5541    GOTO_OPCODE(ip)                     @ jump to next instruction
5542    /* 10-13 instructions */
5543
5544
5545/* ------------------------------ */
5546    .balign 64
5547.L_OP_SHL_INT_2ADDR: /* 0xb8 */
5548/* File: armv5te/OP_SHL_INT_2ADDR.S */
5549/* File: armv5te/binop2addr.S */
5550    /*
5551     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5552     * that specifies an instruction that performs "result = r0 op r1".
5553     * This could be an ARM instruction or a function call.  (If the result
5554     * comes back in a register other than r0, you can override "result".)
5555     *
5556     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5557     * vCC (r1).  Useful for integer division and modulus.
5558     *
5559     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5560     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5561     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5562     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5563     */
5564    /* binop/2addr vA, vB */
5565    mov     r9, rINST, lsr #8           @ r9<- A+
5566    mov     r3, rINST, lsr #12          @ r3<- B
5567    and     r9, r9, #15
5568    GET_VREG(r1, r3)                    @ r1<- vB
5569    GET_VREG(r0, r9)                    @ r0<- vA
5570    .if 0
5571    cmp     r1, #0                      @ is second operand zero?
5572    beq     common_errDivideByZero
5573    .endif
5574    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5575
5576    and     r1, r1, #31                           @ optional op; may set condition codes
5577    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
5578    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5579    SET_VREG(r0, r9)               @ vAA<- r0
5580    GOTO_OPCODE(ip)                     @ jump to next instruction
5581    /* 10-13 instructions */
5582
5583
5584/* ------------------------------ */
5585    .balign 64
5586.L_OP_SHR_INT_2ADDR: /* 0xb9 */
5587/* File: armv5te/OP_SHR_INT_2ADDR.S */
5588/* File: armv5te/binop2addr.S */
5589    /*
5590     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5591     * that specifies an instruction that performs "result = r0 op r1".
5592     * This could be an ARM instruction or a function call.  (If the result
5593     * comes back in a register other than r0, you can override "result".)
5594     *
5595     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5596     * vCC (r1).  Useful for integer division and modulus.
5597     *
5598     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5599     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5600     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5601     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5602     */
5603    /* binop/2addr vA, vB */
5604    mov     r9, rINST, lsr #8           @ r9<- A+
5605    mov     r3, rINST, lsr #12          @ r3<- B
5606    and     r9, r9, #15
5607    GET_VREG(r1, r3)                    @ r1<- vB
5608    GET_VREG(r0, r9)                    @ r0<- vA
5609    .if 0
5610    cmp     r1, #0                      @ is second operand zero?
5611    beq     common_errDivideByZero
5612    .endif
5613    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5614
5615    and     r1, r1, #31                           @ optional op; may set condition codes
5616    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
5617    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5618    SET_VREG(r0, r9)               @ vAA<- r0
5619    GOTO_OPCODE(ip)                     @ jump to next instruction
5620    /* 10-13 instructions */
5621
5622
5623/* ------------------------------ */
5624    .balign 64
5625.L_OP_USHR_INT_2ADDR: /* 0xba */
5626/* File: armv5te/OP_USHR_INT_2ADDR.S */
5627/* File: armv5te/binop2addr.S */
5628    /*
5629     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5630     * that specifies an instruction that performs "result = r0 op r1".
5631     * This could be an ARM instruction or a function call.  (If the result
5632     * comes back in a register other than r0, you can override "result".)
5633     *
5634     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5635     * vCC (r1).  Useful for integer division and modulus.
5636     *
5637     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5638     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5639     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5640     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5641     */
5642    /* binop/2addr vA, vB */
5643    mov     r9, rINST, lsr #8           @ r9<- A+
5644    mov     r3, rINST, lsr #12          @ r3<- B
5645    and     r9, r9, #15
5646    GET_VREG(r1, r3)                    @ r1<- vB
5647    GET_VREG(r0, r9)                    @ r0<- vA
5648    .if 0
5649    cmp     r1, #0                      @ is second operand zero?
5650    beq     common_errDivideByZero
5651    .endif
5652    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5653
5654    and     r1, r1, #31                           @ optional op; may set condition codes
5655    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
5656    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5657    SET_VREG(r0, r9)               @ vAA<- r0
5658    GOTO_OPCODE(ip)                     @ jump to next instruction
5659    /* 10-13 instructions */
5660
5661
5662/* ------------------------------ */
5663    .balign 64
5664.L_OP_ADD_LONG_2ADDR: /* 0xbb */
5665/* File: armv5te/OP_ADD_LONG_2ADDR.S */
5666/* File: armv5te/binopWide2addr.S */
5667    /*
5668     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5669     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5670     * This could be an ARM instruction or a function call.  (If the result
5671     * comes back in a register other than r0, you can override "result".)
5672     *
5673     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5674     * vCC (r1).  Useful for integer division and modulus.
5675     *
5676     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5677     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5678     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5679     *      rem-double/2addr
5680     */
5681    /* binop/2addr vA, vB */
5682    mov     r9, rINST, lsr #8           @ r9<- A+
5683    mov     r1, rINST, lsr #12          @ r1<- B
5684    and     r9, r9, #15
5685    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5686    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5687    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5688    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5689    .if 0
5690    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5691    beq     common_errDivideByZero
5692    .endif
5693    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5694
5695    adds    r0, r0, r2                           @ optional op; may set condition codes
5696    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
5697    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5698    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5699    GOTO_OPCODE(ip)                     @ jump to next instruction
5700    /* 12-15 instructions */
5701
5702
5703/* ------------------------------ */
5704    .balign 64
5705.L_OP_SUB_LONG_2ADDR: /* 0xbc */
5706/* File: armv5te/OP_SUB_LONG_2ADDR.S */
5707/* File: armv5te/binopWide2addr.S */
5708    /*
5709     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5710     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5711     * This could be an ARM instruction or a function call.  (If the result
5712     * comes back in a register other than r0, you can override "result".)
5713     *
5714     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5715     * vCC (r1).  Useful for integer division and modulus.
5716     *
5717     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5718     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5719     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5720     *      rem-double/2addr
5721     */
5722    /* binop/2addr vA, vB */
5723    mov     r9, rINST, lsr #8           @ r9<- A+
5724    mov     r1, rINST, lsr #12          @ r1<- B
5725    and     r9, r9, #15
5726    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5727    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5728    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5729    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5730    .if 0
5731    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5732    beq     common_errDivideByZero
5733    .endif
5734    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5735
5736    subs    r0, r0, r2                           @ optional op; may set condition codes
5737    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
5738    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5739    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5740    GOTO_OPCODE(ip)                     @ jump to next instruction
5741    /* 12-15 instructions */
5742
5743
5744/* ------------------------------ */
5745    .balign 64
5746.L_OP_MUL_LONG_2ADDR: /* 0xbd */
5747/* File: armv5te/OP_MUL_LONG_2ADDR.S */
5748    /*
5749     * Signed 64-bit integer multiply, "/2addr" version.
5750     *
5751     * See OP_MUL_LONG for an explanation.
5752     *
5753     * We get a little tight on registers, so to avoid looking up &fp[A]
5754     * again we stuff it into rINST.
5755     */
5756    /* mul-long/2addr vA, vB */
5757    mov     r9, rINST, lsr #8           @ r9<- A+
5758    mov     r1, rINST, lsr #12          @ r1<- B
5759    and     r9, r9, #15
5760    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5761    add     rINST, rFP, r9, lsl #2      @ rINST<- &fp[A]
5762    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5763    ldmia   rINST, {r0-r1}              @ r0/r1<- vAA/vAA+1
5764    mul     ip, r2, r1                  @  ip<- ZxW
5765    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
5766    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
5767    mov     r0, rINST                   @ r0<- &fp[A] (free up rINST)
5768    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5769    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
5770    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5771    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
5772    GOTO_OPCODE(ip)                     @ jump to next instruction
5773
5774/* ------------------------------ */
5775    .balign 64
5776.L_OP_DIV_LONG_2ADDR: /* 0xbe */
5777/* File: armv5te/OP_DIV_LONG_2ADDR.S */
5778/* File: armv5te/binopWide2addr.S */
5779    /*
5780     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5781     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
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-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5789     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5790     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5791     *      rem-double/2addr
5792     */
5793    /* binop/2addr vA, vB */
5794    mov     r9, rINST, lsr #8           @ r9<- A+
5795    mov     r1, rINST, lsr #12          @ r1<- B
5796    and     r9, r9, #15
5797    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5798    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5799    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5800    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5801    .if 1
5802    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5803    beq     common_errDivideByZero
5804    .endif
5805    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5806
5807                               @ optional op; may set condition codes
5808    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
5809    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5810    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5811    GOTO_OPCODE(ip)                     @ jump to next instruction
5812    /* 12-15 instructions */
5813
5814
5815/* ------------------------------ */
5816    .balign 64
5817.L_OP_REM_LONG_2ADDR: /* 0xbf */
5818/* File: armv5te/OP_REM_LONG_2ADDR.S */
5819/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
5820/* File: armv5te/binopWide2addr.S */
5821    /*
5822     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5823     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5824     * This could be an ARM instruction or a function call.  (If the result
5825     * comes back in a register other than r0, you can override "result".)
5826     *
5827     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5828     * vCC (r1).  Useful for integer division and modulus.
5829     *
5830     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5831     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5832     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5833     *      rem-double/2addr
5834     */
5835    /* binop/2addr vA, vB */
5836    mov     r9, rINST, lsr #8           @ r9<- A+
5837    mov     r1, rINST, lsr #12          @ r1<- B
5838    and     r9, r9, #15
5839    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5840    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5841    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5842    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5843    .if 1
5844    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5845    beq     common_errDivideByZero
5846    .endif
5847    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5848
5849                               @ optional op; may set condition codes
5850    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
5851    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5852    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
5853    GOTO_OPCODE(ip)                     @ jump to next instruction
5854    /* 12-15 instructions */
5855
5856
5857/* ------------------------------ */
5858    .balign 64
5859.L_OP_AND_LONG_2ADDR: /* 0xc0 */
5860/* File: armv5te/OP_AND_LONG_2ADDR.S */
5861/* File: armv5te/binopWide2addr.S */
5862    /*
5863     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5864     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5865     * This could be an ARM instruction or a function call.  (If the result
5866     * comes back in a register other than r0, you can override "result".)
5867     *
5868     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5869     * vCC (r1).  Useful for integer division and modulus.
5870     *
5871     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5872     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5873     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5874     *      rem-double/2addr
5875     */
5876    /* binop/2addr vA, vB */
5877    mov     r9, rINST, lsr #8           @ r9<- A+
5878    mov     r1, rINST, lsr #12          @ r1<- B
5879    and     r9, r9, #15
5880    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5881    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5882    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5883    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5884    .if 0
5885    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5886    beq     common_errDivideByZero
5887    .endif
5888    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5889
5890    and     r0, r0, r2                           @ optional op; may set condition codes
5891    and     r1, r1, r3                              @ result<- op, r0-r3 changed
5892    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5893    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5894    GOTO_OPCODE(ip)                     @ jump to next instruction
5895    /* 12-15 instructions */
5896
5897
5898/* ------------------------------ */
5899    .balign 64
5900.L_OP_OR_LONG_2ADDR: /* 0xc1 */
5901/* File: armv5te/OP_OR_LONG_2ADDR.S */
5902/* File: armv5te/binopWide2addr.S */
5903    /*
5904     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5905     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5906     * This could be an ARM instruction or a function call.  (If the result
5907     * comes back in a register other than r0, you can override "result".)
5908     *
5909     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5910     * vCC (r1).  Useful for integer division and modulus.
5911     *
5912     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5913     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5914     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5915     *      rem-double/2addr
5916     */
5917    /* binop/2addr vA, vB */
5918    mov     r9, rINST, lsr #8           @ r9<- A+
5919    mov     r1, rINST, lsr #12          @ r1<- B
5920    and     r9, r9, #15
5921    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5922    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5923    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5924    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5925    .if 0
5926    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5927    beq     common_errDivideByZero
5928    .endif
5929    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5930
5931    orr     r0, r0, r2                           @ optional op; may set condition codes
5932    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
5933    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5934    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5935    GOTO_OPCODE(ip)                     @ jump to next instruction
5936    /* 12-15 instructions */
5937
5938
5939/* ------------------------------ */
5940    .balign 64
5941.L_OP_XOR_LONG_2ADDR: /* 0xc2 */
5942/* File: armv5te/OP_XOR_LONG_2ADDR.S */
5943/* File: armv5te/binopWide2addr.S */
5944    /*
5945     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5946     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5947     * This could be an ARM instruction or a function call.  (If the result
5948     * comes back in a register other than r0, you can override "result".)
5949     *
5950     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5951     * vCC (r1).  Useful for integer division and modulus.
5952     *
5953     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5954     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5955     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5956     *      rem-double/2addr
5957     */
5958    /* binop/2addr vA, vB */
5959    mov     r9, rINST, lsr #8           @ r9<- A+
5960    mov     r1, rINST, lsr #12          @ r1<- B
5961    and     r9, r9, #15
5962    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5963    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5964    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5965    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5966    .if 0
5967    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5968    beq     common_errDivideByZero
5969    .endif
5970    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5971
5972    eor     r0, r0, r2                           @ optional op; may set condition codes
5973    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
5974    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5975    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5976    GOTO_OPCODE(ip)                     @ jump to next instruction
5977    /* 12-15 instructions */
5978
5979
5980/* ------------------------------ */
5981    .balign 64
5982.L_OP_SHL_LONG_2ADDR: /* 0xc3 */
5983/* File: armv5te/OP_SHL_LONG_2ADDR.S */
5984    /*
5985     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5986     * 32-bit shift distance.
5987     */
5988    /* shl-long/2addr vA, vB */
5989    mov     r9, rINST, lsr #8           @ r9<- A+
5990    mov     r3, rINST, lsr #12          @ r3<- B
5991    and     r9, r9, #15
5992    GET_VREG(r2, r3)                    @ r2<- vB
5993    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5994    and     r2, r2, #63                 @ r2<- r2 & 0x3f
5995    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5996
5997    mov     r1, r1, asl r2              @  r1<- r1 << r2
5998    rsb     r3, r2, #32                 @  r3<- 32 - r2
5999    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
6000    subs    ip, r2, #32                 @  ip<- r2 - 32
6001    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6002    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
6003    mov     r0, r0, asl r2              @  r0<- r0 << r2
6004    b       .LOP_SHL_LONG_2ADDR_finish
6005
6006/* ------------------------------ */
6007    .balign 64
6008.L_OP_SHR_LONG_2ADDR: /* 0xc4 */
6009/* File: armv5te/OP_SHR_LONG_2ADDR.S */
6010    /*
6011     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6012     * 32-bit shift distance.
6013     */
6014    /* shr-long/2addr vA, vB */
6015    mov     r9, rINST, lsr #8           @ r9<- A+
6016    mov     r3, rINST, lsr #12          @ r3<- B
6017    and     r9, r9, #15
6018    GET_VREG(r2, r3)                    @ r2<- vB
6019    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6020    and     r2, r2, #63                 @ r2<- r2 & 0x3f
6021    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6022
6023    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
6024    rsb     r3, r2, #32                 @  r3<- 32 - r2
6025    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
6026    subs    ip, r2, #32                 @  ip<- r2 - 32
6027    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6028    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
6029    mov     r1, r1, asr r2              @  r1<- r1 >> r2
6030    b       .LOP_SHR_LONG_2ADDR_finish
6031
6032/* ------------------------------ */
6033    .balign 64
6034.L_OP_USHR_LONG_2ADDR: /* 0xc5 */
6035/* File: armv5te/OP_USHR_LONG_2ADDR.S */
6036    /*
6037     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6038     * 32-bit shift distance.
6039     */
6040    /* ushr-long/2addr vA, vB */
6041    mov     r9, rINST, lsr #8           @ r9<- A+
6042    mov     r3, rINST, lsr #12          @ r3<- B
6043    and     r9, r9, #15
6044    GET_VREG(r2, r3)                    @ r2<- vB
6045    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6046    and     r2, r2, #63                 @ r2<- r2 & 0x3f
6047    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6048
6049    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
6050    rsb     r3, r2, #32                 @  r3<- 32 - r2
6051    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
6052    subs    ip, r2, #32                 @  ip<- r2 - 32
6053    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6054    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
6055    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
6056    b       .LOP_USHR_LONG_2ADDR_finish
6057
6058/* ------------------------------ */
6059    .balign 64
6060.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
6061/* File: arm-vfp/OP_ADD_FLOAT_2ADDR.S */
6062/* File: arm-vfp/fbinop2addr.S */
6063    /*
6064     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6065     * an "instr" line that specifies an instruction that performs
6066     * "s2 = s0 op s1".
6067     *
6068     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6069     */
6070    /* binop/2addr vA, vB */
6071    mov     r3, rINST, lsr #12          @ r3<- B
6072    mov     r9, rINST, lsr #8           @ r9<- A+
6073    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6074    and     r9, r9, #15                 @ r9<- A
6075    flds    s1, [r3]                    @ s1<- vB
6076    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6077    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6078    flds    s0, [r9]                    @ s0<- vA
6079
6080    fadds   s2, s0, s1                              @ s2<- op
6081    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6082    fsts    s2, [r9]                    @ vAA<- s2
6083    GOTO_OPCODE(ip)                     @ jump to next instruction
6084
6085
6086/* ------------------------------ */
6087    .balign 64
6088.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
6089/* File: arm-vfp/OP_SUB_FLOAT_2ADDR.S */
6090/* File: arm-vfp/fbinop2addr.S */
6091    /*
6092     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6093     * an "instr" line that specifies an instruction that performs
6094     * "s2 = s0 op s1".
6095     *
6096     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6097     */
6098    /* binop/2addr vA, vB */
6099    mov     r3, rINST, lsr #12          @ r3<- B
6100    mov     r9, rINST, lsr #8           @ r9<- A+
6101    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6102    and     r9, r9, #15                 @ r9<- A
6103    flds    s1, [r3]                    @ s1<- vB
6104    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6105    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6106    flds    s0, [r9]                    @ s0<- vA
6107
6108    fsubs   s2, s0, s1                              @ s2<- op
6109    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6110    fsts    s2, [r9]                    @ vAA<- s2
6111    GOTO_OPCODE(ip)                     @ jump to next instruction
6112
6113
6114/* ------------------------------ */
6115    .balign 64
6116.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
6117/* File: arm-vfp/OP_MUL_FLOAT_2ADDR.S */
6118/* File: arm-vfp/fbinop2addr.S */
6119    /*
6120     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6121     * an "instr" line that specifies an instruction that performs
6122     * "s2 = s0 op s1".
6123     *
6124     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6125     */
6126    /* binop/2addr vA, vB */
6127    mov     r3, rINST, lsr #12          @ r3<- B
6128    mov     r9, rINST, lsr #8           @ r9<- A+
6129    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6130    and     r9, r9, #15                 @ r9<- A
6131    flds    s1, [r3]                    @ s1<- vB
6132    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6133    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6134    flds    s0, [r9]                    @ s0<- vA
6135
6136    fmuls   s2, s0, s1                              @ s2<- op
6137    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6138    fsts    s2, [r9]                    @ vAA<- s2
6139    GOTO_OPCODE(ip)                     @ jump to next instruction
6140
6141
6142/* ------------------------------ */
6143    .balign 64
6144.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
6145/* File: arm-vfp/OP_DIV_FLOAT_2ADDR.S */
6146/* File: arm-vfp/fbinop2addr.S */
6147    /*
6148     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6149     * an "instr" line that specifies an instruction that performs
6150     * "s2 = s0 op s1".
6151     *
6152     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6153     */
6154    /* binop/2addr vA, vB */
6155    mov     r3, rINST, lsr #12          @ r3<- B
6156    mov     r9, rINST, lsr #8           @ r9<- A+
6157    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6158    and     r9, r9, #15                 @ r9<- A
6159    flds    s1, [r3]                    @ s1<- vB
6160    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6161    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6162    flds    s0, [r9]                    @ s0<- vA
6163
6164    fdivs   s2, s0, s1                              @ s2<- op
6165    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6166    fsts    s2, [r9]                    @ vAA<- s2
6167    GOTO_OPCODE(ip)                     @ jump to next instruction
6168
6169
6170/* ------------------------------ */
6171    .balign 64
6172.L_OP_REM_FLOAT_2ADDR: /* 0xca */
6173/* File: armv5te/OP_REM_FLOAT_2ADDR.S */
6174/* EABI doesn't define a float remainder function, but libm does */
6175/* File: armv5te/binop2addr.S */
6176    /*
6177     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6178     * that specifies an instruction that performs "result = r0 op r1".
6179     * This could be an ARM instruction or a function call.  (If the result
6180     * comes back in a register other than r0, you can override "result".)
6181     *
6182     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6183     * vCC (r1).  Useful for integer division and modulus.
6184     *
6185     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6186     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6187     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6188     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6189     */
6190    /* binop/2addr vA, vB */
6191    mov     r9, rINST, lsr #8           @ r9<- A+
6192    mov     r3, rINST, lsr #12          @ r3<- B
6193    and     r9, r9, #15
6194    GET_VREG(r1, r3)                    @ r1<- vB
6195    GET_VREG(r0, r9)                    @ r0<- vA
6196    .if 0
6197    cmp     r1, #0                      @ is second operand zero?
6198    beq     common_errDivideByZero
6199    .endif
6200    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6201
6202                               @ optional op; may set condition codes
6203    bl      fmodf                              @ r0<- op, r0-r3 changed
6204    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6205    SET_VREG(r0, r9)               @ vAA<- r0
6206    GOTO_OPCODE(ip)                     @ jump to next instruction
6207    /* 10-13 instructions */
6208
6209
6210/* ------------------------------ */
6211    .balign 64
6212.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
6213/* File: arm-vfp/OP_ADD_DOUBLE_2ADDR.S */
6214/* File: arm-vfp/fbinopWide2addr.S */
6215    /*
6216     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6217     * an "instr" line that specifies an instruction that performs
6218     * "d2 = d0 op d1".
6219     *
6220     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6221     *      div-double/2addr
6222     */
6223    /* binop/2addr vA, vB */
6224    mov     r3, rINST, lsr #12          @ r3<- B
6225    mov     r9, rINST, lsr #8           @ r9<- A+
6226    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6227    and     r9, r9, #15                 @ r9<- A
6228    fldd    d1, [r3]                    @ d1<- vB
6229    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6230    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6231    fldd    d0, [r9]                    @ d0<- vA
6232
6233    faddd   d2, d0, d1                              @ d2<- op
6234    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6235    fstd    d2, [r9]                    @ vAA<- d2
6236    GOTO_OPCODE(ip)                     @ jump to next instruction
6237
6238
6239/* ------------------------------ */
6240    .balign 64
6241.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
6242/* File: arm-vfp/OP_SUB_DOUBLE_2ADDR.S */
6243/* File: arm-vfp/fbinopWide2addr.S */
6244    /*
6245     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6246     * an "instr" line that specifies an instruction that performs
6247     * "d2 = d0 op d1".
6248     *
6249     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6250     *      div-double/2addr
6251     */
6252    /* binop/2addr vA, vB */
6253    mov     r3, rINST, lsr #12          @ r3<- B
6254    mov     r9, rINST, lsr #8           @ r9<- A+
6255    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6256    and     r9, r9, #15                 @ r9<- A
6257    fldd    d1, [r3]                    @ d1<- vB
6258    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6259    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6260    fldd    d0, [r9]                    @ d0<- vA
6261
6262    fsubd   d2, d0, d1                              @ d2<- op
6263    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6264    fstd    d2, [r9]                    @ vAA<- d2
6265    GOTO_OPCODE(ip)                     @ jump to next instruction
6266
6267
6268/* ------------------------------ */
6269    .balign 64
6270.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
6271/* File: arm-vfp/OP_MUL_DOUBLE_2ADDR.S */
6272/* File: arm-vfp/fbinopWide2addr.S */
6273    /*
6274     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6275     * an "instr" line that specifies an instruction that performs
6276     * "d2 = d0 op d1".
6277     *
6278     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6279     *      div-double/2addr
6280     */
6281    /* binop/2addr vA, vB */
6282    mov     r3, rINST, lsr #12          @ r3<- B
6283    mov     r9, rINST, lsr #8           @ r9<- A+
6284    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6285    and     r9, r9, #15                 @ r9<- A
6286    fldd    d1, [r3]                    @ d1<- vB
6287    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6288    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6289    fldd    d0, [r9]                    @ d0<- vA
6290
6291    fmuld   d2, d0, d1                              @ d2<- op
6292    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6293    fstd    d2, [r9]                    @ vAA<- d2
6294    GOTO_OPCODE(ip)                     @ jump to next instruction
6295
6296
6297/* ------------------------------ */
6298    .balign 64
6299.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */
6300/* File: arm-vfp/OP_DIV_DOUBLE_2ADDR.S */
6301/* File: arm-vfp/fbinopWide2addr.S */
6302    /*
6303     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6304     * an "instr" line that specifies an instruction that performs
6305     * "d2 = d0 op d1".
6306     *
6307     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6308     *      div-double/2addr
6309     */
6310    /* binop/2addr vA, vB */
6311    mov     r3, rINST, lsr #12          @ r3<- B
6312    mov     r9, rINST, lsr #8           @ r9<- A+
6313    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6314    and     r9, r9, #15                 @ r9<- A
6315    fldd    d1, [r3]                    @ d1<- vB
6316    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6317    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6318    fldd    d0, [r9]                    @ d0<- vA
6319
6320    fdivd   d2, d0, d1                              @ d2<- op
6321    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6322    fstd    d2, [r9]                    @ vAA<- d2
6323    GOTO_OPCODE(ip)                     @ jump to next instruction
6324
6325
6326/* ------------------------------ */
6327    .balign 64
6328.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */
6329/* File: armv5te/OP_REM_DOUBLE_2ADDR.S */
6330/* EABI doesn't define a double remainder function, but libm does */
6331/* File: armv5te/binopWide2addr.S */
6332    /*
6333     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6334     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6335     * This could be an ARM instruction or a function call.  (If the result
6336     * comes back in a register other than r0, you can override "result".)
6337     *
6338     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6339     * vCC (r1).  Useful for integer division and modulus.
6340     *
6341     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6342     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6343     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6344     *      rem-double/2addr
6345     */
6346    /* binop/2addr vA, vB */
6347    mov     r9, rINST, lsr #8           @ r9<- A+
6348    mov     r1, rINST, lsr #12          @ r1<- B
6349    and     r9, r9, #15
6350    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6351    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6352    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6353    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6354    .if 0
6355    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6356    beq     common_errDivideByZero
6357    .endif
6358    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6359
6360                               @ optional op; may set condition codes
6361    bl      fmod                              @ result<- op, r0-r3 changed
6362    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6363    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6364    GOTO_OPCODE(ip)                     @ jump to next instruction
6365    /* 12-15 instructions */
6366
6367
6368/* ------------------------------ */
6369    .balign 64
6370.L_OP_ADD_INT_LIT16: /* 0xd0 */
6371/* File: armv5te/OP_ADD_INT_LIT16.S */
6372/* File: armv5te/binopLit16.S */
6373    /*
6374     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6375     * that specifies an instruction that performs "result = r0 op r1".
6376     * This could be an ARM instruction or a function call.  (If the result
6377     * comes back in a register other than r0, you can override "result".)
6378     *
6379     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6380     * vCC (r1).  Useful for integer division and modulus.
6381     *
6382     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6383     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6384     */
6385    /* binop/lit16 vA, vB, #+CCCC */
6386    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6387    mov     r2, rINST, lsr #12          @ r2<- B
6388    mov     r9, rINST, lsr #8           @ r9<- A+
6389    GET_VREG(r0, r2)                    @ r0<- vB
6390    and     r9, r9, #15
6391    .if 0
6392    cmp     r1, #0                      @ is second operand zero?
6393    beq     common_errDivideByZero
6394    .endif
6395    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6396
6397    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
6398    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6399    SET_VREG(r0, r9)               @ vAA<- r0
6400    GOTO_OPCODE(ip)                     @ jump to next instruction
6401    /* 10-13 instructions */
6402
6403
6404/* ------------------------------ */
6405    .balign 64
6406.L_OP_RSUB_INT: /* 0xd1 */
6407/* File: armv5te/OP_RSUB_INT.S */
6408/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
6409/* File: armv5te/binopLit16.S */
6410    /*
6411     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6412     * that specifies an instruction that performs "result = r0 op r1".
6413     * This could be an ARM instruction or a function call.  (If the result
6414     * comes back in a register other than r0, you can override "result".)
6415     *
6416     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6417     * vCC (r1).  Useful for integer division and modulus.
6418     *
6419     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6420     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6421     */
6422    /* binop/lit16 vA, vB, #+CCCC */
6423    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6424    mov     r2, rINST, lsr #12          @ r2<- B
6425    mov     r9, rINST, lsr #8           @ r9<- A+
6426    GET_VREG(r0, r2)                    @ r0<- vB
6427    and     r9, r9, #15
6428    .if 0
6429    cmp     r1, #0                      @ is second operand zero?
6430    beq     common_errDivideByZero
6431    .endif
6432    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6433
6434    rsb     r0, r0, r1                              @ r0<- op, r0-r3 changed
6435    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6436    SET_VREG(r0, r9)               @ vAA<- r0
6437    GOTO_OPCODE(ip)                     @ jump to next instruction
6438    /* 10-13 instructions */
6439
6440
6441/* ------------------------------ */
6442    .balign 64
6443.L_OP_MUL_INT_LIT16: /* 0xd2 */
6444/* File: armv5te/OP_MUL_INT_LIT16.S */
6445/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
6446/* File: armv5te/binopLit16.S */
6447    /*
6448     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6449     * that specifies an instruction that performs "result = r0 op r1".
6450     * This could be an ARM instruction or a function call.  (If the result
6451     * comes back in a register other than r0, you can override "result".)
6452     *
6453     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6454     * vCC (r1).  Useful for integer division and modulus.
6455     *
6456     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6457     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6458     */
6459    /* binop/lit16 vA, vB, #+CCCC */
6460    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6461    mov     r2, rINST, lsr #12          @ r2<- B
6462    mov     r9, rINST, lsr #8           @ r9<- A+
6463    GET_VREG(r0, r2)                    @ r0<- vB
6464    and     r9, r9, #15
6465    .if 0
6466    cmp     r1, #0                      @ is second operand zero?
6467    beq     common_errDivideByZero
6468    .endif
6469    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6470
6471    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
6472    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6473    SET_VREG(r0, r9)               @ vAA<- r0
6474    GOTO_OPCODE(ip)                     @ jump to next instruction
6475    /* 10-13 instructions */
6476
6477
6478/* ------------------------------ */
6479    .balign 64
6480.L_OP_DIV_INT_LIT16: /* 0xd3 */
6481/* File: armv5te/OP_DIV_INT_LIT16.S */
6482/* File: armv5te/binopLit16.S */
6483    /*
6484     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6485     * that specifies an instruction that performs "result = r0 op r1".
6486     * This could be an ARM instruction or a function call.  (If the result
6487     * comes back in a register other than r0, you can override "result".)
6488     *
6489     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6490     * vCC (r1).  Useful for integer division and modulus.
6491     *
6492     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6493     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6494     */
6495    /* binop/lit16 vA, vB, #+CCCC */
6496    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6497    mov     r2, rINST, lsr #12          @ r2<- B
6498    mov     r9, rINST, lsr #8           @ r9<- A+
6499    GET_VREG(r0, r2)                    @ r0<- vB
6500    and     r9, r9, #15
6501    .if 1
6502    cmp     r1, #0                      @ is second operand zero?
6503    beq     common_errDivideByZero
6504    .endif
6505    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6506
6507    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
6508    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6509    SET_VREG(r0, r9)               @ vAA<- r0
6510    GOTO_OPCODE(ip)                     @ jump to next instruction
6511    /* 10-13 instructions */
6512
6513
6514/* ------------------------------ */
6515    .balign 64
6516.L_OP_REM_INT_LIT16: /* 0xd4 */
6517/* File: armv5te/OP_REM_INT_LIT16.S */
6518/* idivmod returns quotient in r0 and remainder in r1 */
6519/* File: armv5te/binopLit16.S */
6520    /*
6521     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6522     * that specifies an instruction that performs "result = r0 op r1".
6523     * This could be an ARM instruction or a function call.  (If the result
6524     * comes back in a register other than r0, you can override "result".)
6525     *
6526     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6527     * vCC (r1).  Useful for integer division and modulus.
6528     *
6529     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6530     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6531     */
6532    /* binop/lit16 vA, vB, #+CCCC */
6533    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6534    mov     r2, rINST, lsr #12          @ r2<- B
6535    mov     r9, rINST, lsr #8           @ r9<- A+
6536    GET_VREG(r0, r2)                    @ r0<- vB
6537    and     r9, r9, #15
6538    .if 1
6539    cmp     r1, #0                      @ is second operand zero?
6540    beq     common_errDivideByZero
6541    .endif
6542    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6543
6544    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
6545    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6546    SET_VREG(r1, r9)               @ vAA<- r1
6547    GOTO_OPCODE(ip)                     @ jump to next instruction
6548    /* 10-13 instructions */
6549
6550
6551/* ------------------------------ */
6552    .balign 64
6553.L_OP_AND_INT_LIT16: /* 0xd5 */
6554/* File: armv5te/OP_AND_INT_LIT16.S */
6555/* File: armv5te/binopLit16.S */
6556    /*
6557     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6558     * that specifies an instruction that performs "result = r0 op r1".
6559     * This could be an ARM instruction or a function call.  (If the result
6560     * comes back in a register other than r0, you can override "result".)
6561     *
6562     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6563     * vCC (r1).  Useful for integer division and modulus.
6564     *
6565     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6566     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6567     */
6568    /* binop/lit16 vA, vB, #+CCCC */
6569    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6570    mov     r2, rINST, lsr #12          @ r2<- B
6571    mov     r9, rINST, lsr #8           @ r9<- A+
6572    GET_VREG(r0, r2)                    @ r0<- vB
6573    and     r9, r9, #15
6574    .if 0
6575    cmp     r1, #0                      @ is second operand zero?
6576    beq     common_errDivideByZero
6577    .endif
6578    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6579
6580    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
6581    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6582    SET_VREG(r0, r9)               @ vAA<- r0
6583    GOTO_OPCODE(ip)                     @ jump to next instruction
6584    /* 10-13 instructions */
6585
6586
6587/* ------------------------------ */
6588    .balign 64
6589.L_OP_OR_INT_LIT16: /* 0xd6 */
6590/* File: armv5te/OP_OR_INT_LIT16.S */
6591/* File: armv5te/binopLit16.S */
6592    /*
6593     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6594     * that specifies an instruction that performs "result = r0 op r1".
6595     * This could be an ARM instruction or a function call.  (If the result
6596     * comes back in a register other than r0, you can override "result".)
6597     *
6598     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6599     * vCC (r1).  Useful for integer division and modulus.
6600     *
6601     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6602     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6603     */
6604    /* binop/lit16 vA, vB, #+CCCC */
6605    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6606    mov     r2, rINST, lsr #12          @ r2<- B
6607    mov     r9, rINST, lsr #8           @ r9<- A+
6608    GET_VREG(r0, r2)                    @ r0<- vB
6609    and     r9, r9, #15
6610    .if 0
6611    cmp     r1, #0                      @ is second operand zero?
6612    beq     common_errDivideByZero
6613    .endif
6614    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6615
6616    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
6617    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6618    SET_VREG(r0, r9)               @ vAA<- r0
6619    GOTO_OPCODE(ip)                     @ jump to next instruction
6620    /* 10-13 instructions */
6621
6622
6623/* ------------------------------ */
6624    .balign 64
6625.L_OP_XOR_INT_LIT16: /* 0xd7 */
6626/* File: armv5te/OP_XOR_INT_LIT16.S */
6627/* File: armv5te/binopLit16.S */
6628    /*
6629     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6630     * that specifies an instruction that performs "result = r0 op r1".
6631     * This could be an ARM instruction or a function call.  (If the result
6632     * comes back in a register other than r0, you can override "result".)
6633     *
6634     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6635     * vCC (r1).  Useful for integer division and modulus.
6636     *
6637     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6638     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6639     */
6640    /* binop/lit16 vA, vB, #+CCCC */
6641    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6642    mov     r2, rINST, lsr #12          @ r2<- B
6643    mov     r9, rINST, lsr #8           @ r9<- A+
6644    GET_VREG(r0, r2)                    @ r0<- vB
6645    and     r9, r9, #15
6646    .if 0
6647    cmp     r1, #0                      @ is second operand zero?
6648    beq     common_errDivideByZero
6649    .endif
6650    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6651
6652    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
6653    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6654    SET_VREG(r0, r9)               @ vAA<- r0
6655    GOTO_OPCODE(ip)                     @ jump to next instruction
6656    /* 10-13 instructions */
6657
6658
6659/* ------------------------------ */
6660    .balign 64
6661.L_OP_ADD_INT_LIT8: /* 0xd8 */
6662/* File: armv5te/OP_ADD_INT_LIT8.S */
6663/* File: armv5te/binopLit8.S */
6664    /*
6665     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6666     * that specifies an instruction that performs "result = r0 op r1".
6667     * This could be an ARM instruction or a function call.  (If the result
6668     * comes back in a register other than r0, you can override "result".)
6669     *
6670     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6671     * vCC (r1).  Useful for integer division and modulus.
6672     *
6673     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6674     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6675     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6676     */
6677    /* binop/lit8 vAA, vBB, #+CC */
6678    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6679    mov     r9, rINST, lsr #8           @ r9<- AA
6680    and     r2, r3, #255                @ r2<- BB
6681    GET_VREG(r0, r2)                    @ r0<- vBB
6682    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6683    .if 0
6684    @cmp     r1, #0                      @ is second operand zero?
6685    beq     common_errDivideByZero
6686    .endif
6687    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6688
6689                               @ optional op; may set condition codes
6690    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
6691    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6692    SET_VREG(r0, r9)               @ vAA<- r0
6693    GOTO_OPCODE(ip)                     @ jump to next instruction
6694    /* 10-12 instructions */
6695
6696
6697/* ------------------------------ */
6698    .balign 64
6699.L_OP_RSUB_INT_LIT8: /* 0xd9 */
6700/* File: armv5te/OP_RSUB_INT_LIT8.S */
6701/* File: armv5te/binopLit8.S */
6702    /*
6703     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6704     * that specifies an instruction that performs "result = r0 op r1".
6705     * This could be an ARM instruction or a function call.  (If the result
6706     * comes back in a register other than r0, you can override "result".)
6707     *
6708     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6709     * vCC (r1).  Useful for integer division and modulus.
6710     *
6711     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6712     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6713     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6714     */
6715    /* binop/lit8 vAA, vBB, #+CC */
6716    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6717    mov     r9, rINST, lsr #8           @ r9<- AA
6718    and     r2, r3, #255                @ r2<- BB
6719    GET_VREG(r0, r2)                    @ r0<- vBB
6720    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6721    .if 0
6722    @cmp     r1, #0                      @ is second operand zero?
6723    beq     common_errDivideByZero
6724    .endif
6725    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6726
6727                               @ optional op; may set condition codes
6728    rsb     r0, r0, r1                              @ r0<- op, r0-r3 changed
6729    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6730    SET_VREG(r0, r9)               @ vAA<- r0
6731    GOTO_OPCODE(ip)                     @ jump to next instruction
6732    /* 10-12 instructions */
6733
6734
6735/* ------------------------------ */
6736    .balign 64
6737.L_OP_MUL_INT_LIT8: /* 0xda */
6738/* File: armv5te/OP_MUL_INT_LIT8.S */
6739/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
6740/* File: armv5te/binopLit8.S */
6741    /*
6742     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6743     * that specifies an instruction that performs "result = r0 op r1".
6744     * This could be an ARM instruction or a function call.  (If the result
6745     * comes back in a register other than r0, you can override "result".)
6746     *
6747     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6748     * vCC (r1).  Useful for integer division and modulus.
6749     *
6750     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6751     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6752     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6753     */
6754    /* binop/lit8 vAA, vBB, #+CC */
6755    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6756    mov     r9, rINST, lsr #8           @ r9<- AA
6757    and     r2, r3, #255                @ r2<- BB
6758    GET_VREG(r0, r2)                    @ r0<- vBB
6759    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6760    .if 0
6761    @cmp     r1, #0                      @ is second operand zero?
6762    beq     common_errDivideByZero
6763    .endif
6764    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6765
6766                               @ optional op; may set condition codes
6767    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
6768    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6769    SET_VREG(r0, r9)               @ vAA<- r0
6770    GOTO_OPCODE(ip)                     @ jump to next instruction
6771    /* 10-12 instructions */
6772
6773
6774/* ------------------------------ */
6775    .balign 64
6776.L_OP_DIV_INT_LIT8: /* 0xdb */
6777/* File: armv5te/OP_DIV_INT_LIT8.S */
6778/* File: armv5te/binopLit8.S */
6779    /*
6780     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6781     * that specifies an instruction that performs "result = r0 op r1".
6782     * This could be an ARM instruction or a function call.  (If the result
6783     * comes back in a register other than r0, you can override "result".)
6784     *
6785     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6786     * vCC (r1).  Useful for integer division and modulus.
6787     *
6788     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6789     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6790     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6791     */
6792    /* binop/lit8 vAA, vBB, #+CC */
6793    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6794    mov     r9, rINST, lsr #8           @ r9<- AA
6795    and     r2, r3, #255                @ r2<- BB
6796    GET_VREG(r0, r2)                    @ r0<- vBB
6797    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6798    .if 1
6799    @cmp     r1, #0                      @ is second operand zero?
6800    beq     common_errDivideByZero
6801    .endif
6802    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6803
6804                               @ optional op; may set condition codes
6805    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
6806    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6807    SET_VREG(r0, r9)               @ vAA<- r0
6808    GOTO_OPCODE(ip)                     @ jump to next instruction
6809    /* 10-12 instructions */
6810
6811
6812/* ------------------------------ */
6813    .balign 64
6814.L_OP_REM_INT_LIT8: /* 0xdc */
6815/* File: armv5te/OP_REM_INT_LIT8.S */
6816/* idivmod returns quotient in r0 and remainder in r1 */
6817/* File: armv5te/binopLit8.S */
6818    /*
6819     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6820     * that specifies an instruction that performs "result = r0 op r1".
6821     * This could be an ARM instruction or a function call.  (If the result
6822     * comes back in a register other than r0, you can override "result".)
6823     *
6824     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6825     * vCC (r1).  Useful for integer division and modulus.
6826     *
6827     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6828     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6829     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6830     */
6831    /* binop/lit8 vAA, vBB, #+CC */
6832    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6833    mov     r9, rINST, lsr #8           @ r9<- AA
6834    and     r2, r3, #255                @ r2<- BB
6835    GET_VREG(r0, r2)                    @ r0<- vBB
6836    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6837    .if 1
6838    @cmp     r1, #0                      @ is second operand zero?
6839    beq     common_errDivideByZero
6840    .endif
6841    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6842
6843                               @ optional op; may set condition codes
6844    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
6845    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6846    SET_VREG(r1, r9)               @ vAA<- r1
6847    GOTO_OPCODE(ip)                     @ jump to next instruction
6848    /* 10-12 instructions */
6849
6850
6851/* ------------------------------ */
6852    .balign 64
6853.L_OP_AND_INT_LIT8: /* 0xdd */
6854/* File: armv5te/OP_AND_INT_LIT8.S */
6855/* File: armv5te/binopLit8.S */
6856    /*
6857     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6858     * that specifies an instruction that performs "result = r0 op r1".
6859     * This could be an ARM instruction or a function call.  (If the result
6860     * comes back in a register other than r0, you can override "result".)
6861     *
6862     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6863     * vCC (r1).  Useful for integer division and modulus.
6864     *
6865     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6866     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6867     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6868     */
6869    /* binop/lit8 vAA, vBB, #+CC */
6870    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6871    mov     r9, rINST, lsr #8           @ r9<- AA
6872    and     r2, r3, #255                @ r2<- BB
6873    GET_VREG(r0, r2)                    @ r0<- vBB
6874    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6875    .if 0
6876    @cmp     r1, #0                      @ is second operand zero?
6877    beq     common_errDivideByZero
6878    .endif
6879    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6880
6881                               @ optional op; may set condition codes
6882    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
6883    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6884    SET_VREG(r0, r9)               @ vAA<- r0
6885    GOTO_OPCODE(ip)                     @ jump to next instruction
6886    /* 10-12 instructions */
6887
6888
6889/* ------------------------------ */
6890    .balign 64
6891.L_OP_OR_INT_LIT8: /* 0xde */
6892/* File: armv5te/OP_OR_INT_LIT8.S */
6893/* File: armv5te/binopLit8.S */
6894    /*
6895     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6896     * that specifies an instruction that performs "result = r0 op r1".
6897     * This could be an ARM instruction or a function call.  (If the result
6898     * comes back in a register other than r0, you can override "result".)
6899     *
6900     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6901     * vCC (r1).  Useful for integer division and modulus.
6902     *
6903     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6904     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6905     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6906     */
6907    /* binop/lit8 vAA, vBB, #+CC */
6908    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6909    mov     r9, rINST, lsr #8           @ r9<- AA
6910    and     r2, r3, #255                @ r2<- BB
6911    GET_VREG(r0, r2)                    @ r0<- vBB
6912    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6913    .if 0
6914    @cmp     r1, #0                      @ is second operand zero?
6915    beq     common_errDivideByZero
6916    .endif
6917    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6918
6919                               @ optional op; may set condition codes
6920    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
6921    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6922    SET_VREG(r0, r9)               @ vAA<- r0
6923    GOTO_OPCODE(ip)                     @ jump to next instruction
6924    /* 10-12 instructions */
6925
6926
6927/* ------------------------------ */
6928    .balign 64
6929.L_OP_XOR_INT_LIT8: /* 0xdf */
6930/* File: armv5te/OP_XOR_INT_LIT8.S */
6931/* File: armv5te/binopLit8.S */
6932    /*
6933     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6934     * that specifies an instruction that performs "result = r0 op r1".
6935     * This could be an ARM instruction or a function call.  (If the result
6936     * comes back in a register other than r0, you can override "result".)
6937     *
6938     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6939     * vCC (r1).  Useful for integer division and modulus.
6940     *
6941     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6942     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6943     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6944     */
6945    /* binop/lit8 vAA, vBB, #+CC */
6946    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6947    mov     r9, rINST, lsr #8           @ r9<- AA
6948    and     r2, r3, #255                @ r2<- BB
6949    GET_VREG(r0, r2)                    @ r0<- vBB
6950    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6951    .if 0
6952    @cmp     r1, #0                      @ is second operand zero?
6953    beq     common_errDivideByZero
6954    .endif
6955    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6956
6957                               @ optional op; may set condition codes
6958    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
6959    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6960    SET_VREG(r0, r9)               @ vAA<- r0
6961    GOTO_OPCODE(ip)                     @ jump to next instruction
6962    /* 10-12 instructions */
6963
6964
6965/* ------------------------------ */
6966    .balign 64
6967.L_OP_SHL_INT_LIT8: /* 0xe0 */
6968/* File: armv5te/OP_SHL_INT_LIT8.S */
6969/* File: armv5te/binopLit8.S */
6970    /*
6971     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6972     * that specifies an instruction that performs "result = r0 op r1".
6973     * This could be an ARM instruction or a function call.  (If the result
6974     * comes back in a register other than r0, you can override "result".)
6975     *
6976     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6977     * vCC (r1).  Useful for integer division and modulus.
6978     *
6979     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6980     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6981     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6982     */
6983    /* binop/lit8 vAA, vBB, #+CC */
6984    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6985    mov     r9, rINST, lsr #8           @ r9<- AA
6986    and     r2, r3, #255                @ r2<- BB
6987    GET_VREG(r0, r2)                    @ r0<- vBB
6988    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6989    .if 0
6990    @cmp     r1, #0                      @ is second operand zero?
6991    beq     common_errDivideByZero
6992    .endif
6993    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6994
6995    and     r1, r1, #31                           @ optional op; may set condition codes
6996    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
6997    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6998    SET_VREG(r0, r9)               @ vAA<- r0
6999    GOTO_OPCODE(ip)                     @ jump to next instruction
7000    /* 10-12 instructions */
7001
7002
7003/* ------------------------------ */
7004    .balign 64
7005.L_OP_SHR_INT_LIT8: /* 0xe1 */
7006/* File: armv5te/OP_SHR_INT_LIT8.S */
7007/* File: armv5te/binopLit8.S */
7008    /*
7009     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7010     * that specifies an instruction that performs "result = r0 op r1".
7011     * This could be an ARM instruction or a function call.  (If the result
7012     * comes back in a register other than r0, you can override "result".)
7013     *
7014     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7015     * vCC (r1).  Useful for integer division and modulus.
7016     *
7017     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7018     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7019     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7020     */
7021    /* binop/lit8 vAA, vBB, #+CC */
7022    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7023    mov     r9, rINST, lsr #8           @ r9<- AA
7024    and     r2, r3, #255                @ r2<- BB
7025    GET_VREG(r0, r2)                    @ r0<- vBB
7026    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7027    .if 0
7028    @cmp     r1, #0                      @ is second operand zero?
7029    beq     common_errDivideByZero
7030    .endif
7031    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7032
7033    and     r1, r1, #31                           @ optional op; may set condition codes
7034    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
7035    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7036    SET_VREG(r0, r9)               @ vAA<- r0
7037    GOTO_OPCODE(ip)                     @ jump to next instruction
7038    /* 10-12 instructions */
7039
7040
7041/* ------------------------------ */
7042    .balign 64
7043.L_OP_USHR_INT_LIT8: /* 0xe2 */
7044/* File: armv5te/OP_USHR_INT_LIT8.S */
7045/* File: armv5te/binopLit8.S */
7046    /*
7047     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7048     * that specifies an instruction that performs "result = r0 op r1".
7049     * This could be an ARM instruction or a function call.  (If the result
7050     * comes back in a register other than r0, you can override "result".)
7051     *
7052     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7053     * vCC (r1).  Useful for integer division and modulus.
7054     *
7055     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7056     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7057     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7058     */
7059    /* binop/lit8 vAA, vBB, #+CC */
7060    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7061    mov     r9, rINST, lsr #8           @ r9<- AA
7062    and     r2, r3, #255                @ r2<- BB
7063    GET_VREG(r0, r2)                    @ r0<- vBB
7064    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7065    .if 0
7066    @cmp     r1, #0                      @ is second operand zero?
7067    beq     common_errDivideByZero
7068    .endif
7069    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7070
7071    and     r1, r1, #31                           @ optional op; may set condition codes
7072    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
7073    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7074    SET_VREG(r0, r9)               @ vAA<- r0
7075    GOTO_OPCODE(ip)                     @ jump to next instruction
7076    /* 10-12 instructions */
7077
7078
7079/* ------------------------------ */
7080    .balign 64
7081.L_OP_IGET_VOLATILE: /* 0xe3 */
7082/* File: armv5te/OP_IGET_VOLATILE.S */
7083/* File: armv5te/OP_IGET.S */
7084    /*
7085     * General 32-bit instance field get.
7086     *
7087     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7088     */
7089    /* op vA, vB, field@CCCC */
7090    mov     r0, rINST, lsr #12          @ r0<- B
7091    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7092    FETCH(r1, 1)                        @ r1<- field ref CCCC
7093    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7094    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7095    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7096    cmp     r0, #0                      @ is resolved entry null?
7097    bne     .LOP_IGET_VOLATILE_finish          @ no, already resolved
70988:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7099    EXPORT_PC()                         @ resolve() could throw
7100    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7101    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7102    cmp     r0, #0
7103    bne     .LOP_IGET_VOLATILE_finish
7104    b       common_exceptionThrown
7105
7106
7107/* ------------------------------ */
7108    .balign 64
7109.L_OP_IPUT_VOLATILE: /* 0xe4 */
7110/* File: armv5te/OP_IPUT_VOLATILE.S */
7111/* File: armv5te/OP_IPUT.S */
7112    /*
7113     * General 32-bit instance field put.
7114     *
7115     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
7116     */
7117    /* op vA, vB, field@CCCC */
7118    mov     r0, rINST, lsr #12          @ r0<- B
7119    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7120    FETCH(r1, 1)                        @ r1<- field ref CCCC
7121    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7122    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7123    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7124    cmp     r0, #0                      @ is resolved entry null?
7125    bne     .LOP_IPUT_VOLATILE_finish          @ no, already resolved
71268:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7127    EXPORT_PC()                         @ resolve() could throw
7128    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7129    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7130    cmp     r0, #0                      @ success?
7131    bne     .LOP_IPUT_VOLATILE_finish          @ yes, finish up
7132    b       common_exceptionThrown
7133
7134
7135/* ------------------------------ */
7136    .balign 64
7137.L_OP_SGET_VOLATILE: /* 0xe5 */
7138/* File: armv5te/OP_SGET_VOLATILE.S */
7139/* File: armv5te/OP_SGET.S */
7140    /*
7141     * General 32-bit SGET handler.
7142     *
7143     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7144     */
7145    /* op vAA, field@BBBB */
7146    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7147    FETCH(r1, 1)                        @ r1<- field ref BBBB
7148    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7149    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7150    cmp     r0, #0                      @ is resolved entry null?
7151    beq     .LOP_SGET_VOLATILE_resolve         @ yes, do resolve
7152.LOP_SGET_VOLATILE_finish: @ field ptr in r0
7153    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7154    SMP_DMB                            @ acquiring load
7155    mov     r2, rINST, lsr #8           @ r2<- AA
7156    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7157    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7158    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7159    GOTO_OPCODE(ip)                     @ jump to next instruction
7160
7161
7162/* ------------------------------ */
7163    .balign 64
7164.L_OP_SPUT_VOLATILE: /* 0xe6 */
7165/* File: armv5te/OP_SPUT_VOLATILE.S */
7166/* File: armv5te/OP_SPUT.S */
7167    /*
7168     * General 32-bit SPUT handler.
7169     *
7170     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
7171     */
7172    /* op vAA, field@BBBB */
7173    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7174    FETCH(r1, 1)                        @ r1<- field ref BBBB
7175    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7176    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7177    cmp     r0, #0                      @ is resolved entry null?
7178    beq     .LOP_SPUT_VOLATILE_resolve         @ yes, do resolve
7179.LOP_SPUT_VOLATILE_finish:   @ field ptr in r0
7180    mov     r2, rINST, lsr #8           @ r2<- AA
7181    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7182    GET_VREG(r1, r2)                    @ r1<- fp[AA]
7183    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7184    SMP_DMB                            @ releasing store
7185    str     r1, [r0, #offStaticField_value] @ field<- vAA
7186    GOTO_OPCODE(ip)                     @ jump to next instruction
7187
7188
7189/* ------------------------------ */
7190    .balign 64
7191.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
7192/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */
7193/* File: armv5te/OP_IGET.S */
7194    /*
7195     * General 32-bit instance field get.
7196     *
7197     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7198     */
7199    /* op vA, vB, field@CCCC */
7200    mov     r0, rINST, lsr #12          @ r0<- B
7201    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7202    FETCH(r1, 1)                        @ r1<- field ref CCCC
7203    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7204    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7205    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7206    cmp     r0, #0                      @ is resolved entry null?
7207    bne     .LOP_IGET_OBJECT_VOLATILE_finish          @ no, already resolved
72088:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7209    EXPORT_PC()                         @ resolve() could throw
7210    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7211    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7212    cmp     r0, #0
7213    bne     .LOP_IGET_OBJECT_VOLATILE_finish
7214    b       common_exceptionThrown
7215
7216
7217/* ------------------------------ */
7218    .balign 64
7219.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
7220/* File: armv5te/OP_IGET_WIDE_VOLATILE.S */
7221/* File: armv5te/OP_IGET_WIDE.S */
7222    /*
7223     * Wide 32-bit instance field get.
7224     */
7225    /* iget-wide vA, vB, field@CCCC */
7226    mov     r0, rINST, lsr #12          @ r0<- B
7227    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7228    FETCH(r1, 1)                        @ r1<- field ref CCCC
7229    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7230    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7231    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7232    cmp     r0, #0                      @ is resolved entry null?
7233    bne     .LOP_IGET_WIDE_VOLATILE_finish          @ no, already resolved
72348:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
7235    EXPORT_PC()                         @ resolve() could throw
7236    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7237    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7238    cmp     r0, #0
7239    bne     .LOP_IGET_WIDE_VOLATILE_finish
7240    b       common_exceptionThrown
7241
7242
7243/* ------------------------------ */
7244    .balign 64
7245.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
7246/* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */
7247/* File: armv5te/OP_IPUT_WIDE.S */
7248    /* iput-wide vA, vB, field@CCCC */
7249    mov     r0, rINST, lsr #12          @ r0<- B
7250    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7251    FETCH(r1, 1)                        @ r1<- field ref CCCC
7252    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7253    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7254    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7255    cmp     r0, #0                      @ is resolved entry null?
7256    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ no, already resolved
72578:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
7258    EXPORT_PC()                         @ resolve() could throw
7259    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7260    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7261    cmp     r0, #0                      @ success?
7262    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ yes, finish up
7263    b       common_exceptionThrown
7264
7265
7266/* ------------------------------ */
7267    .balign 64
7268.L_OP_SGET_WIDE_VOLATILE: /* 0xea */
7269/* File: armv5te/OP_SGET_WIDE_VOLATILE.S */
7270/* File: armv5te/OP_SGET_WIDE.S */
7271    /*
7272     * 64-bit SGET handler.
7273     */
7274    /* sget-wide vAA, field@BBBB */
7275    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7276    FETCH(r1, 1)                        @ r1<- field ref BBBB
7277    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7278    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7279    cmp     r0, #0                      @ is resolved entry null?
7280    beq     .LOP_SGET_WIDE_VOLATILE_resolve         @ yes, do resolve
7281.LOP_SGET_WIDE_VOLATILE_finish:
7282    mov     r9, rINST, lsr #8           @ r9<- AA
7283    .if 1
7284    add     r0, r0, #offStaticField_value @ r0<- pointer to data
7285    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
7286    .else
7287    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
7288    .endif
7289    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7290    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7291    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
7292    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7293    GOTO_OPCODE(ip)                     @ jump to next instruction
7294
7295
7296/* ------------------------------ */
7297    .balign 64
7298.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
7299/* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */
7300/* File: armv5te/OP_SPUT_WIDE.S */
7301    /*
7302     * 64-bit SPUT handler.
7303     */
7304    /* sput-wide vAA, field@BBBB */
7305    ldr     r0, [rGLUE, #offGlue_methodClassDex]  @ r0<- DvmDex
7306    FETCH(r1, 1)                        @ r1<- field ref BBBB
7307    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
7308    mov     r9, rINST, lsr #8           @ r9<- AA
7309    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
7310    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7311    cmp     r2, #0                      @ is resolved entry null?
7312    beq     .LOP_SPUT_WIDE_VOLATILE_resolve         @ yes, do resolve
7313.LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9
7314    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7315    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
7316    GET_INST_OPCODE(r10)                @ extract opcode from rINST
7317    .if 1
7318    add     r2, r2, #offStaticField_value @ r2<- pointer to data
7319    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
7320    .else
7321    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
7322    .endif
7323    GOTO_OPCODE(r10)                    @ jump to next instruction
7324
7325
7326/* ------------------------------ */
7327    .balign 64
7328.L_OP_BREAKPOINT: /* 0xec */
7329/* File: armv5te/OP_BREAKPOINT.S */
7330/* File: armv5te/unused.S */
7331    bl      common_abort
7332
7333
7334/* ------------------------------ */
7335    .balign 64
7336.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
7337/* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */
7338    /*
7339     * Handle a throw-verification-error instruction.  This throws an
7340     * exception for an error discovered during verification.  The
7341     * exception is indicated by AA, with some detail provided by BBBB.
7342     */
7343    /* op AA, ref@BBBB */
7344    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
7345    FETCH(r2, 1)                        @ r2<- BBBB
7346    EXPORT_PC()                         @ export the PC
7347    mov     r1, rINST, lsr #8           @ r1<- AA
7348    bl      dvmThrowVerificationError   @ always throws
7349    b       common_exceptionThrown      @ handle exception
7350
7351/* ------------------------------ */
7352    .balign 64
7353.L_OP_EXECUTE_INLINE: /* 0xee */
7354/* File: armv5te/OP_EXECUTE_INLINE.S */
7355    /*
7356     * Execute a "native inline" instruction.
7357     *
7358     * We need to call an InlineOp4Func:
7359     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7360     *
7361     * The first four args are in r0-r3, pointer to return value storage
7362     * is on the stack.  The function's return value is a flag that tells
7363     * us if an exception was thrown.
7364     */
7365    /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
7366    FETCH(r10, 1)                       @ r10<- BBBB
7367    add     r1, rGLUE, #offGlue_retval  @ r1<- &glue->retval
7368    EXPORT_PC()                         @ can throw
7369    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7370    mov     r0, rINST, lsr #12          @ r0<- B
7371    str     r1, [sp]                    @ push &glue->retval
7372    bl      .LOP_EXECUTE_INLINE_continue        @ make call; will return after
7373    add     sp, sp, #8                  @ pop stack
7374    cmp     r0, #0                      @ test boolean result of inline
7375    beq     common_exceptionThrown      @ returned false, handle exception
7376    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7377    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7378    GOTO_OPCODE(ip)                     @ jump to next instruction
7379
7380/* ------------------------------ */
7381    .balign 64
7382.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
7383/* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */
7384    /*
7385     * Execute a "native inline" instruction, using "/range" semantics.
7386     * Same idea as execute-inline, but we get the args differently.
7387     *
7388     * We need to call an InlineOp4Func:
7389     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7390     *
7391     * The first four args are in r0-r3, pointer to return value storage
7392     * is on the stack.  The function's return value is a flag that tells
7393     * us if an exception was thrown.
7394     */
7395    /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */
7396    FETCH(r10, 1)                       @ r10<- BBBB
7397    add     r1, rGLUE, #offGlue_retval  @ r1<- &glue->retval
7398    EXPORT_PC()                         @ can throw
7399    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7400    mov     r0, rINST, lsr #8           @ r0<- AA
7401    str     r1, [sp]                    @ push &glue->retval
7402    bl      .LOP_EXECUTE_INLINE_RANGE_continue        @ make call; will return after
7403    add     sp, sp, #8                  @ pop stack
7404    cmp     r0, #0                      @ test boolean result of inline
7405    beq     common_exceptionThrown      @ returned false, handle exception
7406    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7407    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7408    GOTO_OPCODE(ip)                     @ jump to next instruction
7409
7410/* ------------------------------ */
7411    .balign 64
7412.L_OP_INVOKE_OBJECT_INIT: /* 0xf0 */
7413/* File: armv5te/OP_INVOKE_OBJECT_INIT.S */
7414    /*
7415     * Invoke Object.<init> on an object.  In practice we know that
7416     * Object's nullary constructor doesn't do anything, so we just
7417     * skip it (we know a debugger isn't active).
7418     */
7419    FETCH(r0, 2)                        @ r0<- GFED
7420    and     r1, r0, #15                 @ r1<- D
7421    GET_VREG(r0, r1)                    @ r0<- "this" ptr
7422    cmp     r0, #0                      @ check for NULL
7423    beq     common_errNullObject        @ export PC and throw NPE
7424    ldr     r1, [r0, #offObject_clazz]  @ r1<- obj->clazz
7425    ldr     r2, [r1, #offClassObject_accessFlags] @ r2<- clazz->accessFlags
7426    tst     r2, #CLASS_ISFINALIZABLE    @ is this class finalizable?
7427    beq     1f                          @ nope, done
7428    bl      dvmSetFinalizable           @ call dvmSetFinalizable(obj)
74291:  FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
7430    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
7431    GOTO_OPCODE(ip)                     @ execute it
7432
7433/* ------------------------------ */
7434    .balign 64
7435.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */
7436/* File: armv5te/OP_RETURN_VOID_BARRIER.S */
7437    SMP_DMB_ST
7438    b       common_returnFromMethod
7439
7440/* ------------------------------ */
7441    .balign 64
7442.L_OP_IGET_QUICK: /* 0xf2 */
7443/* File: armv5te/OP_IGET_QUICK.S */
7444    /* For: iget-quick, iget-object-quick */
7445    /* op vA, vB, offset@CCCC */
7446    mov     r2, rINST, lsr #12          @ r2<- B
7447    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7448    FETCH(r1, 1)                        @ r1<- field byte offset
7449    cmp     r3, #0                      @ check object for null
7450    mov     r2, rINST, lsr #8           @ r2<- A(+)
7451    beq     common_errNullObject        @ object was null
7452    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7453    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7454    and     r2, r2, #15
7455    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7456    SET_VREG(r0, r2)                    @ fp[A]<- r0
7457    GOTO_OPCODE(ip)                     @ jump to next instruction
7458
7459/* ------------------------------ */
7460    .balign 64
7461.L_OP_IGET_WIDE_QUICK: /* 0xf3 */
7462/* File: armv5te/OP_IGET_WIDE_QUICK.S */
7463    /* iget-wide-quick vA, vB, offset@CCCC */
7464    mov     r2, rINST, lsr #12          @ r2<- B
7465    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7466    FETCH(ip, 1)                        @ ip<- field byte offset
7467    cmp     r3, #0                      @ check object for null
7468    mov     r2, rINST, lsr #8           @ r2<- A(+)
7469    beq     common_errNullObject        @ object was null
7470    ldrd    r0, [r3, ip]                @ r0<- obj.field (64 bits, aligned)
7471    and     r2, r2, #15
7472    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7473    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
7474    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7475    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
7476    GOTO_OPCODE(ip)                     @ jump to next instruction
7477
7478/* ------------------------------ */
7479    .balign 64
7480.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */
7481/* File: armv5te/OP_IGET_OBJECT_QUICK.S */
7482/* File: armv5te/OP_IGET_QUICK.S */
7483    /* For: iget-quick, iget-object-quick */
7484    /* op vA, vB, offset@CCCC */
7485    mov     r2, rINST, lsr #12          @ r2<- B
7486    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7487    FETCH(r1, 1)                        @ r1<- field byte offset
7488    cmp     r3, #0                      @ check object for null
7489    mov     r2, rINST, lsr #8           @ r2<- A(+)
7490    beq     common_errNullObject        @ object was null
7491    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7492    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7493    and     r2, r2, #15
7494    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7495    SET_VREG(r0, r2)                    @ fp[A]<- r0
7496    GOTO_OPCODE(ip)                     @ jump to next instruction
7497
7498
7499/* ------------------------------ */
7500    .balign 64
7501.L_OP_IPUT_QUICK: /* 0xf5 */
7502/* File: armv5te/OP_IPUT_QUICK.S */
7503    /* For: iput-quick */
7504    /* op vA, vB, offset@CCCC */
7505    mov     r2, rINST, lsr #12          @ r2<- B
7506    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7507    FETCH(r1, 1)                        @ r1<- field byte offset
7508    cmp     r3, #0                      @ check object for null
7509    mov     r2, rINST, lsr #8           @ r2<- A(+)
7510    beq     common_errNullObject        @ object was null
7511    and     r2, r2, #15
7512    GET_VREG(r0, r2)                    @ r0<- fp[A]
7513    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7514    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7515    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7516    GOTO_OPCODE(ip)                     @ jump to next instruction
7517
7518/* ------------------------------ */
7519    .balign 64
7520.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */
7521/* File: armv5te/OP_IPUT_WIDE_QUICK.S */
7522    /* iput-wide-quick vA, vB, offset@CCCC */
7523    mov     r0, rINST, lsr #8           @ r0<- A(+)
7524    mov     r1, rINST, lsr #12          @ r1<- B
7525    and     r0, r0, #15
7526    GET_VREG(r2, r1)                    @ r2<- fp[B], the object pointer
7527    add     r3, rFP, r0, lsl #2         @ r3<- &fp[A]
7528    cmp     r2, #0                      @ check object for null
7529    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[A]
7530    beq     common_errNullObject        @ object was null
7531    FETCH(r3, 1)                        @ r3<- field byte offset
7532    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7533    strd    r0, [r2, r3]                @ obj.field (64 bits, aligned)<- r0/r1
7534    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7535    GOTO_OPCODE(ip)                     @ jump to next instruction
7536
7537/* ------------------------------ */
7538    .balign 64
7539.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
7540/* File: armv5te/OP_IPUT_OBJECT_QUICK.S */
7541    /* For: iput-object-quick */
7542    /* op vA, vB, offset@CCCC */
7543    mov     r2, rINST, lsr #12          @ r2<- B
7544    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7545    FETCH(r1, 1)                        @ r1<- field byte offset
7546    cmp     r3, #0                      @ check object for null
7547    mov     r2, rINST, lsr #8           @ r2<- A(+)
7548    beq     common_errNullObject        @ object was null
7549    and     r2, r2, #15
7550    GET_VREG(r0, r2)                    @ r0<- fp[A]
7551    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
7552    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7553    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7554    cmp     r0, #0
7555    strneb  r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head
7556    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7557    GOTO_OPCODE(ip)                     @ jump to next instruction
7558
7559/* ------------------------------ */
7560    .balign 64
7561.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
7562/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7563    /*
7564     * Handle an optimized virtual method call.
7565     *
7566     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7567     */
7568    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7569    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7570    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7571    FETCH(r1, 1)                        @ r1<- BBBB
7572    .if     (!0)
7573    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7574    .endif
7575    GET_VREG(r2, r3)                    @ r2<- vC ("this" ptr)
7576    cmp     r2, #0                      @ is "this" null?
7577    beq     common_errNullObject        @ null "this", throw exception
7578    ldr     r2, [r2, #offObject_clazz]  @ r2<- thisPtr->clazz
7579    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7580    EXPORT_PC()                         @ invoke must export
7581    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7582    bl      common_invokeMethodNoRange @ continue on
7583
7584/* ------------------------------ */
7585    .balign 64
7586.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
7587/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */
7588/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7589    /*
7590     * Handle an optimized virtual method call.
7591     *
7592     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7593     */
7594    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7595    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7596    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7597    FETCH(r1, 1)                        @ r1<- BBBB
7598    .if     (!1)
7599    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7600    .endif
7601    GET_VREG(r2, r3)                    @ r2<- vC ("this" ptr)
7602    cmp     r2, #0                      @ is "this" null?
7603    beq     common_errNullObject        @ null "this", throw exception
7604    ldr     r2, [r2, #offObject_clazz]  @ r2<- thisPtr->clazz
7605    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7606    EXPORT_PC()                         @ invoke must export
7607    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7608    bl      common_invokeMethodRange @ continue on
7609
7610
7611/* ------------------------------ */
7612    .balign 64
7613.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */
7614/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7615    /*
7616     * Handle an optimized "super" method call.
7617     *
7618     * for: [opt] invoke-super-quick, invoke-super-quick/range
7619     */
7620    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7621    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7622    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7623    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7624    .if     (!0)
7625    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7626    .endif
7627    FETCH(r1, 1)                        @ r1<- BBBB
7628    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7629    EXPORT_PC()                         @ must export for invoke
7630    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7631    GET_VREG(r3, r10)                   @ r3<- "this"
7632    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7633    cmp     r3, #0                      @ null "this" ref?
7634    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7635    beq     common_errNullObject        @ "this" is null, throw exception
7636    bl      common_invokeMethodNoRange @ continue on
7637
7638/* ------------------------------ */
7639    .balign 64
7640.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
7641/* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */
7642/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7643    /*
7644     * Handle an optimized "super" method call.
7645     *
7646     * for: [opt] invoke-super-quick, invoke-super-quick/range
7647     */
7648    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7649    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7650    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7651    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7652    .if     (!1)
7653    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7654    .endif
7655    FETCH(r1, 1)                        @ r1<- BBBB
7656    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7657    EXPORT_PC()                         @ must export for invoke
7658    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7659    GET_VREG(r3, r10)                   @ r3<- "this"
7660    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7661    cmp     r3, #0                      @ null "this" ref?
7662    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7663    beq     common_errNullObject        @ "this" is null, throw exception
7664    bl      common_invokeMethodRange @ continue on
7665
7666
7667/* ------------------------------ */
7668    .balign 64
7669.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
7670/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */
7671/* File: armv5te/OP_IPUT_OBJECT.S */
7672    /*
7673     * 32-bit instance field put.
7674     *
7675     * for: iput-object, iput-object-volatile
7676     */
7677    /* op vA, vB, field@CCCC */
7678    mov     r0, rINST, lsr #12          @ r0<- B
7679    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7680    FETCH(r1, 1)                        @ r1<- field ref CCCC
7681    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7682    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7683    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7684    cmp     r0, #0                      @ is resolved entry null?
7685    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ no, already resolved
76868:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7687    EXPORT_PC()                         @ resolve() could throw
7688    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7689    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7690    cmp     r0, #0                      @ success?
7691    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ yes, finish up
7692    b       common_exceptionThrown
7693
7694
7695/* ------------------------------ */
7696    .balign 64
7697.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
7698/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */
7699/* File: armv5te/OP_SGET.S */
7700    /*
7701     * General 32-bit SGET handler.
7702     *
7703     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7704     */
7705    /* op vAA, field@BBBB */
7706    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7707    FETCH(r1, 1)                        @ r1<- field ref BBBB
7708    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7709    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7710    cmp     r0, #0                      @ is resolved entry null?
7711    beq     .LOP_SGET_OBJECT_VOLATILE_resolve         @ yes, do resolve
7712.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0
7713    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7714    SMP_DMB                            @ acquiring load
7715    mov     r2, rINST, lsr #8           @ r2<- AA
7716    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7717    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7718    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7719    GOTO_OPCODE(ip)                     @ jump to next instruction
7720
7721
7722/* ------------------------------ */
7723    .balign 64
7724.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
7725/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */
7726/* File: armv5te/OP_SPUT_OBJECT.S */
7727    /*
7728     * 32-bit SPUT handler for objects
7729     *
7730     * for: sput-object, sput-object-volatile
7731     */
7732    /* op vAA, field@BBBB */
7733    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7734    FETCH(r1, 1)                        @ r1<- field ref BBBB
7735    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7736    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7737    cmp     r0, #0                      @ is resolved entry null?
7738    bne     .LOP_SPUT_OBJECT_VOLATILE_finish          @ no, continue
7739    ldr     r9, [rGLUE, #offGlue_method]    @ r9<- current method
7740    EXPORT_PC()                         @ resolve() could throw, so export now
7741    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
7742    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
7743    cmp     r0, #0                      @ success?
7744    bne     .LOP_SPUT_OBJECT_VOLATILE_finish          @ yes, finish
7745    b       common_exceptionThrown      @ no, handle exception
7746
7747
7748
7749/* ------------------------------ */
7750    .balign 64
7751.L_OP_DISPATCH_FF: /* 0xff */
7752/* File: armv5te/OP_DISPATCH_FF.S */
7753    mov     ip, rINST, lsr #8           @ r9<- extended opcode
7754    add     ip, ip, #256                @ add offset for extended opcodes
7755    GOTO_OPCODE(ip)                     @ go to proper extended handler
7756
7757
7758/* ------------------------------ */
7759    .balign 64
7760.L_OP_CONST_CLASS_JUMBO: /* 0x100 */
7761/* File: armv5te/OP_CONST_CLASS_JUMBO.S */
7762    /* const-class/jumbo vBBBB, Class@AAAAAAAA */
7763    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7764    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- glue->methodClassDex
7765    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7766    ldr     r2, [r2, #offDvmDex_pResClasses]   @ r2<- dvmDex->pResClasses
7767    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7768    FETCH(r9, 3)                        @ r9<- BBBB
7769    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResClasses[AAAAaaaa]
7770    cmp     r0, #0                      @ not yet resolved?
7771    beq     .LOP_CONST_CLASS_JUMBO_resolve
7772    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
7773    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7774    SET_VREG(r0, r9)                    @ vBBBB<- r0
7775    GOTO_OPCODE(ip)                     @ jump to next instruction
7776
7777/* ------------------------------ */
7778    .balign 64
7779.L_OP_CHECK_CAST_JUMBO: /* 0x101 */
7780/* File: armv5te/OP_CHECK_CAST_JUMBO.S */
7781    /*
7782     * Check to see if a cast from one class to another is allowed.
7783     */
7784    /* check-cast/jumbo vBBBB, class@AAAAAAAA */
7785    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7786    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7787    FETCH(r3, 3)                        @ r3<- BBBB
7788    orr     r2, r0, r2, lsl #16         @ r2<- AAAAaaaa
7789    GET_VREG(r9, r3)                    @ r9<- object
7790    ldr     r0, [rGLUE, #offGlue_methodClassDex]    @ r0<- pDvmDex
7791    cmp     r9, #0                      @ is object null?
7792    ldr     r0, [r0, #offDvmDex_pResClasses]    @ r0<- pDvmDex->pResClasses
7793    beq     .LOP_CHECK_CAST_JUMBO_okay            @ null obj, cast always succeeds
7794    ldr     r1, [r0, r2, lsl #2]        @ r1<- resolved class
7795    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
7796    cmp     r1, #0                      @ have we resolved this before?
7797    beq     .LOP_CHECK_CAST_JUMBO_resolve         @ not resolved, do it now
7798.LOP_CHECK_CAST_JUMBO_resolved:
7799    cmp     r0, r1                      @ same class (trivial success)?
7800    bne     .LOP_CHECK_CAST_JUMBO_fullcheck       @ no, do full check
7801    b       .LOP_CHECK_CAST_JUMBO_okay            @ yes, finish up
7802
7803/* ------------------------------ */
7804    .balign 64
7805.L_OP_INSTANCE_OF_JUMBO: /* 0x102 */
7806/* File: armv5te/OP_INSTANCE_OF_JUMBO.S */
7807    /*
7808     * Check to see if an object reference is an instance of a class.
7809     *
7810     * Most common situation is a non-null object, being compared against
7811     * an already-resolved class.
7812     *
7813     * TODO: convert most of this into a common subroutine, shared with
7814     *       OP_INSTANCE_OF.S.
7815     */
7816    /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */
7817    FETCH(r3, 4)                        @ r3<- vCCCC
7818    FETCH(r9, 3)                        @ r9<- vBBBB
7819    GET_VREG(r0, r3)                    @ r0<- vCCCC (object)
7820    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- pDvmDex
7821    cmp     r0, #0                      @ is object null?
7822    beq     .LOP_INSTANCE_OF_JUMBO_store           @ null obj, not an instance, store r0
7823    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7824    FETCH(r3, 2)                        @ r3<- AAAA (hi)
7825    ldr     r2, [r2, #offDvmDex_pResClasses]    @ r2<- pDvmDex->pResClasses
7826    orr     r3, r1, r3, lsl #16         @ r3<- AAAAaaaa
7827    ldr     r1, [r2, r3, lsl #2]        @ r1<- resolved class
7828    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
7829    cmp     r1, #0                      @ have we resolved this before?
7830    beq     .LOP_INSTANCE_OF_JUMBO_resolve         @ not resolved, do it now
7831    b       .LOP_INSTANCE_OF_JUMBO_resolved        @ resolved, continue
7832
7833/* ------------------------------ */
7834    .balign 64
7835.L_OP_NEW_INSTANCE_JUMBO: /* 0x103 */
7836/* File: armv5te/OP_NEW_INSTANCE_JUMBO.S */
7837    /*
7838     * Create a new instance of a class.
7839     */
7840    /* new-instance/jumbo vBBBB, class@AAAAAAAA */
7841    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7842    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7843    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
7844    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7845    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7846    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
7847    EXPORT_PC()                         @ req'd for init, resolve, alloc
7848    cmp     r0, #0                      @ already resolved?
7849    beq     .LOP_NEW_INSTANCE_JUMBO_resolve         @ no, resolve it now
7850.LOP_NEW_INSTANCE_JUMBO_resolved:   @ r0=class
7851    ldrb    r1, [r0, #offClassObject_status]    @ r1<- ClassStatus enum
7852    cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
7853    bne     .LOP_NEW_INSTANCE_JUMBO_needinit        @ no, init class now
7854.LOP_NEW_INSTANCE_JUMBO_initialized: @ r0=class
7855    mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
7856    bl      dvmAllocObject              @ r0<- new object
7857    b       .LOP_NEW_INSTANCE_JUMBO_finish          @ continue
7858
7859/* ------------------------------ */
7860    .balign 64
7861.L_OP_NEW_ARRAY_JUMBO: /* 0x104 */
7862/* File: armv5te/OP_NEW_ARRAY_JUMBO.S */
7863    /*
7864     * Allocate an array of objects, specified with the array class
7865     * and a count.
7866     *
7867     * The verifier guarantees that this is an array class, so we don't
7868     * check for it here.
7869     */
7870    /* new-array/jumbo vBBBB, vCCCC, class@AAAAAAAA */
7871    FETCH(r2, 1)                        @ r2<- aaaa (lo)
7872    FETCH(r3, 2)                        @ r3<- AAAA (hi)
7873    FETCH(r0, 4)                        @ r0<- vCCCC
7874    orr     r2, r2, r3, lsl #16         @ r2<- AAAAaaaa
7875    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
7876    GET_VREG(r1, r0)                    @ r1<- vCCCC (array length)
7877    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7878    cmp     r1, #0                      @ check length
7879    ldr     r0, [r3, r2, lsl #2]        @ r0<- resolved class
7880    bmi     common_errNegativeArraySize @ negative length, bail
7881    cmp     r0, #0                      @ already resolved?
7882    EXPORT_PC()                         @ req'd for resolve, alloc
7883    bne     .LOP_NEW_ARRAY_JUMBO_finish          @ resolved, continue
7884    b       .LOP_NEW_ARRAY_JUMBO_resolve         @ do resolve now
7885
7886/* ------------------------------ */
7887    .balign 64
7888.L_OP_FILLED_NEW_ARRAY_JUMBO: /* 0x105 */
7889/* File: armv5te/OP_FILLED_NEW_ARRAY_JUMBO.S */
7890    /*
7891     * Create a new array with elements filled from registers.
7892     *
7893     * TODO: convert most of this into a common subroutine, shared with
7894     *       OP_FILLED_NEW_ARRAY.S.
7895     */
7896    /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */
7897    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
7898    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7899    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7900    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7901    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7902    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
7903    EXPORT_PC()                         @ need for resolve and alloc
7904    cmp     r0, #0                      @ already resolved?
7905    bne     .LOP_FILLED_NEW_ARRAY_JUMBO_continue        @ yes, continue on
79068:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
7907    mov     r2, #0                      @ r2<- false
7908    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
7909    bl      dvmResolveClass             @ r0<- call(clazz, ref)
7910    cmp     r0, #0                      @ got null?
7911    beq     common_exceptionThrown      @ yes, handle exception
7912    b       .LOP_FILLED_NEW_ARRAY_JUMBO_continue
7913
7914/* ------------------------------ */
7915    .balign 64
7916.L_OP_IGET_JUMBO: /* 0x106 */
7917/* File: armv5te/OP_IGET_JUMBO.S */
7918    /*
7919     * Jumbo 32-bit instance field get.
7920     *
7921     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7922     *      iget-char/jumbo, iget-short/jumbo
7923     */
7924    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7925    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7926    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7927    FETCH(r0, 4)                        @ r0<- CCCC
7928    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7929    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7930    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7931    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7932    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7933    cmp     r0, #0                      @ is resolved entry null?
7934    bne     .LOP_IGET_JUMBO_finish          @ no, already resolved
79358:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7936    EXPORT_PC()                         @ resolve() could throw
7937    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7938    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7939    b       .LOP_IGET_JUMBO_resolved        @ resolved, continue
7940
7941/* ------------------------------ */
7942    .balign 64
7943.L_OP_IGET_WIDE_JUMBO: /* 0x107 */
7944/* File: armv5te/OP_IGET_WIDE_JUMBO.S */
7945    /*
7946     * Jumbo 64-bit instance field get.
7947     */
7948    /* iget-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
7949    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7950    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7951    FETCH(r0, 4)                        @ r0<- CCCC
7952    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7953    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7954    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7955    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7956    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7957    cmp     r0, #0                      @ is resolved entry null?
7958    bne     .LOP_IGET_WIDE_JUMBO_finish          @ no, already resolved
79598:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
7960    EXPORT_PC()                         @ resolve() could throw
7961    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7962    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7963    b       .LOP_IGET_WIDE_JUMBO_resolved        @ resolved, continue
7964
7965/* ------------------------------ */
7966    .balign 64
7967.L_OP_IGET_OBJECT_JUMBO: /* 0x108 */
7968/* File: armv5te/OP_IGET_OBJECT_JUMBO.S */
7969/* File: armv5te/OP_IGET_JUMBO.S */
7970    /*
7971     * Jumbo 32-bit instance field get.
7972     *
7973     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7974     *      iget-char/jumbo, iget-short/jumbo
7975     */
7976    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7977    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7978    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7979    FETCH(r0, 4)                        @ r0<- CCCC
7980    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7981    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7982    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7983    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7984    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7985    cmp     r0, #0                      @ is resolved entry null?
7986    bne     .LOP_IGET_OBJECT_JUMBO_finish          @ no, already resolved
79878:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7988    EXPORT_PC()                         @ resolve() could throw
7989    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7990    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7991    b       .LOP_IGET_OBJECT_JUMBO_resolved        @ resolved, continue
7992
7993
7994/* ------------------------------ */
7995    .balign 64
7996.L_OP_IGET_BOOLEAN_JUMBO: /* 0x109 */
7997/* File: armv5te/OP_IGET_BOOLEAN_JUMBO.S */
7998@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrb", "sqnum":"1" }
7999/* File: armv5te/OP_IGET_JUMBO.S */
8000    /*
8001     * Jumbo 32-bit instance field get.
8002     *
8003     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8004     *      iget-char/jumbo, iget-short/jumbo
8005     */
8006    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8007    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8008    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8009    FETCH(r0, 4)                        @ r0<- CCCC
8010    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8011    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8012    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8013    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8014    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8015    cmp     r0, #0                      @ is resolved entry null?
8016    bne     .LOP_IGET_BOOLEAN_JUMBO_finish          @ no, already resolved
80178:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8018    EXPORT_PC()                         @ resolve() could throw
8019    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8020    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8021    b       .LOP_IGET_BOOLEAN_JUMBO_resolved        @ resolved, continue
8022
8023
8024/* ------------------------------ */
8025    .balign 64
8026.L_OP_IGET_BYTE_JUMBO: /* 0x10a */
8027/* File: armv5te/OP_IGET_BYTE_JUMBO.S */
8028@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsb", "sqnum":"2" }
8029/* File: armv5te/OP_IGET_JUMBO.S */
8030    /*
8031     * Jumbo 32-bit instance field get.
8032     *
8033     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8034     *      iget-char/jumbo, iget-short/jumbo
8035     */
8036    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8037    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8038    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8039    FETCH(r0, 4)                        @ r0<- CCCC
8040    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8041    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8042    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8043    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8044    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8045    cmp     r0, #0                      @ is resolved entry null?
8046    bne     .LOP_IGET_BYTE_JUMBO_finish          @ no, already resolved
80478:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8048    EXPORT_PC()                         @ resolve() could throw
8049    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8050    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8051    b       .LOP_IGET_BYTE_JUMBO_resolved        @ resolved, continue
8052
8053
8054/* ------------------------------ */
8055    .balign 64
8056.L_OP_IGET_CHAR_JUMBO: /* 0x10b */
8057/* File: armv5te/OP_IGET_CHAR_JUMBO.S */
8058@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrh", "sqnum":"3" }
8059/* File: armv5te/OP_IGET_JUMBO.S */
8060    /*
8061     * Jumbo 32-bit instance field get.
8062     *
8063     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8064     *      iget-char/jumbo, iget-short/jumbo
8065     */
8066    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8067    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8068    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8069    FETCH(r0, 4)                        @ r0<- CCCC
8070    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8071    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8072    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8073    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8074    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8075    cmp     r0, #0                      @ is resolved entry null?
8076    bne     .LOP_IGET_CHAR_JUMBO_finish          @ no, already resolved
80778:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8078    EXPORT_PC()                         @ resolve() could throw
8079    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8080    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8081    b       .LOP_IGET_CHAR_JUMBO_resolved        @ resolved, continue
8082
8083
8084/* ------------------------------ */
8085    .balign 64
8086.L_OP_IGET_SHORT_JUMBO: /* 0x10c */
8087/* File: armv5te/OP_IGET_SHORT_JUMBO.S */
8088@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsh", "sqnum":"4" }
8089/* File: armv5te/OP_IGET_JUMBO.S */
8090    /*
8091     * Jumbo 32-bit instance field get.
8092     *
8093     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8094     *      iget-char/jumbo, iget-short/jumbo
8095     */
8096    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8097    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8098    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8099    FETCH(r0, 4)                        @ r0<- CCCC
8100    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8101    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8102    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8103    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8104    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8105    cmp     r0, #0                      @ is resolved entry null?
8106    bne     .LOP_IGET_SHORT_JUMBO_finish          @ no, already resolved
81078:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8108    EXPORT_PC()                         @ resolve() could throw
8109    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8110    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8111    b       .LOP_IGET_SHORT_JUMBO_resolved        @ resolved, continue
8112
8113
8114/* ------------------------------ */
8115    .balign 64
8116.L_OP_IPUT_JUMBO: /* 0x10d */
8117/* File: armv5te/OP_IPUT_JUMBO.S */
8118    /*
8119     * Jumbo 32-bit instance field put.
8120     *
8121     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8122     *      iput-short/jumbo
8123     */
8124    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8125    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8126    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8127    FETCH(r0, 4)                        @ r0<- CCCC
8128    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8129    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8130    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8131    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8132    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8133    cmp     r0, #0                      @ is resolved entry null?
8134    bne     .LOP_IPUT_JUMBO_finish          @ no, already resolved
81358:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8136    EXPORT_PC()                         @ resolve() could throw
8137    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8138    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8139    b       .LOP_IPUT_JUMBO_resolved        @ resolved, continue
8140
8141/* ------------------------------ */
8142    .balign 64
8143.L_OP_IPUT_WIDE_JUMBO: /* 0x10e */
8144/* File: armv5te/OP_IPUT_WIDE_JUMBO.S */
8145    /* iput-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
8146    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8147    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8148    FETCH(r0, 4)                        @ r0<- CCCC
8149    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8150    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8151    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
8152    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
8153    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8154    cmp     r0, #0                      @ is resolved entry null?
8155    bne     .LOP_IPUT_WIDE_JUMBO_finish          @ no, already resolved
81568:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
8157    EXPORT_PC()                         @ resolve() could throw
8158    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8159    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8160    b       .LOP_IPUT_WIDE_JUMBO_resolved        @ resolved, continue
8161
8162/* ------------------------------ */
8163    .balign 64
8164.L_OP_IPUT_OBJECT_JUMBO: /* 0x10f */
8165/* File: armv5te/OP_IPUT_OBJECT_JUMBO.S */
8166    /*
8167     * Jumbo 32-bit instance field put.
8168     */
8169    /* iput-object/jumbo vBBBB, vCCCC, field@AAAAAAAA */
8170    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8171    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8172    FETCH(r0, 4)                        @ r0<- CCCC
8173    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8174    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8175    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8176    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8177    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8178    cmp     r0, #0                      @ is resolved entry null?
8179    bne     .LOP_IPUT_OBJECT_JUMBO_finish          @ no, already resolved
81808:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8181    EXPORT_PC()                         @ resolve() could throw
8182    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8183    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8184    b       .LOP_IPUT_OBJECT_JUMBO_resolved        @ resolved, continue
8185
8186/* ------------------------------ */
8187    .balign 64
8188.L_OP_IPUT_BOOLEAN_JUMBO: /* 0x110 */
8189/* File: armv5te/OP_IPUT_BOOLEAN_JUMBO.S */
8190@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"1" }
8191/* File: armv5te/OP_IPUT_JUMBO.S */
8192    /*
8193     * Jumbo 32-bit instance field put.
8194     *
8195     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8196     *      iput-short/jumbo
8197     */
8198    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8199    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8200    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8201    FETCH(r0, 4)                        @ r0<- CCCC
8202    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8203    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8204    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8205    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8206    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8207    cmp     r0, #0                      @ is resolved entry null?
8208    bne     .LOP_IPUT_BOOLEAN_JUMBO_finish          @ no, already resolved
82098:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8210    EXPORT_PC()                         @ resolve() could throw
8211    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8212    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8213    b       .LOP_IPUT_BOOLEAN_JUMBO_resolved        @ resolved, continue
8214
8215
8216/* ------------------------------ */
8217    .balign 64
8218.L_OP_IPUT_BYTE_JUMBO: /* 0x111 */
8219/* File: armv5te/OP_IPUT_BYTE_JUMBO.S */
8220@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"2" }
8221/* File: armv5te/OP_IPUT_JUMBO.S */
8222    /*
8223     * Jumbo 32-bit instance field put.
8224     *
8225     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8226     *      iput-short/jumbo
8227     */
8228    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8229    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8230    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8231    FETCH(r0, 4)                        @ r0<- CCCC
8232    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8233    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8234    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8235    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8236    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8237    cmp     r0, #0                      @ is resolved entry null?
8238    bne     .LOP_IPUT_BYTE_JUMBO_finish          @ no, already resolved
82398:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8240    EXPORT_PC()                         @ resolve() could throw
8241    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8242    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8243    b       .LOP_IPUT_BYTE_JUMBO_resolved        @ resolved, continue
8244
8245
8246/* ------------------------------ */
8247    .balign 64
8248.L_OP_IPUT_CHAR_JUMBO: /* 0x112 */
8249/* File: armv5te/OP_IPUT_CHAR_JUMBO.S */
8250@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"3" }
8251/* File: armv5te/OP_IPUT_JUMBO.S */
8252    /*
8253     * Jumbo 32-bit instance field put.
8254     *
8255     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8256     *      iput-short/jumbo
8257     */
8258    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8259    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8260    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8261    FETCH(r0, 4)                        @ r0<- CCCC
8262    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8263    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8264    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8265    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8266    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8267    cmp     r0, #0                      @ is resolved entry null?
8268    bne     .LOP_IPUT_CHAR_JUMBO_finish          @ no, already resolved
82698:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8270    EXPORT_PC()                         @ resolve() could throw
8271    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8272    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8273    b       .LOP_IPUT_CHAR_JUMBO_resolved        @ resolved, continue
8274
8275
8276/* ------------------------------ */
8277    .balign 64
8278.L_OP_IPUT_SHORT_JUMBO: /* 0x113 */
8279/* File: armv5te/OP_IPUT_SHORT_JUMBO.S */
8280@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"4" }
8281/* File: armv5te/OP_IPUT_JUMBO.S */
8282    /*
8283     * Jumbo 32-bit instance field put.
8284     *
8285     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8286     *      iput-short/jumbo
8287     */
8288    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8289    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8290    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8291    FETCH(r0, 4)                        @ r0<- CCCC
8292    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8293    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8294    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8295    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8296    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8297    cmp     r0, #0                      @ is resolved entry null?
8298    bne     .LOP_IPUT_SHORT_JUMBO_finish          @ no, already resolved
82998:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8300    EXPORT_PC()                         @ resolve() could throw
8301    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8302    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8303    b       .LOP_IPUT_SHORT_JUMBO_resolved        @ resolved, continue
8304
8305
8306/* ------------------------------ */
8307    .balign 64
8308.L_OP_SGET_JUMBO: /* 0x114 */
8309/* File: armv5te/OP_SGET_JUMBO.S */
8310    /*
8311     * Jumbo 32-bit SGET handler.
8312     *
8313     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8314     *      sget-char/jumbo, sget-short/jumbo
8315     */
8316    /* exop vBBBB, field@AAAAAAAA */
8317    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8318    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8319    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8320    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8321    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8322    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8323    cmp     r0, #0                      @ is resolved entry null?
8324    beq     .LOP_SGET_JUMBO_resolve         @ yes, do resolve
8325.LOP_SGET_JUMBO_finish: @ field ptr in r0
8326    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8327    @ no-op                             @ acquiring load
8328    FETCH(r2, 3)                        @ r2<- BBBB
8329    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8330    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8331    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8332    GOTO_OPCODE(ip)                     @ jump to next instruction
8333
8334/* ------------------------------ */
8335    .balign 64
8336.L_OP_SGET_WIDE_JUMBO: /* 0x115 */
8337/* File: armv5te/OP_SGET_WIDE_JUMBO.S */
8338    /*
8339     * Jumbo 64-bit SGET handler.
8340     */
8341    /* sget-wide/jumbo vBBBB, field@AAAAAAAA */
8342    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8343    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8344    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8345    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8346    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8347    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8348    cmp     r0, #0                      @ is resolved entry null?
8349    beq     .LOP_SGET_WIDE_JUMBO_resolve         @ yes, do resolve
8350.LOP_SGET_WIDE_JUMBO_finish:
8351    FETCH(r9, 3)                        @ r9<- BBBB
8352    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
8353    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BBBB]
8354    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8355    stmia   r9, {r0-r1}                 @ vBBBB/vBBBB+1<- r0/r1
8356    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8357    GOTO_OPCODE(ip)                     @ jump to next instruction
8358
8359/* ------------------------------ */
8360    .balign 64
8361.L_OP_SGET_OBJECT_JUMBO: /* 0x116 */
8362/* File: armv5te/OP_SGET_OBJECT_JUMBO.S */
8363/* File: armv5te/OP_SGET_JUMBO.S */
8364    /*
8365     * Jumbo 32-bit SGET handler.
8366     *
8367     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8368     *      sget-char/jumbo, sget-short/jumbo
8369     */
8370    /* exop vBBBB, field@AAAAAAAA */
8371    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8372    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8373    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8374    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8375    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8376    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8377    cmp     r0, #0                      @ is resolved entry null?
8378    beq     .LOP_SGET_OBJECT_JUMBO_resolve         @ yes, do resolve
8379.LOP_SGET_OBJECT_JUMBO_finish: @ field ptr in r0
8380    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8381    @ no-op                             @ acquiring load
8382    FETCH(r2, 3)                        @ r2<- BBBB
8383    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8384    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8385    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8386    GOTO_OPCODE(ip)                     @ jump to next instruction
8387
8388
8389/* ------------------------------ */
8390    .balign 64
8391.L_OP_SGET_BOOLEAN_JUMBO: /* 0x117 */
8392/* File: armv5te/OP_SGET_BOOLEAN_JUMBO.S */
8393/* File: armv5te/OP_SGET_JUMBO.S */
8394    /*
8395     * Jumbo 32-bit SGET handler.
8396     *
8397     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8398     *      sget-char/jumbo, sget-short/jumbo
8399     */
8400    /* exop vBBBB, field@AAAAAAAA */
8401    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8402    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8403    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8404    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8405    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8406    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8407    cmp     r0, #0                      @ is resolved entry null?
8408    beq     .LOP_SGET_BOOLEAN_JUMBO_resolve         @ yes, do resolve
8409.LOP_SGET_BOOLEAN_JUMBO_finish: @ field ptr in r0
8410    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8411    @ no-op                             @ acquiring load
8412    FETCH(r2, 3)                        @ r2<- BBBB
8413    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8414    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8415    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8416    GOTO_OPCODE(ip)                     @ jump to next instruction
8417
8418
8419/* ------------------------------ */
8420    .balign 64
8421.L_OP_SGET_BYTE_JUMBO: /* 0x118 */
8422/* File: armv5te/OP_SGET_BYTE_JUMBO.S */
8423/* File: armv5te/OP_SGET_JUMBO.S */
8424    /*
8425     * Jumbo 32-bit SGET handler.
8426     *
8427     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8428     *      sget-char/jumbo, sget-short/jumbo
8429     */
8430    /* exop vBBBB, field@AAAAAAAA */
8431    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8432    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8433    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8434    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8435    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8436    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8437    cmp     r0, #0                      @ is resolved entry null?
8438    beq     .LOP_SGET_BYTE_JUMBO_resolve         @ yes, do resolve
8439.LOP_SGET_BYTE_JUMBO_finish: @ field ptr in r0
8440    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8441    @ no-op                             @ acquiring load
8442    FETCH(r2, 3)                        @ r2<- BBBB
8443    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8444    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8445    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8446    GOTO_OPCODE(ip)                     @ jump to next instruction
8447
8448
8449/* ------------------------------ */
8450    .balign 64
8451.L_OP_SGET_CHAR_JUMBO: /* 0x119 */
8452/* File: armv5te/OP_SGET_CHAR_JUMBO.S */
8453/* File: armv5te/OP_SGET_JUMBO.S */
8454    /*
8455     * Jumbo 32-bit SGET handler.
8456     *
8457     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8458     *      sget-char/jumbo, sget-short/jumbo
8459     */
8460    /* exop vBBBB, field@AAAAAAAA */
8461    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8462    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8463    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8464    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8465    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8466    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8467    cmp     r0, #0                      @ is resolved entry null?
8468    beq     .LOP_SGET_CHAR_JUMBO_resolve         @ yes, do resolve
8469.LOP_SGET_CHAR_JUMBO_finish: @ field ptr in r0
8470    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8471    @ no-op                             @ acquiring load
8472    FETCH(r2, 3)                        @ r2<- BBBB
8473    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8474    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8475    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8476    GOTO_OPCODE(ip)                     @ jump to next instruction
8477
8478
8479/* ------------------------------ */
8480    .balign 64
8481.L_OP_SGET_SHORT_JUMBO: /* 0x11a */
8482/* File: armv5te/OP_SGET_SHORT_JUMBO.S */
8483/* File: armv5te/OP_SGET_JUMBO.S */
8484    /*
8485     * Jumbo 32-bit SGET handler.
8486     *
8487     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8488     *      sget-char/jumbo, sget-short/jumbo
8489     */
8490    /* exop vBBBB, field@AAAAAAAA */
8491    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8492    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8493    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8494    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8495    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8496    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8497    cmp     r0, #0                      @ is resolved entry null?
8498    beq     .LOP_SGET_SHORT_JUMBO_resolve         @ yes, do resolve
8499.LOP_SGET_SHORT_JUMBO_finish: @ field ptr in r0
8500    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8501    @ no-op                             @ acquiring load
8502    FETCH(r2, 3)                        @ r2<- BBBB
8503    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8504    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8505    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8506    GOTO_OPCODE(ip)                     @ jump to next instruction
8507
8508
8509/* ------------------------------ */
8510    .balign 64
8511.L_OP_SPUT_JUMBO: /* 0x11b */
8512/* File: armv5te/OP_SPUT_JUMBO.S */
8513    /*
8514     * Jumbo 32-bit SPUT handler.
8515     *
8516     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8517     *      sput-short/jumbo
8518     */
8519    /* exop vBBBB, field@AAAAAAAA */
8520    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8521    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8522    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8523    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8524    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8525    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8526    cmp     r0, #0                      @ is resolved entry null?
8527    beq     .LOP_SPUT_JUMBO_resolve         @ yes, do resolve
8528.LOP_SPUT_JUMBO_finish:   @ field ptr in r0
8529    FETCH(r2, 3)                        @ r2<- BBBB
8530    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8531    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8532    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8533    @ no-op                             @ releasing store
8534    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8535    GOTO_OPCODE(ip)                     @ jump to next instruction
8536
8537/* ------------------------------ */
8538    .balign 64
8539.L_OP_SPUT_WIDE_JUMBO: /* 0x11c */
8540/* File: armv5te/OP_SPUT_WIDE_JUMBO.S */
8541    /*
8542     * Jumbo 64-bit SPUT handler.
8543     */
8544    /* sput-wide/jumbo vBBBB, field@AAAAAAAA */
8545    ldr     r0, [rGLUE, #offGlue_methodClassDex]  @ r0<- DvmDex
8546    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8547    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8548    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
8549    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8550    FETCH(r9, 3)                        @ r9<- BBBB
8551    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
8552    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BBBB]
8553    cmp     r2, #0                      @ is resolved entry null?
8554    beq     .LOP_SPUT_WIDE_JUMBO_resolve         @ yes, do resolve
8555.LOP_SPUT_WIDE_JUMBO_finish: @ field ptr in r2, BBBB in r9
8556    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8557    ldmia   r9, {r0-r1}                 @ r0/r1<- vBBBB/vBBBB+1
8558    GET_INST_OPCODE(r10)                @ extract opcode from rINST
8559    strd    r0, [r2, #offStaticField_value] @ field<- vBBBB/vBBBB+1
8560    GOTO_OPCODE(r10)                    @ jump to next instruction
8561
8562/* ------------------------------ */
8563    .balign 64
8564.L_OP_SPUT_OBJECT_JUMBO: /* 0x11d */
8565/* File: armv5te/OP_SPUT_OBJECT_JUMBO.S */
8566    /*
8567     * Jumbo 32-bit SPUT handler for objects
8568     */
8569    /* sput-object/jumbo vBBBB, field@AAAAAAAA */
8570    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8571    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8572    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8573    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8574    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8575    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8576    cmp     r0, #0                      @ is resolved entry null?
8577    bne     .LOP_SPUT_OBJECT_JUMBO_finish          @ no, continue
8578    ldr     r9, [rGLUE, #offGlue_method]    @ r9<- current method
8579    EXPORT_PC()                         @ resolve() could throw, so export now
8580    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
8581    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8582    cmp     r0, #0                      @ success?
8583    bne     .LOP_SPUT_OBJECT_JUMBO_finish          @ yes, finish
8584    b       common_exceptionThrown      @ no, handle exception
8585
8586/* ------------------------------ */
8587    .balign 64
8588.L_OP_SPUT_BOOLEAN_JUMBO: /* 0x11e */
8589/* File: armv5te/OP_SPUT_BOOLEAN_JUMBO.S */
8590/* File: armv5te/OP_SPUT_JUMBO.S */
8591    /*
8592     * Jumbo 32-bit SPUT handler.
8593     *
8594     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8595     *      sput-short/jumbo
8596     */
8597    /* exop vBBBB, field@AAAAAAAA */
8598    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8599    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8600    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8601    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8602    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8603    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8604    cmp     r0, #0                      @ is resolved entry null?
8605    beq     .LOP_SPUT_BOOLEAN_JUMBO_resolve         @ yes, do resolve
8606.LOP_SPUT_BOOLEAN_JUMBO_finish:   @ field ptr in r0
8607    FETCH(r2, 3)                        @ r2<- BBBB
8608    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8609    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8610    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8611    @ no-op                             @ releasing store
8612    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8613    GOTO_OPCODE(ip)                     @ jump to next instruction
8614
8615
8616/* ------------------------------ */
8617    .balign 64
8618.L_OP_SPUT_BYTE_JUMBO: /* 0x11f */
8619/* File: armv5te/OP_SPUT_BYTE_JUMBO.S */
8620/* File: armv5te/OP_SPUT_JUMBO.S */
8621    /*
8622     * Jumbo 32-bit SPUT handler.
8623     *
8624     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8625     *      sput-short/jumbo
8626     */
8627    /* exop vBBBB, field@AAAAAAAA */
8628    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8629    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8630    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8631    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8632    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8633    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8634    cmp     r0, #0                      @ is resolved entry null?
8635    beq     .LOP_SPUT_BYTE_JUMBO_resolve         @ yes, do resolve
8636.LOP_SPUT_BYTE_JUMBO_finish:   @ field ptr in r0
8637    FETCH(r2, 3)                        @ r2<- BBBB
8638    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8639    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8640    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8641    @ no-op                             @ releasing store
8642    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8643    GOTO_OPCODE(ip)                     @ jump to next instruction
8644
8645
8646/* ------------------------------ */
8647    .balign 64
8648.L_OP_SPUT_CHAR_JUMBO: /* 0x120 */
8649/* File: armv5te/OP_SPUT_CHAR_JUMBO.S */
8650/* File: armv5te/OP_SPUT_JUMBO.S */
8651    /*
8652     * Jumbo 32-bit SPUT handler.
8653     *
8654     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8655     *      sput-short/jumbo
8656     */
8657    /* exop vBBBB, field@AAAAAAAA */
8658    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8659    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8660    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8661    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8662    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8663    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8664    cmp     r0, #0                      @ is resolved entry null?
8665    beq     .LOP_SPUT_CHAR_JUMBO_resolve         @ yes, do resolve
8666.LOP_SPUT_CHAR_JUMBO_finish:   @ field ptr in r0
8667    FETCH(r2, 3)                        @ r2<- BBBB
8668    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8669    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8670    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8671    @ no-op                             @ releasing store
8672    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8673    GOTO_OPCODE(ip)                     @ jump to next instruction
8674
8675
8676/* ------------------------------ */
8677    .balign 64
8678.L_OP_SPUT_SHORT_JUMBO: /* 0x121 */
8679/* File: armv5te/OP_SPUT_SHORT_JUMBO.S */
8680/* File: armv5te/OP_SPUT_JUMBO.S */
8681    /*
8682     * Jumbo 32-bit SPUT handler.
8683     *
8684     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8685     *      sput-short/jumbo
8686     */
8687    /* exop vBBBB, field@AAAAAAAA */
8688    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8689    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8690    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8691    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8692    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8693    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8694    cmp     r0, #0                      @ is resolved entry null?
8695    beq     .LOP_SPUT_SHORT_JUMBO_resolve         @ yes, do resolve
8696.LOP_SPUT_SHORT_JUMBO_finish:   @ field ptr in r0
8697    FETCH(r2, 3)                        @ r2<- BBBB
8698    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8699    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8700    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8701    @ no-op                             @ releasing store
8702    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8703    GOTO_OPCODE(ip)                     @ jump to next instruction
8704
8705
8706/* ------------------------------ */
8707    .balign 64
8708.L_OP_INVOKE_VIRTUAL_JUMBO: /* 0x122 */
8709/* File: armv5te/OP_INVOKE_VIRTUAL_JUMBO.S */
8710    /*
8711     * Handle a virtual method call.
8712     */
8713    /* invoke-virtual/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8714    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8715    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8716    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8717    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8718    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8719    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
8720    cmp     r0, #0                      @ already resolved?
8721    EXPORT_PC()                         @ must export for invoke
8722    bne     .LOP_INVOKE_VIRTUAL_JUMBO_continue        @ yes, continue on
8723    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
8724    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8725    mov     r2, #METHOD_VIRTUAL         @ resolver method type
8726    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8727    cmp     r0, #0                      @ got null?
8728    bne     .LOP_INVOKE_VIRTUAL_JUMBO_continue        @ no, continue
8729    b       common_exceptionThrown      @ yes, handle exception
8730
8731/* ------------------------------ */
8732    .balign 64
8733.L_OP_INVOKE_SUPER_JUMBO: /* 0x123 */
8734/* File: armv5te/OP_INVOKE_SUPER_JUMBO.S */
8735    /*
8736     * Handle a "super" method call.
8737     */
8738    /* invoke-super/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8739    FETCH(r10, 4)                       @ r10<- CCCC
8740    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8741    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8742    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8743    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8744    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8745    GET_VREG(r2, r10)                   @ r2<- "this" ptr
8746    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
8747    cmp     r2, #0                      @ null "this"?
8748    ldr     r9, [rGLUE, #offGlue_method] @ r9<- current method
8749    beq     common_errNullObject        @ null "this", throw exception
8750    cmp     r0, #0                      @ already resolved?
8751    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
8752    EXPORT_PC()                         @ must export for invoke
8753    bne     .LOP_INVOKE_SUPER_JUMBO_continue        @ resolved, continue on
8754    b       .LOP_INVOKE_SUPER_JUMBO_resolve         @ do resolve now
8755
8756/* ------------------------------ */
8757    .balign 64
8758.L_OP_INVOKE_DIRECT_JUMBO: /* 0x124 */
8759/* File: armv5te/OP_INVOKE_DIRECT_JUMBO.S */
8760    /*
8761     * Handle a direct method call.
8762     *
8763     * (We could defer the "is 'this' pointer null" test to the common
8764     * method invocation code, and use a flag to indicate that static
8765     * calls don't count.  If we do this as part of copying the arguments
8766     * out we could avoiding loading the first arg twice.)
8767     *
8768     */
8769    /* invoke-direct/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8770    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8771    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8772    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8773    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8774    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8775    FETCH(r10, 4)                       @ r10<- CCCC
8776    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
8777    cmp     r0, #0                      @ already resolved?
8778    EXPORT_PC()                         @ must export for invoke
8779    GET_VREG(r2, r10)                   @ r2<- "this" ptr
8780    beq     .LOP_INVOKE_DIRECT_JUMBO_resolve         @ not resolved, do it now
8781.LOP_INVOKE_DIRECT_JUMBO_finish:
8782    cmp     r2, #0                      @ null "this" ref?
8783    bne     common_invokeMethodJumbo    @ no, continue on
8784    b       common_errNullObject        @ yes, throw exception
8785
8786/* ------------------------------ */
8787    .balign 64
8788.L_OP_INVOKE_STATIC_JUMBO: /* 0x125 */
8789/* File: armv5te/OP_INVOKE_STATIC_JUMBO.S */
8790    /*
8791     * Handle a static method call.
8792     */
8793    /* invoke-static/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8794    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8795    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8796    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8797    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8798    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8799    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
8800    cmp     r0, #0                      @ already resolved?
8801    EXPORT_PC()                         @ must export for invoke
8802    bne     common_invokeMethodJumbo    @ yes, continue on
88030:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
8804    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8805    mov     r2, #METHOD_STATIC          @ resolver method type
8806    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8807    cmp     r0, #0                      @ got null?
8808    bne     common_invokeMethodJumbo    @ no, continue
8809    b       common_exceptionThrown      @ yes, handle exception
8810
8811/* ------------------------------ */
8812    .balign 64
8813.L_OP_INVOKE_INTERFACE_JUMBO: /* 0x126 */
8814/* File: armv5te/OP_INVOKE_INTERFACE_JUMBO.S */
8815    /*
8816     * Handle an interface method call.
8817     */
8818    /* invoke-interface/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8819    FETCH(r2, 4)                        @ r2<- CCCC
8820    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8821    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8822    EXPORT_PC()                         @ must export for invoke
8823    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8824    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
8825    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- methodClassDex
8826    cmp     r0, #0                      @ null obj?
8827    ldr     r2, [rGLUE, #offGlue_method]  @ r2<- method
8828    beq     common_errNullObject        @ yes, fail
8829    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
8830    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
8831    cmp     r0, #0                      @ failed?
8832    beq     common_exceptionThrown      @ yes, handle exception
8833    b       common_invokeMethodJumbo    @ jump to common handler
8834
8835/* ------------------------------ */
8836    .balign 64
8837.L_OP_UNUSED_27FF: /* 0x127 */
8838/* File: armv5te/OP_UNUSED_27FF.S */
8839/* File: armv5te/unused.S */
8840    bl      common_abort
8841
8842
8843/* ------------------------------ */
8844    .balign 64
8845.L_OP_UNUSED_28FF: /* 0x128 */
8846/* File: armv5te/OP_UNUSED_28FF.S */
8847/* File: armv5te/unused.S */
8848    bl      common_abort
8849
8850
8851/* ------------------------------ */
8852    .balign 64
8853.L_OP_UNUSED_29FF: /* 0x129 */
8854/* File: armv5te/OP_UNUSED_29FF.S */
8855/* File: armv5te/unused.S */
8856    bl      common_abort
8857
8858
8859/* ------------------------------ */
8860    .balign 64
8861.L_OP_UNUSED_2AFF: /* 0x12a */
8862/* File: armv5te/OP_UNUSED_2AFF.S */
8863/* File: armv5te/unused.S */
8864    bl      common_abort
8865
8866
8867/* ------------------------------ */
8868    .balign 64
8869.L_OP_UNUSED_2BFF: /* 0x12b */
8870/* File: armv5te/OP_UNUSED_2BFF.S */
8871/* File: armv5te/unused.S */
8872    bl      common_abort
8873
8874
8875/* ------------------------------ */
8876    .balign 64
8877.L_OP_UNUSED_2CFF: /* 0x12c */
8878/* File: armv5te/OP_UNUSED_2CFF.S */
8879/* File: armv5te/unused.S */
8880    bl      common_abort
8881
8882
8883/* ------------------------------ */
8884    .balign 64
8885.L_OP_UNUSED_2DFF: /* 0x12d */
8886/* File: armv5te/OP_UNUSED_2DFF.S */
8887/* File: armv5te/unused.S */
8888    bl      common_abort
8889
8890
8891/* ------------------------------ */
8892    .balign 64
8893.L_OP_UNUSED_2EFF: /* 0x12e */
8894/* File: armv5te/OP_UNUSED_2EFF.S */
8895/* File: armv5te/unused.S */
8896    bl      common_abort
8897
8898
8899/* ------------------------------ */
8900    .balign 64
8901.L_OP_UNUSED_2FFF: /* 0x12f */
8902/* File: armv5te/OP_UNUSED_2FFF.S */
8903/* File: armv5te/unused.S */
8904    bl      common_abort
8905
8906
8907/* ------------------------------ */
8908    .balign 64
8909.L_OP_UNUSED_30FF: /* 0x130 */
8910/* File: armv5te/OP_UNUSED_30FF.S */
8911/* File: armv5te/unused.S */
8912    bl      common_abort
8913
8914
8915/* ------------------------------ */
8916    .balign 64
8917.L_OP_UNUSED_31FF: /* 0x131 */
8918/* File: armv5te/OP_UNUSED_31FF.S */
8919/* File: armv5te/unused.S */
8920    bl      common_abort
8921
8922
8923/* ------------------------------ */
8924    .balign 64
8925.L_OP_UNUSED_32FF: /* 0x132 */
8926/* File: armv5te/OP_UNUSED_32FF.S */
8927/* File: armv5te/unused.S */
8928    bl      common_abort
8929
8930
8931/* ------------------------------ */
8932    .balign 64
8933.L_OP_UNUSED_33FF: /* 0x133 */
8934/* File: armv5te/OP_UNUSED_33FF.S */
8935/* File: armv5te/unused.S */
8936    bl      common_abort
8937
8938
8939/* ------------------------------ */
8940    .balign 64
8941.L_OP_UNUSED_34FF: /* 0x134 */
8942/* File: armv5te/OP_UNUSED_34FF.S */
8943/* File: armv5te/unused.S */
8944    bl      common_abort
8945
8946
8947/* ------------------------------ */
8948    .balign 64
8949.L_OP_UNUSED_35FF: /* 0x135 */
8950/* File: armv5te/OP_UNUSED_35FF.S */
8951/* File: armv5te/unused.S */
8952    bl      common_abort
8953
8954
8955/* ------------------------------ */
8956    .balign 64
8957.L_OP_UNUSED_36FF: /* 0x136 */
8958/* File: armv5te/OP_UNUSED_36FF.S */
8959/* File: armv5te/unused.S */
8960    bl      common_abort
8961
8962
8963/* ------------------------------ */
8964    .balign 64
8965.L_OP_UNUSED_37FF: /* 0x137 */
8966/* File: armv5te/OP_UNUSED_37FF.S */
8967/* File: armv5te/unused.S */
8968    bl      common_abort
8969
8970
8971/* ------------------------------ */
8972    .balign 64
8973.L_OP_UNUSED_38FF: /* 0x138 */
8974/* File: armv5te/OP_UNUSED_38FF.S */
8975/* File: armv5te/unused.S */
8976    bl      common_abort
8977
8978
8979/* ------------------------------ */
8980    .balign 64
8981.L_OP_UNUSED_39FF: /* 0x139 */
8982/* File: armv5te/OP_UNUSED_39FF.S */
8983/* File: armv5te/unused.S */
8984    bl      common_abort
8985
8986
8987/* ------------------------------ */
8988    .balign 64
8989.L_OP_UNUSED_3AFF: /* 0x13a */
8990/* File: armv5te/OP_UNUSED_3AFF.S */
8991/* File: armv5te/unused.S */
8992    bl      common_abort
8993
8994
8995/* ------------------------------ */
8996    .balign 64
8997.L_OP_UNUSED_3BFF: /* 0x13b */
8998/* File: armv5te/OP_UNUSED_3BFF.S */
8999/* File: armv5te/unused.S */
9000    bl      common_abort
9001
9002
9003/* ------------------------------ */
9004    .balign 64
9005.L_OP_UNUSED_3CFF: /* 0x13c */
9006/* File: armv5te/OP_UNUSED_3CFF.S */
9007/* File: armv5te/unused.S */
9008    bl      common_abort
9009
9010
9011/* ------------------------------ */
9012    .balign 64
9013.L_OP_UNUSED_3DFF: /* 0x13d */
9014/* File: armv5te/OP_UNUSED_3DFF.S */
9015/* File: armv5te/unused.S */
9016    bl      common_abort
9017
9018
9019/* ------------------------------ */
9020    .balign 64
9021.L_OP_UNUSED_3EFF: /* 0x13e */
9022/* File: armv5te/OP_UNUSED_3EFF.S */
9023/* File: armv5te/unused.S */
9024    bl      common_abort
9025
9026
9027/* ------------------------------ */
9028    .balign 64
9029.L_OP_UNUSED_3FFF: /* 0x13f */
9030/* File: armv5te/OP_UNUSED_3FFF.S */
9031/* File: armv5te/unused.S */
9032    bl      common_abort
9033
9034
9035/* ------------------------------ */
9036    .balign 64
9037.L_OP_UNUSED_40FF: /* 0x140 */
9038/* File: armv5te/OP_UNUSED_40FF.S */
9039/* File: armv5te/unused.S */
9040    bl      common_abort
9041
9042
9043/* ------------------------------ */
9044    .balign 64
9045.L_OP_UNUSED_41FF: /* 0x141 */
9046/* File: armv5te/OP_UNUSED_41FF.S */
9047/* File: armv5te/unused.S */
9048    bl      common_abort
9049
9050
9051/* ------------------------------ */
9052    .balign 64
9053.L_OP_UNUSED_42FF: /* 0x142 */
9054/* File: armv5te/OP_UNUSED_42FF.S */
9055/* File: armv5te/unused.S */
9056    bl      common_abort
9057
9058
9059/* ------------------------------ */
9060    .balign 64
9061.L_OP_UNUSED_43FF: /* 0x143 */
9062/* File: armv5te/OP_UNUSED_43FF.S */
9063/* File: armv5te/unused.S */
9064    bl      common_abort
9065
9066
9067/* ------------------------------ */
9068    .balign 64
9069.L_OP_UNUSED_44FF: /* 0x144 */
9070/* File: armv5te/OP_UNUSED_44FF.S */
9071/* File: armv5te/unused.S */
9072    bl      common_abort
9073
9074
9075/* ------------------------------ */
9076    .balign 64
9077.L_OP_UNUSED_45FF: /* 0x145 */
9078/* File: armv5te/OP_UNUSED_45FF.S */
9079/* File: armv5te/unused.S */
9080    bl      common_abort
9081
9082
9083/* ------------------------------ */
9084    .balign 64
9085.L_OP_UNUSED_46FF: /* 0x146 */
9086/* File: armv5te/OP_UNUSED_46FF.S */
9087/* File: armv5te/unused.S */
9088    bl      common_abort
9089
9090
9091/* ------------------------------ */
9092    .balign 64
9093.L_OP_UNUSED_47FF: /* 0x147 */
9094/* File: armv5te/OP_UNUSED_47FF.S */
9095/* File: armv5te/unused.S */
9096    bl      common_abort
9097
9098
9099/* ------------------------------ */
9100    .balign 64
9101.L_OP_UNUSED_48FF: /* 0x148 */
9102/* File: armv5te/OP_UNUSED_48FF.S */
9103/* File: armv5te/unused.S */
9104    bl      common_abort
9105
9106
9107/* ------------------------------ */
9108    .balign 64
9109.L_OP_UNUSED_49FF: /* 0x149 */
9110/* File: armv5te/OP_UNUSED_49FF.S */
9111/* File: armv5te/unused.S */
9112    bl      common_abort
9113
9114
9115/* ------------------------------ */
9116    .balign 64
9117.L_OP_UNUSED_4AFF: /* 0x14a */
9118/* File: armv5te/OP_UNUSED_4AFF.S */
9119/* File: armv5te/unused.S */
9120    bl      common_abort
9121
9122
9123/* ------------------------------ */
9124    .balign 64
9125.L_OP_UNUSED_4BFF: /* 0x14b */
9126/* File: armv5te/OP_UNUSED_4BFF.S */
9127/* File: armv5te/unused.S */
9128    bl      common_abort
9129
9130
9131/* ------------------------------ */
9132    .balign 64
9133.L_OP_UNUSED_4CFF: /* 0x14c */
9134/* File: armv5te/OP_UNUSED_4CFF.S */
9135/* File: armv5te/unused.S */
9136    bl      common_abort
9137
9138
9139/* ------------------------------ */
9140    .balign 64
9141.L_OP_UNUSED_4DFF: /* 0x14d */
9142/* File: armv5te/OP_UNUSED_4DFF.S */
9143/* File: armv5te/unused.S */
9144    bl      common_abort
9145
9146
9147/* ------------------------------ */
9148    .balign 64
9149.L_OP_UNUSED_4EFF: /* 0x14e */
9150/* File: armv5te/OP_UNUSED_4EFF.S */
9151/* File: armv5te/unused.S */
9152    bl      common_abort
9153
9154
9155/* ------------------------------ */
9156    .balign 64
9157.L_OP_UNUSED_4FFF: /* 0x14f */
9158/* File: armv5te/OP_UNUSED_4FFF.S */
9159/* File: armv5te/unused.S */
9160    bl      common_abort
9161
9162
9163/* ------------------------------ */
9164    .balign 64
9165.L_OP_UNUSED_50FF: /* 0x150 */
9166/* File: armv5te/OP_UNUSED_50FF.S */
9167/* File: armv5te/unused.S */
9168    bl      common_abort
9169
9170
9171/* ------------------------------ */
9172    .balign 64
9173.L_OP_UNUSED_51FF: /* 0x151 */
9174/* File: armv5te/OP_UNUSED_51FF.S */
9175/* File: armv5te/unused.S */
9176    bl      common_abort
9177
9178
9179/* ------------------------------ */
9180    .balign 64
9181.L_OP_UNUSED_52FF: /* 0x152 */
9182/* File: armv5te/OP_UNUSED_52FF.S */
9183/* File: armv5te/unused.S */
9184    bl      common_abort
9185
9186
9187/* ------------------------------ */
9188    .balign 64
9189.L_OP_UNUSED_53FF: /* 0x153 */
9190/* File: armv5te/OP_UNUSED_53FF.S */
9191/* File: armv5te/unused.S */
9192    bl      common_abort
9193
9194
9195/* ------------------------------ */
9196    .balign 64
9197.L_OP_UNUSED_54FF: /* 0x154 */
9198/* File: armv5te/OP_UNUSED_54FF.S */
9199/* File: armv5te/unused.S */
9200    bl      common_abort
9201
9202
9203/* ------------------------------ */
9204    .balign 64
9205.L_OP_UNUSED_55FF: /* 0x155 */
9206/* File: armv5te/OP_UNUSED_55FF.S */
9207/* File: armv5te/unused.S */
9208    bl      common_abort
9209
9210
9211/* ------------------------------ */
9212    .balign 64
9213.L_OP_UNUSED_56FF: /* 0x156 */
9214/* File: armv5te/OP_UNUSED_56FF.S */
9215/* File: armv5te/unused.S */
9216    bl      common_abort
9217
9218
9219/* ------------------------------ */
9220    .balign 64
9221.L_OP_UNUSED_57FF: /* 0x157 */
9222/* File: armv5te/OP_UNUSED_57FF.S */
9223/* File: armv5te/unused.S */
9224    bl      common_abort
9225
9226
9227/* ------------------------------ */
9228    .balign 64
9229.L_OP_UNUSED_58FF: /* 0x158 */
9230/* File: armv5te/OP_UNUSED_58FF.S */
9231/* File: armv5te/unused.S */
9232    bl      common_abort
9233
9234
9235/* ------------------------------ */
9236    .balign 64
9237.L_OP_UNUSED_59FF: /* 0x159 */
9238/* File: armv5te/OP_UNUSED_59FF.S */
9239/* File: armv5te/unused.S */
9240    bl      common_abort
9241
9242
9243/* ------------------------------ */
9244    .balign 64
9245.L_OP_UNUSED_5AFF: /* 0x15a */
9246/* File: armv5te/OP_UNUSED_5AFF.S */
9247/* File: armv5te/unused.S */
9248    bl      common_abort
9249
9250
9251/* ------------------------------ */
9252    .balign 64
9253.L_OP_UNUSED_5BFF: /* 0x15b */
9254/* File: armv5te/OP_UNUSED_5BFF.S */
9255/* File: armv5te/unused.S */
9256    bl      common_abort
9257
9258
9259/* ------------------------------ */
9260    .balign 64
9261.L_OP_UNUSED_5CFF: /* 0x15c */
9262/* File: armv5te/OP_UNUSED_5CFF.S */
9263/* File: armv5te/unused.S */
9264    bl      common_abort
9265
9266
9267/* ------------------------------ */
9268    .balign 64
9269.L_OP_UNUSED_5DFF: /* 0x15d */
9270/* File: armv5te/OP_UNUSED_5DFF.S */
9271/* File: armv5te/unused.S */
9272    bl      common_abort
9273
9274
9275/* ------------------------------ */
9276    .balign 64
9277.L_OP_UNUSED_5EFF: /* 0x15e */
9278/* File: armv5te/OP_UNUSED_5EFF.S */
9279/* File: armv5te/unused.S */
9280    bl      common_abort
9281
9282
9283/* ------------------------------ */
9284    .balign 64
9285.L_OP_UNUSED_5FFF: /* 0x15f */
9286/* File: armv5te/OP_UNUSED_5FFF.S */
9287/* File: armv5te/unused.S */
9288    bl      common_abort
9289
9290
9291/* ------------------------------ */
9292    .balign 64
9293.L_OP_UNUSED_60FF: /* 0x160 */
9294/* File: armv5te/OP_UNUSED_60FF.S */
9295/* File: armv5te/unused.S */
9296    bl      common_abort
9297
9298
9299/* ------------------------------ */
9300    .balign 64
9301.L_OP_UNUSED_61FF: /* 0x161 */
9302/* File: armv5te/OP_UNUSED_61FF.S */
9303/* File: armv5te/unused.S */
9304    bl      common_abort
9305
9306
9307/* ------------------------------ */
9308    .balign 64
9309.L_OP_UNUSED_62FF: /* 0x162 */
9310/* File: armv5te/OP_UNUSED_62FF.S */
9311/* File: armv5te/unused.S */
9312    bl      common_abort
9313
9314
9315/* ------------------------------ */
9316    .balign 64
9317.L_OP_UNUSED_63FF: /* 0x163 */
9318/* File: armv5te/OP_UNUSED_63FF.S */
9319/* File: armv5te/unused.S */
9320    bl      common_abort
9321
9322
9323/* ------------------------------ */
9324    .balign 64
9325.L_OP_UNUSED_64FF: /* 0x164 */
9326/* File: armv5te/OP_UNUSED_64FF.S */
9327/* File: armv5te/unused.S */
9328    bl      common_abort
9329
9330
9331/* ------------------------------ */
9332    .balign 64
9333.L_OP_UNUSED_65FF: /* 0x165 */
9334/* File: armv5te/OP_UNUSED_65FF.S */
9335/* File: armv5te/unused.S */
9336    bl      common_abort
9337
9338
9339/* ------------------------------ */
9340    .balign 64
9341.L_OP_UNUSED_66FF: /* 0x166 */
9342/* File: armv5te/OP_UNUSED_66FF.S */
9343/* File: armv5te/unused.S */
9344    bl      common_abort
9345
9346
9347/* ------------------------------ */
9348    .balign 64
9349.L_OP_UNUSED_67FF: /* 0x167 */
9350/* File: armv5te/OP_UNUSED_67FF.S */
9351/* File: armv5te/unused.S */
9352    bl      common_abort
9353
9354
9355/* ------------------------------ */
9356    .balign 64
9357.L_OP_UNUSED_68FF: /* 0x168 */
9358/* File: armv5te/OP_UNUSED_68FF.S */
9359/* File: armv5te/unused.S */
9360    bl      common_abort
9361
9362
9363/* ------------------------------ */
9364    .balign 64
9365.L_OP_UNUSED_69FF: /* 0x169 */
9366/* File: armv5te/OP_UNUSED_69FF.S */
9367/* File: armv5te/unused.S */
9368    bl      common_abort
9369
9370
9371/* ------------------------------ */
9372    .balign 64
9373.L_OP_UNUSED_6AFF: /* 0x16a */
9374/* File: armv5te/OP_UNUSED_6AFF.S */
9375/* File: armv5te/unused.S */
9376    bl      common_abort
9377
9378
9379/* ------------------------------ */
9380    .balign 64
9381.L_OP_UNUSED_6BFF: /* 0x16b */
9382/* File: armv5te/OP_UNUSED_6BFF.S */
9383/* File: armv5te/unused.S */
9384    bl      common_abort
9385
9386
9387/* ------------------------------ */
9388    .balign 64
9389.L_OP_UNUSED_6CFF: /* 0x16c */
9390/* File: armv5te/OP_UNUSED_6CFF.S */
9391/* File: armv5te/unused.S */
9392    bl      common_abort
9393
9394
9395/* ------------------------------ */
9396    .balign 64
9397.L_OP_UNUSED_6DFF: /* 0x16d */
9398/* File: armv5te/OP_UNUSED_6DFF.S */
9399/* File: armv5te/unused.S */
9400    bl      common_abort
9401
9402
9403/* ------------------------------ */
9404    .balign 64
9405.L_OP_UNUSED_6EFF: /* 0x16e */
9406/* File: armv5te/OP_UNUSED_6EFF.S */
9407/* File: armv5te/unused.S */
9408    bl      common_abort
9409
9410
9411/* ------------------------------ */
9412    .balign 64
9413.L_OP_UNUSED_6FFF: /* 0x16f */
9414/* File: armv5te/OP_UNUSED_6FFF.S */
9415/* File: armv5te/unused.S */
9416    bl      common_abort
9417
9418
9419/* ------------------------------ */
9420    .balign 64
9421.L_OP_UNUSED_70FF: /* 0x170 */
9422/* File: armv5te/OP_UNUSED_70FF.S */
9423/* File: armv5te/unused.S */
9424    bl      common_abort
9425
9426
9427/* ------------------------------ */
9428    .balign 64
9429.L_OP_UNUSED_71FF: /* 0x171 */
9430/* File: armv5te/OP_UNUSED_71FF.S */
9431/* File: armv5te/unused.S */
9432    bl      common_abort
9433
9434
9435/* ------------------------------ */
9436    .balign 64
9437.L_OP_UNUSED_72FF: /* 0x172 */
9438/* File: armv5te/OP_UNUSED_72FF.S */
9439/* File: armv5te/unused.S */
9440    bl      common_abort
9441
9442
9443/* ------------------------------ */
9444    .balign 64
9445.L_OP_UNUSED_73FF: /* 0x173 */
9446/* File: armv5te/OP_UNUSED_73FF.S */
9447/* File: armv5te/unused.S */
9448    bl      common_abort
9449
9450
9451/* ------------------------------ */
9452    .balign 64
9453.L_OP_UNUSED_74FF: /* 0x174 */
9454/* File: armv5te/OP_UNUSED_74FF.S */
9455/* File: armv5te/unused.S */
9456    bl      common_abort
9457
9458
9459/* ------------------------------ */
9460    .balign 64
9461.L_OP_UNUSED_75FF: /* 0x175 */
9462/* File: armv5te/OP_UNUSED_75FF.S */
9463/* File: armv5te/unused.S */
9464    bl      common_abort
9465
9466
9467/* ------------------------------ */
9468    .balign 64
9469.L_OP_UNUSED_76FF: /* 0x176 */
9470/* File: armv5te/OP_UNUSED_76FF.S */
9471/* File: armv5te/unused.S */
9472    bl      common_abort
9473
9474
9475/* ------------------------------ */
9476    .balign 64
9477.L_OP_UNUSED_77FF: /* 0x177 */
9478/* File: armv5te/OP_UNUSED_77FF.S */
9479/* File: armv5te/unused.S */
9480    bl      common_abort
9481
9482
9483/* ------------------------------ */
9484    .balign 64
9485.L_OP_UNUSED_78FF: /* 0x178 */
9486/* File: armv5te/OP_UNUSED_78FF.S */
9487/* File: armv5te/unused.S */
9488    bl      common_abort
9489
9490
9491/* ------------------------------ */
9492    .balign 64
9493.L_OP_UNUSED_79FF: /* 0x179 */
9494/* File: armv5te/OP_UNUSED_79FF.S */
9495/* File: armv5te/unused.S */
9496    bl      common_abort
9497
9498
9499/* ------------------------------ */
9500    .balign 64
9501.L_OP_UNUSED_7AFF: /* 0x17a */
9502/* File: armv5te/OP_UNUSED_7AFF.S */
9503/* File: armv5te/unused.S */
9504    bl      common_abort
9505
9506
9507/* ------------------------------ */
9508    .balign 64
9509.L_OP_UNUSED_7BFF: /* 0x17b */
9510/* File: armv5te/OP_UNUSED_7BFF.S */
9511/* File: armv5te/unused.S */
9512    bl      common_abort
9513
9514
9515/* ------------------------------ */
9516    .balign 64
9517.L_OP_UNUSED_7CFF: /* 0x17c */
9518/* File: armv5te/OP_UNUSED_7CFF.S */
9519/* File: armv5te/unused.S */
9520    bl      common_abort
9521
9522
9523/* ------------------------------ */
9524    .balign 64
9525.L_OP_UNUSED_7DFF: /* 0x17d */
9526/* File: armv5te/OP_UNUSED_7DFF.S */
9527/* File: armv5te/unused.S */
9528    bl      common_abort
9529
9530
9531/* ------------------------------ */
9532    .balign 64
9533.L_OP_UNUSED_7EFF: /* 0x17e */
9534/* File: armv5te/OP_UNUSED_7EFF.S */
9535/* File: armv5te/unused.S */
9536    bl      common_abort
9537
9538
9539/* ------------------------------ */
9540    .balign 64
9541.L_OP_UNUSED_7FFF: /* 0x17f */
9542/* File: armv5te/OP_UNUSED_7FFF.S */
9543/* File: armv5te/unused.S */
9544    bl      common_abort
9545
9546
9547/* ------------------------------ */
9548    .balign 64
9549.L_OP_UNUSED_80FF: /* 0x180 */
9550/* File: armv5te/OP_UNUSED_80FF.S */
9551/* File: armv5te/unused.S */
9552    bl      common_abort
9553
9554
9555/* ------------------------------ */
9556    .balign 64
9557.L_OP_UNUSED_81FF: /* 0x181 */
9558/* File: armv5te/OP_UNUSED_81FF.S */
9559/* File: armv5te/unused.S */
9560    bl      common_abort
9561
9562
9563/* ------------------------------ */
9564    .balign 64
9565.L_OP_UNUSED_82FF: /* 0x182 */
9566/* File: armv5te/OP_UNUSED_82FF.S */
9567/* File: armv5te/unused.S */
9568    bl      common_abort
9569
9570
9571/* ------------------------------ */
9572    .balign 64
9573.L_OP_UNUSED_83FF: /* 0x183 */
9574/* File: armv5te/OP_UNUSED_83FF.S */
9575/* File: armv5te/unused.S */
9576    bl      common_abort
9577
9578
9579/* ------------------------------ */
9580    .balign 64
9581.L_OP_UNUSED_84FF: /* 0x184 */
9582/* File: armv5te/OP_UNUSED_84FF.S */
9583/* File: armv5te/unused.S */
9584    bl      common_abort
9585
9586
9587/* ------------------------------ */
9588    .balign 64
9589.L_OP_UNUSED_85FF: /* 0x185 */
9590/* File: armv5te/OP_UNUSED_85FF.S */
9591/* File: armv5te/unused.S */
9592    bl      common_abort
9593
9594
9595/* ------------------------------ */
9596    .balign 64
9597.L_OP_UNUSED_86FF: /* 0x186 */
9598/* File: armv5te/OP_UNUSED_86FF.S */
9599/* File: armv5te/unused.S */
9600    bl      common_abort
9601
9602
9603/* ------------------------------ */
9604    .balign 64
9605.L_OP_UNUSED_87FF: /* 0x187 */
9606/* File: armv5te/OP_UNUSED_87FF.S */
9607/* File: armv5te/unused.S */
9608    bl      common_abort
9609
9610
9611/* ------------------------------ */
9612    .balign 64
9613.L_OP_UNUSED_88FF: /* 0x188 */
9614/* File: armv5te/OP_UNUSED_88FF.S */
9615/* File: armv5te/unused.S */
9616    bl      common_abort
9617
9618
9619/* ------------------------------ */
9620    .balign 64
9621.L_OP_UNUSED_89FF: /* 0x189 */
9622/* File: armv5te/OP_UNUSED_89FF.S */
9623/* File: armv5te/unused.S */
9624    bl      common_abort
9625
9626
9627/* ------------------------------ */
9628    .balign 64
9629.L_OP_UNUSED_8AFF: /* 0x18a */
9630/* File: armv5te/OP_UNUSED_8AFF.S */
9631/* File: armv5te/unused.S */
9632    bl      common_abort
9633
9634
9635/* ------------------------------ */
9636    .balign 64
9637.L_OP_UNUSED_8BFF: /* 0x18b */
9638/* File: armv5te/OP_UNUSED_8BFF.S */
9639/* File: armv5te/unused.S */
9640    bl      common_abort
9641
9642
9643/* ------------------------------ */
9644    .balign 64
9645.L_OP_UNUSED_8CFF: /* 0x18c */
9646/* File: armv5te/OP_UNUSED_8CFF.S */
9647/* File: armv5te/unused.S */
9648    bl      common_abort
9649
9650
9651/* ------------------------------ */
9652    .balign 64
9653.L_OP_UNUSED_8DFF: /* 0x18d */
9654/* File: armv5te/OP_UNUSED_8DFF.S */
9655/* File: armv5te/unused.S */
9656    bl      common_abort
9657
9658
9659/* ------------------------------ */
9660    .balign 64
9661.L_OP_UNUSED_8EFF: /* 0x18e */
9662/* File: armv5te/OP_UNUSED_8EFF.S */
9663/* File: armv5te/unused.S */
9664    bl      common_abort
9665
9666
9667/* ------------------------------ */
9668    .balign 64
9669.L_OP_UNUSED_8FFF: /* 0x18f */
9670/* File: armv5te/OP_UNUSED_8FFF.S */
9671/* File: armv5te/unused.S */
9672    bl      common_abort
9673
9674
9675/* ------------------------------ */
9676    .balign 64
9677.L_OP_UNUSED_90FF: /* 0x190 */
9678/* File: armv5te/OP_UNUSED_90FF.S */
9679/* File: armv5te/unused.S */
9680    bl      common_abort
9681
9682
9683/* ------------------------------ */
9684    .balign 64
9685.L_OP_UNUSED_91FF: /* 0x191 */
9686/* File: armv5te/OP_UNUSED_91FF.S */
9687/* File: armv5te/unused.S */
9688    bl      common_abort
9689
9690
9691/* ------------------------------ */
9692    .balign 64
9693.L_OP_UNUSED_92FF: /* 0x192 */
9694/* File: armv5te/OP_UNUSED_92FF.S */
9695/* File: armv5te/unused.S */
9696    bl      common_abort
9697
9698
9699/* ------------------------------ */
9700    .balign 64
9701.L_OP_UNUSED_93FF: /* 0x193 */
9702/* File: armv5te/OP_UNUSED_93FF.S */
9703/* File: armv5te/unused.S */
9704    bl      common_abort
9705
9706
9707/* ------------------------------ */
9708    .balign 64
9709.L_OP_UNUSED_94FF: /* 0x194 */
9710/* File: armv5te/OP_UNUSED_94FF.S */
9711/* File: armv5te/unused.S */
9712    bl      common_abort
9713
9714
9715/* ------------------------------ */
9716    .balign 64
9717.L_OP_UNUSED_95FF: /* 0x195 */
9718/* File: armv5te/OP_UNUSED_95FF.S */
9719/* File: armv5te/unused.S */
9720    bl      common_abort
9721
9722
9723/* ------------------------------ */
9724    .balign 64
9725.L_OP_UNUSED_96FF: /* 0x196 */
9726/* File: armv5te/OP_UNUSED_96FF.S */
9727/* File: armv5te/unused.S */
9728    bl      common_abort
9729
9730
9731/* ------------------------------ */
9732    .balign 64
9733.L_OP_UNUSED_97FF: /* 0x197 */
9734/* File: armv5te/OP_UNUSED_97FF.S */
9735/* File: armv5te/unused.S */
9736    bl      common_abort
9737
9738
9739/* ------------------------------ */
9740    .balign 64
9741.L_OP_UNUSED_98FF: /* 0x198 */
9742/* File: armv5te/OP_UNUSED_98FF.S */
9743/* File: armv5te/unused.S */
9744    bl      common_abort
9745
9746
9747/* ------------------------------ */
9748    .balign 64
9749.L_OP_UNUSED_99FF: /* 0x199 */
9750/* File: armv5te/OP_UNUSED_99FF.S */
9751/* File: armv5te/unused.S */
9752    bl      common_abort
9753
9754
9755/* ------------------------------ */
9756    .balign 64
9757.L_OP_UNUSED_9AFF: /* 0x19a */
9758/* File: armv5te/OP_UNUSED_9AFF.S */
9759/* File: armv5te/unused.S */
9760    bl      common_abort
9761
9762
9763/* ------------------------------ */
9764    .balign 64
9765.L_OP_UNUSED_9BFF: /* 0x19b */
9766/* File: armv5te/OP_UNUSED_9BFF.S */
9767/* File: armv5te/unused.S */
9768    bl      common_abort
9769
9770
9771/* ------------------------------ */
9772    .balign 64
9773.L_OP_UNUSED_9CFF: /* 0x19c */
9774/* File: armv5te/OP_UNUSED_9CFF.S */
9775/* File: armv5te/unused.S */
9776    bl      common_abort
9777
9778
9779/* ------------------------------ */
9780    .balign 64
9781.L_OP_UNUSED_9DFF: /* 0x19d */
9782/* File: armv5te/OP_UNUSED_9DFF.S */
9783/* File: armv5te/unused.S */
9784    bl      common_abort
9785
9786
9787/* ------------------------------ */
9788    .balign 64
9789.L_OP_UNUSED_9EFF: /* 0x19e */
9790/* File: armv5te/OP_UNUSED_9EFF.S */
9791/* File: armv5te/unused.S */
9792    bl      common_abort
9793
9794
9795/* ------------------------------ */
9796    .balign 64
9797.L_OP_UNUSED_9FFF: /* 0x19f */
9798/* File: armv5te/OP_UNUSED_9FFF.S */
9799/* File: armv5te/unused.S */
9800    bl      common_abort
9801
9802
9803/* ------------------------------ */
9804    .balign 64
9805.L_OP_UNUSED_A0FF: /* 0x1a0 */
9806/* File: armv5te/OP_UNUSED_A0FF.S */
9807/* File: armv5te/unused.S */
9808    bl      common_abort
9809
9810
9811/* ------------------------------ */
9812    .balign 64
9813.L_OP_UNUSED_A1FF: /* 0x1a1 */
9814/* File: armv5te/OP_UNUSED_A1FF.S */
9815/* File: armv5te/unused.S */
9816    bl      common_abort
9817
9818
9819/* ------------------------------ */
9820    .balign 64
9821.L_OP_UNUSED_A2FF: /* 0x1a2 */
9822/* File: armv5te/OP_UNUSED_A2FF.S */
9823/* File: armv5te/unused.S */
9824    bl      common_abort
9825
9826
9827/* ------------------------------ */
9828    .balign 64
9829.L_OP_UNUSED_A3FF: /* 0x1a3 */
9830/* File: armv5te/OP_UNUSED_A3FF.S */
9831/* File: armv5te/unused.S */
9832    bl      common_abort
9833
9834
9835/* ------------------------------ */
9836    .balign 64
9837.L_OP_UNUSED_A4FF: /* 0x1a4 */
9838/* File: armv5te/OP_UNUSED_A4FF.S */
9839/* File: armv5te/unused.S */
9840    bl      common_abort
9841
9842
9843/* ------------------------------ */
9844    .balign 64
9845.L_OP_UNUSED_A5FF: /* 0x1a5 */
9846/* File: armv5te/OP_UNUSED_A5FF.S */
9847/* File: armv5te/unused.S */
9848    bl      common_abort
9849
9850
9851/* ------------------------------ */
9852    .balign 64
9853.L_OP_UNUSED_A6FF: /* 0x1a6 */
9854/* File: armv5te/OP_UNUSED_A6FF.S */
9855/* File: armv5te/unused.S */
9856    bl      common_abort
9857
9858
9859/* ------------------------------ */
9860    .balign 64
9861.L_OP_UNUSED_A7FF: /* 0x1a7 */
9862/* File: armv5te/OP_UNUSED_A7FF.S */
9863/* File: armv5te/unused.S */
9864    bl      common_abort
9865
9866
9867/* ------------------------------ */
9868    .balign 64
9869.L_OP_UNUSED_A8FF: /* 0x1a8 */
9870/* File: armv5te/OP_UNUSED_A8FF.S */
9871/* File: armv5te/unused.S */
9872    bl      common_abort
9873
9874
9875/* ------------------------------ */
9876    .balign 64
9877.L_OP_UNUSED_A9FF: /* 0x1a9 */
9878/* File: armv5te/OP_UNUSED_A9FF.S */
9879/* File: armv5te/unused.S */
9880    bl      common_abort
9881
9882
9883/* ------------------------------ */
9884    .balign 64
9885.L_OP_UNUSED_AAFF: /* 0x1aa */
9886/* File: armv5te/OP_UNUSED_AAFF.S */
9887/* File: armv5te/unused.S */
9888    bl      common_abort
9889
9890
9891/* ------------------------------ */
9892    .balign 64
9893.L_OP_UNUSED_ABFF: /* 0x1ab */
9894/* File: armv5te/OP_UNUSED_ABFF.S */
9895/* File: armv5te/unused.S */
9896    bl      common_abort
9897
9898
9899/* ------------------------------ */
9900    .balign 64
9901.L_OP_UNUSED_ACFF: /* 0x1ac */
9902/* File: armv5te/OP_UNUSED_ACFF.S */
9903/* File: armv5te/unused.S */
9904    bl      common_abort
9905
9906
9907/* ------------------------------ */
9908    .balign 64
9909.L_OP_UNUSED_ADFF: /* 0x1ad */
9910/* File: armv5te/OP_UNUSED_ADFF.S */
9911/* File: armv5te/unused.S */
9912    bl      common_abort
9913
9914
9915/* ------------------------------ */
9916    .balign 64
9917.L_OP_UNUSED_AEFF: /* 0x1ae */
9918/* File: armv5te/OP_UNUSED_AEFF.S */
9919/* File: armv5te/unused.S */
9920    bl      common_abort
9921
9922
9923/* ------------------------------ */
9924    .balign 64
9925.L_OP_UNUSED_AFFF: /* 0x1af */
9926/* File: armv5te/OP_UNUSED_AFFF.S */
9927/* File: armv5te/unused.S */
9928    bl      common_abort
9929
9930
9931/* ------------------------------ */
9932    .balign 64
9933.L_OP_UNUSED_B0FF: /* 0x1b0 */
9934/* File: armv5te/OP_UNUSED_B0FF.S */
9935/* File: armv5te/unused.S */
9936    bl      common_abort
9937
9938
9939/* ------------------------------ */
9940    .balign 64
9941.L_OP_UNUSED_B1FF: /* 0x1b1 */
9942/* File: armv5te/OP_UNUSED_B1FF.S */
9943/* File: armv5te/unused.S */
9944    bl      common_abort
9945
9946
9947/* ------------------------------ */
9948    .balign 64
9949.L_OP_UNUSED_B2FF: /* 0x1b2 */
9950/* File: armv5te/OP_UNUSED_B2FF.S */
9951/* File: armv5te/unused.S */
9952    bl      common_abort
9953
9954
9955/* ------------------------------ */
9956    .balign 64
9957.L_OP_UNUSED_B3FF: /* 0x1b3 */
9958/* File: armv5te/OP_UNUSED_B3FF.S */
9959/* File: armv5te/unused.S */
9960    bl      common_abort
9961
9962
9963/* ------------------------------ */
9964    .balign 64
9965.L_OP_UNUSED_B4FF: /* 0x1b4 */
9966/* File: armv5te/OP_UNUSED_B4FF.S */
9967/* File: armv5te/unused.S */
9968    bl      common_abort
9969
9970
9971/* ------------------------------ */
9972    .balign 64
9973.L_OP_UNUSED_B5FF: /* 0x1b5 */
9974/* File: armv5te/OP_UNUSED_B5FF.S */
9975/* File: armv5te/unused.S */
9976    bl      common_abort
9977
9978
9979/* ------------------------------ */
9980    .balign 64
9981.L_OP_UNUSED_B6FF: /* 0x1b6 */
9982/* File: armv5te/OP_UNUSED_B6FF.S */
9983/* File: armv5te/unused.S */
9984    bl      common_abort
9985
9986
9987/* ------------------------------ */
9988    .balign 64
9989.L_OP_UNUSED_B7FF: /* 0x1b7 */
9990/* File: armv5te/OP_UNUSED_B7FF.S */
9991/* File: armv5te/unused.S */
9992    bl      common_abort
9993
9994
9995/* ------------------------------ */
9996    .balign 64
9997.L_OP_UNUSED_B8FF: /* 0x1b8 */
9998/* File: armv5te/OP_UNUSED_B8FF.S */
9999/* File: armv5te/unused.S */
10000    bl      common_abort
10001
10002
10003/* ------------------------------ */
10004    .balign 64
10005.L_OP_UNUSED_B9FF: /* 0x1b9 */
10006/* File: armv5te/OP_UNUSED_B9FF.S */
10007/* File: armv5te/unused.S */
10008    bl      common_abort
10009
10010
10011/* ------------------------------ */
10012    .balign 64
10013.L_OP_UNUSED_BAFF: /* 0x1ba */
10014/* File: armv5te/OP_UNUSED_BAFF.S */
10015/* File: armv5te/unused.S */
10016    bl      common_abort
10017
10018
10019/* ------------------------------ */
10020    .balign 64
10021.L_OP_UNUSED_BBFF: /* 0x1bb */
10022/* File: armv5te/OP_UNUSED_BBFF.S */
10023/* File: armv5te/unused.S */
10024    bl      common_abort
10025
10026
10027/* ------------------------------ */
10028    .balign 64
10029.L_OP_UNUSED_BCFF: /* 0x1bc */
10030/* File: armv5te/OP_UNUSED_BCFF.S */
10031/* File: armv5te/unused.S */
10032    bl      common_abort
10033
10034
10035/* ------------------------------ */
10036    .balign 64
10037.L_OP_UNUSED_BDFF: /* 0x1bd */
10038/* File: armv5te/OP_UNUSED_BDFF.S */
10039/* File: armv5te/unused.S */
10040    bl      common_abort
10041
10042
10043/* ------------------------------ */
10044    .balign 64
10045.L_OP_UNUSED_BEFF: /* 0x1be */
10046/* File: armv5te/OP_UNUSED_BEFF.S */
10047/* File: armv5te/unused.S */
10048    bl      common_abort
10049
10050
10051/* ------------------------------ */
10052    .balign 64
10053.L_OP_UNUSED_BFFF: /* 0x1bf */
10054/* File: armv5te/OP_UNUSED_BFFF.S */
10055/* File: armv5te/unused.S */
10056    bl      common_abort
10057
10058
10059/* ------------------------------ */
10060    .balign 64
10061.L_OP_UNUSED_C0FF: /* 0x1c0 */
10062/* File: armv5te/OP_UNUSED_C0FF.S */
10063/* File: armv5te/unused.S */
10064    bl      common_abort
10065
10066
10067/* ------------------------------ */
10068    .balign 64
10069.L_OP_UNUSED_C1FF: /* 0x1c1 */
10070/* File: armv5te/OP_UNUSED_C1FF.S */
10071/* File: armv5te/unused.S */
10072    bl      common_abort
10073
10074
10075/* ------------------------------ */
10076    .balign 64
10077.L_OP_UNUSED_C2FF: /* 0x1c2 */
10078/* File: armv5te/OP_UNUSED_C2FF.S */
10079/* File: armv5te/unused.S */
10080    bl      common_abort
10081
10082
10083/* ------------------------------ */
10084    .balign 64
10085.L_OP_UNUSED_C3FF: /* 0x1c3 */
10086/* File: armv5te/OP_UNUSED_C3FF.S */
10087/* File: armv5te/unused.S */
10088    bl      common_abort
10089
10090
10091/* ------------------------------ */
10092    .balign 64
10093.L_OP_UNUSED_C4FF: /* 0x1c4 */
10094/* File: armv5te/OP_UNUSED_C4FF.S */
10095/* File: armv5te/unused.S */
10096    bl      common_abort
10097
10098
10099/* ------------------------------ */
10100    .balign 64
10101.L_OP_UNUSED_C5FF: /* 0x1c5 */
10102/* File: armv5te/OP_UNUSED_C5FF.S */
10103/* File: armv5te/unused.S */
10104    bl      common_abort
10105
10106
10107/* ------------------------------ */
10108    .balign 64
10109.L_OP_UNUSED_C6FF: /* 0x1c6 */
10110/* File: armv5te/OP_UNUSED_C6FF.S */
10111/* File: armv5te/unused.S */
10112    bl      common_abort
10113
10114
10115/* ------------------------------ */
10116    .balign 64
10117.L_OP_UNUSED_C7FF: /* 0x1c7 */
10118/* File: armv5te/OP_UNUSED_C7FF.S */
10119/* File: armv5te/unused.S */
10120    bl      common_abort
10121
10122
10123/* ------------------------------ */
10124    .balign 64
10125.L_OP_UNUSED_C8FF: /* 0x1c8 */
10126/* File: armv5te/OP_UNUSED_C8FF.S */
10127/* File: armv5te/unused.S */
10128    bl      common_abort
10129
10130
10131/* ------------------------------ */
10132    .balign 64
10133.L_OP_UNUSED_C9FF: /* 0x1c9 */
10134/* File: armv5te/OP_UNUSED_C9FF.S */
10135/* File: armv5te/unused.S */
10136    bl      common_abort
10137
10138
10139/* ------------------------------ */
10140    .balign 64
10141.L_OP_UNUSED_CAFF: /* 0x1ca */
10142/* File: armv5te/OP_UNUSED_CAFF.S */
10143/* File: armv5te/unused.S */
10144    bl      common_abort
10145
10146
10147/* ------------------------------ */
10148    .balign 64
10149.L_OP_UNUSED_CBFF: /* 0x1cb */
10150/* File: armv5te/OP_UNUSED_CBFF.S */
10151/* File: armv5te/unused.S */
10152    bl      common_abort
10153
10154
10155/* ------------------------------ */
10156    .balign 64
10157.L_OP_UNUSED_CCFF: /* 0x1cc */
10158/* File: armv5te/OP_UNUSED_CCFF.S */
10159/* File: armv5te/unused.S */
10160    bl      common_abort
10161
10162
10163/* ------------------------------ */
10164    .balign 64
10165.L_OP_UNUSED_CDFF: /* 0x1cd */
10166/* File: armv5te/OP_UNUSED_CDFF.S */
10167/* File: armv5te/unused.S */
10168    bl      common_abort
10169
10170
10171/* ------------------------------ */
10172    .balign 64
10173.L_OP_UNUSED_CEFF: /* 0x1ce */
10174/* File: armv5te/OP_UNUSED_CEFF.S */
10175/* File: armv5te/unused.S */
10176    bl      common_abort
10177
10178
10179/* ------------------------------ */
10180    .balign 64
10181.L_OP_UNUSED_CFFF: /* 0x1cf */
10182/* File: armv5te/OP_UNUSED_CFFF.S */
10183/* File: armv5te/unused.S */
10184    bl      common_abort
10185
10186
10187/* ------------------------------ */
10188    .balign 64
10189.L_OP_UNUSED_D0FF: /* 0x1d0 */
10190/* File: armv5te/OP_UNUSED_D0FF.S */
10191/* File: armv5te/unused.S */
10192    bl      common_abort
10193
10194
10195/* ------------------------------ */
10196    .balign 64
10197.L_OP_UNUSED_D1FF: /* 0x1d1 */
10198/* File: armv5te/OP_UNUSED_D1FF.S */
10199/* File: armv5te/unused.S */
10200    bl      common_abort
10201
10202
10203/* ------------------------------ */
10204    .balign 64
10205.L_OP_UNUSED_D2FF: /* 0x1d2 */
10206/* File: armv5te/OP_UNUSED_D2FF.S */
10207/* File: armv5te/unused.S */
10208    bl      common_abort
10209
10210
10211/* ------------------------------ */
10212    .balign 64
10213.L_OP_UNUSED_D3FF: /* 0x1d3 */
10214/* File: armv5te/OP_UNUSED_D3FF.S */
10215/* File: armv5te/unused.S */
10216    bl      common_abort
10217
10218
10219/* ------------------------------ */
10220    .balign 64
10221.L_OP_UNUSED_D4FF: /* 0x1d4 */
10222/* File: armv5te/OP_UNUSED_D4FF.S */
10223/* File: armv5te/unused.S */
10224    bl      common_abort
10225
10226
10227/* ------------------------------ */
10228    .balign 64
10229.L_OP_UNUSED_D5FF: /* 0x1d5 */
10230/* File: armv5te/OP_UNUSED_D5FF.S */
10231/* File: armv5te/unused.S */
10232    bl      common_abort
10233
10234
10235/* ------------------------------ */
10236    .balign 64
10237.L_OP_UNUSED_D6FF: /* 0x1d6 */
10238/* File: armv5te/OP_UNUSED_D6FF.S */
10239/* File: armv5te/unused.S */
10240    bl      common_abort
10241
10242
10243/* ------------------------------ */
10244    .balign 64
10245.L_OP_UNUSED_D7FF: /* 0x1d7 */
10246/* File: armv5te/OP_UNUSED_D7FF.S */
10247/* File: armv5te/unused.S */
10248    bl      common_abort
10249
10250
10251/* ------------------------------ */
10252    .balign 64
10253.L_OP_UNUSED_D8FF: /* 0x1d8 */
10254/* File: armv5te/OP_UNUSED_D8FF.S */
10255/* File: armv5te/unused.S */
10256    bl      common_abort
10257
10258
10259/* ------------------------------ */
10260    .balign 64
10261.L_OP_UNUSED_D9FF: /* 0x1d9 */
10262/* File: armv5te/OP_UNUSED_D9FF.S */
10263/* File: armv5te/unused.S */
10264    bl      common_abort
10265
10266
10267/* ------------------------------ */
10268    .balign 64
10269.L_OP_UNUSED_DAFF: /* 0x1da */
10270/* File: armv5te/OP_UNUSED_DAFF.S */
10271/* File: armv5te/unused.S */
10272    bl      common_abort
10273
10274
10275/* ------------------------------ */
10276    .balign 64
10277.L_OP_UNUSED_DBFF: /* 0x1db */
10278/* File: armv5te/OP_UNUSED_DBFF.S */
10279/* File: armv5te/unused.S */
10280    bl      common_abort
10281
10282
10283/* ------------------------------ */
10284    .balign 64
10285.L_OP_UNUSED_DCFF: /* 0x1dc */
10286/* File: armv5te/OP_UNUSED_DCFF.S */
10287/* File: armv5te/unused.S */
10288    bl      common_abort
10289
10290
10291/* ------------------------------ */
10292    .balign 64
10293.L_OP_UNUSED_DDFF: /* 0x1dd */
10294/* File: armv5te/OP_UNUSED_DDFF.S */
10295/* File: armv5te/unused.S */
10296    bl      common_abort
10297
10298
10299/* ------------------------------ */
10300    .balign 64
10301.L_OP_UNUSED_DEFF: /* 0x1de */
10302/* File: armv5te/OP_UNUSED_DEFF.S */
10303/* File: armv5te/unused.S */
10304    bl      common_abort
10305
10306
10307/* ------------------------------ */
10308    .balign 64
10309.L_OP_UNUSED_DFFF: /* 0x1df */
10310/* File: armv5te/OP_UNUSED_DFFF.S */
10311/* File: armv5te/unused.S */
10312    bl      common_abort
10313
10314
10315/* ------------------------------ */
10316    .balign 64
10317.L_OP_UNUSED_E0FF: /* 0x1e0 */
10318/* File: armv5te/OP_UNUSED_E0FF.S */
10319/* File: armv5te/unused.S */
10320    bl      common_abort
10321
10322
10323/* ------------------------------ */
10324    .balign 64
10325.L_OP_UNUSED_E1FF: /* 0x1e1 */
10326/* File: armv5te/OP_UNUSED_E1FF.S */
10327/* File: armv5te/unused.S */
10328    bl      common_abort
10329
10330
10331/* ------------------------------ */
10332    .balign 64
10333.L_OP_UNUSED_E2FF: /* 0x1e2 */
10334/* File: armv5te/OP_UNUSED_E2FF.S */
10335/* File: armv5te/unused.S */
10336    bl      common_abort
10337
10338
10339/* ------------------------------ */
10340    .balign 64
10341.L_OP_UNUSED_E3FF: /* 0x1e3 */
10342/* File: armv5te/OP_UNUSED_E3FF.S */
10343/* File: armv5te/unused.S */
10344    bl      common_abort
10345
10346
10347/* ------------------------------ */
10348    .balign 64
10349.L_OP_UNUSED_E4FF: /* 0x1e4 */
10350/* File: armv5te/OP_UNUSED_E4FF.S */
10351/* File: armv5te/unused.S */
10352    bl      common_abort
10353
10354
10355/* ------------------------------ */
10356    .balign 64
10357.L_OP_UNUSED_E5FF: /* 0x1e5 */
10358/* File: armv5te/OP_UNUSED_E5FF.S */
10359/* File: armv5te/unused.S */
10360    bl      common_abort
10361
10362
10363/* ------------------------------ */
10364    .balign 64
10365.L_OP_UNUSED_E6FF: /* 0x1e6 */
10366/* File: armv5te/OP_UNUSED_E6FF.S */
10367/* File: armv5te/unused.S */
10368    bl      common_abort
10369
10370
10371/* ------------------------------ */
10372    .balign 64
10373.L_OP_UNUSED_E7FF: /* 0x1e7 */
10374/* File: armv5te/OP_UNUSED_E7FF.S */
10375/* File: armv5te/unused.S */
10376    bl      common_abort
10377
10378
10379/* ------------------------------ */
10380    .balign 64
10381.L_OP_UNUSED_E8FF: /* 0x1e8 */
10382/* File: armv5te/OP_UNUSED_E8FF.S */
10383/* File: armv5te/unused.S */
10384    bl      common_abort
10385
10386
10387/* ------------------------------ */
10388    .balign 64
10389.L_OP_UNUSED_E9FF: /* 0x1e9 */
10390/* File: armv5te/OP_UNUSED_E9FF.S */
10391/* File: armv5te/unused.S */
10392    bl      common_abort
10393
10394
10395/* ------------------------------ */
10396    .balign 64
10397.L_OP_UNUSED_EAFF: /* 0x1ea */
10398/* File: armv5te/OP_UNUSED_EAFF.S */
10399/* File: armv5te/unused.S */
10400    bl      common_abort
10401
10402
10403/* ------------------------------ */
10404    .balign 64
10405.L_OP_UNUSED_EBFF: /* 0x1eb */
10406/* File: armv5te/OP_UNUSED_EBFF.S */
10407/* File: armv5te/unused.S */
10408    bl      common_abort
10409
10410
10411/* ------------------------------ */
10412    .balign 64
10413.L_OP_UNUSED_ECFF: /* 0x1ec */
10414/* File: armv5te/OP_UNUSED_ECFF.S */
10415/* File: armv5te/unused.S */
10416    bl      common_abort
10417
10418
10419/* ------------------------------ */
10420    .balign 64
10421.L_OP_UNUSED_EDFF: /* 0x1ed */
10422/* File: armv5te/OP_UNUSED_EDFF.S */
10423/* File: armv5te/unused.S */
10424    bl      common_abort
10425
10426
10427/* ------------------------------ */
10428    .balign 64
10429.L_OP_UNUSED_EEFF: /* 0x1ee */
10430/* File: armv5te/OP_UNUSED_EEFF.S */
10431/* File: armv5te/unused.S */
10432    bl      common_abort
10433
10434
10435/* ------------------------------ */
10436    .balign 64
10437.L_OP_UNUSED_EFFF: /* 0x1ef */
10438/* File: armv5te/OP_UNUSED_EFFF.S */
10439/* File: armv5te/unused.S */
10440    bl      common_abort
10441
10442
10443/* ------------------------------ */
10444    .balign 64
10445.L_OP_UNUSED_F0FF: /* 0x1f0 */
10446/* File: armv5te/OP_UNUSED_F0FF.S */
10447/* File: armv5te/unused.S */
10448    bl      common_abort
10449
10450
10451/* ------------------------------ */
10452    .balign 64
10453.L_OP_UNUSED_F1FF: /* 0x1f1 */
10454/* File: armv5te/OP_UNUSED_F1FF.S */
10455/* File: armv5te/unused.S */
10456    bl      common_abort
10457
10458
10459/* ------------------------------ */
10460    .balign 64
10461.L_OP_UNUSED_F2FF: /* 0x1f2 */
10462/* File: armv5te/OP_UNUSED_F2FF.S */
10463/* File: armv5te/unused.S */
10464    bl      common_abort
10465
10466
10467/* ------------------------------ */
10468    .balign 64
10469.L_OP_UNUSED_F3FF: /* 0x1f3 */
10470/* File: armv5te/OP_UNUSED_F3FF.S */
10471/* File: armv5te/unused.S */
10472    bl      common_abort
10473
10474
10475/* ------------------------------ */
10476    .balign 64
10477.L_OP_UNUSED_F4FF: /* 0x1f4 */
10478/* File: armv5te/OP_UNUSED_F4FF.S */
10479/* File: armv5te/unused.S */
10480    bl      common_abort
10481
10482
10483/* ------------------------------ */
10484    .balign 64
10485.L_OP_UNUSED_F5FF: /* 0x1f5 */
10486/* File: armv5te/OP_UNUSED_F5FF.S */
10487/* File: armv5te/unused.S */
10488    bl      common_abort
10489
10490
10491/* ------------------------------ */
10492    .balign 64
10493.L_OP_UNUSED_F6FF: /* 0x1f6 */
10494/* File: armv5te/OP_UNUSED_F6FF.S */
10495/* File: armv5te/unused.S */
10496    bl      common_abort
10497
10498
10499/* ------------------------------ */
10500    .balign 64
10501.L_OP_UNUSED_F7FF: /* 0x1f7 */
10502/* File: armv5te/OP_UNUSED_F7FF.S */
10503/* File: armv5te/unused.S */
10504    bl      common_abort
10505
10506
10507/* ------------------------------ */
10508    .balign 64
10509.L_OP_UNUSED_F8FF: /* 0x1f8 */
10510/* File: armv5te/OP_UNUSED_F8FF.S */
10511/* File: armv5te/unused.S */
10512    bl      common_abort
10513
10514
10515/* ------------------------------ */
10516    .balign 64
10517.L_OP_UNUSED_F9FF: /* 0x1f9 */
10518/* File: armv5te/OP_UNUSED_F9FF.S */
10519/* File: armv5te/unused.S */
10520    bl      common_abort
10521
10522
10523/* ------------------------------ */
10524    .balign 64
10525.L_OP_UNUSED_FAFF: /* 0x1fa */
10526/* File: armv5te/OP_UNUSED_FAFF.S */
10527/* File: armv5te/unused.S */
10528    bl      common_abort
10529
10530
10531/* ------------------------------ */
10532    .balign 64
10533.L_OP_UNUSED_FBFF: /* 0x1fb */
10534/* File: armv5te/OP_UNUSED_FBFF.S */
10535/* File: armv5te/unused.S */
10536    bl      common_abort
10537
10538
10539/* ------------------------------ */
10540    .balign 64
10541.L_OP_UNUSED_FCFF: /* 0x1fc */
10542/* File: armv5te/OP_UNUSED_FCFF.S */
10543/* File: armv5te/unused.S */
10544    bl      common_abort
10545
10546
10547/* ------------------------------ */
10548    .balign 64
10549.L_OP_UNUSED_FDFF: /* 0x1fd */
10550/* File: armv5te/OP_UNUSED_FDFF.S */
10551/* File: armv5te/unused.S */
10552    bl      common_abort
10553
10554
10555/* ------------------------------ */
10556    .balign 64
10557.L_OP_UNUSED_FEFF: /* 0x1fe */
10558/* File: armv5te/OP_UNUSED_FEFF.S */
10559/* File: armv5te/unused.S */
10560    bl      common_abort
10561
10562
10563/* ------------------------------ */
10564    .balign 64
10565.L_OP_THROW_VERIFICATION_ERROR_JUMBO: /* 0x1ff */
10566/* File: armv5te/OP_THROW_VERIFICATION_ERROR_JUMBO.S */
10567    /*
10568     * Handle a jumbo throw-verification-error instruction.  This throws an
10569     * exception for an error discovered during verification.  The
10570     * exception is indicated by BBBB, with some detail provided by AAAAAAAA.
10571     */
10572    /* exop BBBB, Class@AAAAAAAA */
10573    FETCH(r1, 1)                        @ r1<- aaaa (lo)
10574    FETCH(r2, 2)                        @ r2<- AAAA (hi)
10575    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
10576    orr     r2, r1, r2, lsl #16         @ r2<- AAAAaaaa
10577    EXPORT_PC()                         @ export the PC
10578    FETCH(r1, 3)                        @ r1<- BBBB
10579    bl      dvmThrowVerificationError   @ always throws
10580    b       common_exceptionThrown      @ handle exception
10581
10582
10583    .balign 64
10584    .size   .L_OP_NOP, .-.L_OP_NOP
10585    .global dvmAsmInstructionEnd
10586dvmAsmInstructionEnd:
10587
10588/*
10589 * ===========================================================================
10590 *  Sister implementations
10591 * ===========================================================================
10592 */
10593    .global dvmAsmSisterStart
10594    .type   dvmAsmSisterStart, %function
10595    .text
10596    .balign 4
10597dvmAsmSisterStart:
10598
10599/* continuation for OP_CONST_STRING */
10600
10601    /*
10602     * Continuation if the String has not yet been resolved.
10603     *  r1: BBBB (String ref)
10604     *  r9: target register
10605     */
10606.LOP_CONST_STRING_resolve:
10607    EXPORT_PC()
10608    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
10609    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10610    bl      dvmResolveString            @ r0<- String reference
10611    cmp     r0, #0                      @ failed?
10612    beq     common_exceptionThrown      @ yup, handle the exception
10613    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10614    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10615    SET_VREG(r0, r9)                    @ vAA<- r0
10616    GOTO_OPCODE(ip)                     @ jump to next instruction
10617
10618/* continuation for OP_CONST_STRING_JUMBO */
10619
10620    /*
10621     * Continuation if the String has not yet been resolved.
10622     *  r1: BBBBBBBB (String ref)
10623     *  r9: target register
10624     */
10625.LOP_CONST_STRING_JUMBO_resolve:
10626    EXPORT_PC()
10627    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
10628    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10629    bl      dvmResolveString            @ r0<- String reference
10630    cmp     r0, #0                      @ failed?
10631    beq     common_exceptionThrown      @ yup, handle the exception
10632    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
10633    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10634    SET_VREG(r0, r9)                    @ vAA<- r0
10635    GOTO_OPCODE(ip)                     @ jump to next instruction
10636
10637/* continuation for OP_CONST_CLASS */
10638
10639    /*
10640     * Continuation if the Class has not yet been resolved.
10641     *  r1: BBBB (Class ref)
10642     *  r9: target register
10643     */
10644.LOP_CONST_CLASS_resolve:
10645    EXPORT_PC()
10646    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
10647    mov     r2, #1                      @ r2<- true
10648    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10649    bl      dvmResolveClass             @ r0<- Class reference
10650    cmp     r0, #0                      @ failed?
10651    beq     common_exceptionThrown      @ yup, handle the exception
10652    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10653    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10654    SET_VREG(r0, r9)                    @ vAA<- r0
10655    GOTO_OPCODE(ip)                     @ jump to next instruction
10656
10657/* continuation for OP_CHECK_CAST */
10658
10659    /*
10660     * Trivial test failed, need to perform full check.  This is common.
10661     *  r0 holds obj->clazz
10662     *  r1 holds desired class resolved from BBBB
10663     *  r9 holds object
10664     */
10665.LOP_CHECK_CAST_fullcheck:
10666    mov     r10, r1                     @ avoid ClassObject getting clobbered
10667    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
10668    cmp     r0, #0                      @ failed?
10669    bne     .LOP_CHECK_CAST_okay            @ no, success
10670
10671    @ A cast has failed.  We need to throw a ClassCastException.
10672    EXPORT_PC()                         @ about to throw
10673    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
10674    mov     r1, r10                     @ r1<- desired class
10675    bl      dvmThrowClassCastException
10676    b       common_exceptionThrown
10677
10678    /*
10679     * Resolution required.  This is the least-likely path.
10680     *
10681     *  r2 holds BBBB
10682     *  r9 holds object
10683     */
10684.LOP_CHECK_CAST_resolve:
10685    EXPORT_PC()                         @ resolve() could throw
10686    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
10687    mov     r1, r2                      @ r1<- BBBB
10688    mov     r2, #0                      @ r2<- false
10689    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10690    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10691    cmp     r0, #0                      @ got null?
10692    beq     common_exceptionThrown      @ yes, handle exception
10693    mov     r1, r0                      @ r1<- class resolved from BBB
10694    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
10695    b       .LOP_CHECK_CAST_resolved        @ pick up where we left off
10696
10697/* continuation for OP_INSTANCE_OF */
10698
10699    /*
10700     * Trivial test failed, need to perform full check.  This is common.
10701     *  r0 holds obj->clazz
10702     *  r1 holds class resolved from BBBB
10703     *  r9 holds A
10704     */
10705.LOP_INSTANCE_OF_fullcheck:
10706    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
10707    @ fall through to OP_INSTANCE_OF_store
10708
10709    /*
10710     * r0 holds boolean result
10711     * r9 holds A
10712     */
10713.LOP_INSTANCE_OF_store:
10714    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10715    SET_VREG(r0, r9)                    @ vA<- r0
10716    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10717    GOTO_OPCODE(ip)                     @ jump to next instruction
10718
10719    /*
10720     * Trivial test succeeded, save and bail.
10721     *  r9 holds A
10722     */
10723.LOP_INSTANCE_OF_trivial:
10724    mov     r0, #1                      @ indicate success
10725    @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper
10726    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10727    SET_VREG(r0, r9)                    @ vA<- r0
10728    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10729    GOTO_OPCODE(ip)                     @ jump to next instruction
10730
10731    /*
10732     * Resolution required.  This is the least-likely path.
10733     *
10734     *  r3 holds BBBB
10735     *  r9 holds A
10736     */
10737.LOP_INSTANCE_OF_resolve:
10738    EXPORT_PC()                         @ resolve() could throw
10739    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
10740    mov     r1, r3                      @ r1<- BBBB
10741    mov     r2, #1                      @ r2<- true
10742    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10743    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10744    cmp     r0, #0                      @ got null?
10745    beq     common_exceptionThrown      @ yes, handle exception
10746    mov     r1, r0                      @ r1<- class resolved from BBB
10747    mov     r3, rINST, lsr #12          @ r3<- B
10748    GET_VREG(r0, r3)                    @ r0<- vB (object)
10749    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
10750    b       .LOP_INSTANCE_OF_resolved        @ pick up where we left off
10751
10752/* continuation for OP_NEW_INSTANCE */
10753
10754    .balign 32                          @ minimize cache lines
10755.LOP_NEW_INSTANCE_finish: @ r0=new object
10756    mov     r3, rINST, lsr #8           @ r3<- AA
10757    cmp     r0, #0                      @ failed?
10758    beq     common_exceptionThrown      @ yes, handle the exception
10759    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10760    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10761    SET_VREG(r0, r3)                    @ vAA<- r0
10762    GOTO_OPCODE(ip)                     @ jump to next instruction
10763
10764    /*
10765     * Class initialization required.
10766     *
10767     *  r0 holds class object
10768     */
10769.LOP_NEW_INSTANCE_needinit:
10770    mov     r9, r0                      @ save r0
10771    bl      dvmInitClass                @ initialize class
10772    cmp     r0, #0                      @ check boolean result
10773    mov     r0, r9                      @ restore r0
10774    bne     .LOP_NEW_INSTANCE_initialized     @ success, continue
10775    b       common_exceptionThrown      @ failed, deal with init exception
10776
10777    /*
10778     * Resolution required.  This is the least-likely path.
10779     *
10780     *  r1 holds BBBB
10781     */
10782.LOP_NEW_INSTANCE_resolve:
10783    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
10784    mov     r2, #0                      @ r2<- false
10785    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10786    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10787    cmp     r0, #0                      @ got null?
10788    bne     .LOP_NEW_INSTANCE_resolved        @ no, continue
10789    b       common_exceptionThrown      @ yes, handle exception
10790
10791.LstrInstantiationErrorPtr:
10792    .word   .LstrInstantiationError
10793
10794/* continuation for OP_NEW_ARRAY */
10795
10796
10797    /*
10798     * Resolve class.  (This is an uncommon case.)
10799     *
10800     *  r1 holds array length
10801     *  r2 holds class ref CCCC
10802     */
10803.LOP_NEW_ARRAY_resolve:
10804    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
10805    mov     r9, r1                      @ r9<- length (save)
10806    mov     r1, r2                      @ r1<- CCCC
10807    mov     r2, #0                      @ r2<- false
10808    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10809    bl      dvmResolveClass             @ r0<- call(clazz, ref)
10810    cmp     r0, #0                      @ got null?
10811    mov     r1, r9                      @ r1<- length (restore)
10812    beq     common_exceptionThrown      @ yes, handle exception
10813    @ fall through to OP_NEW_ARRAY_finish
10814
10815    /*
10816     * Finish allocation.
10817     *
10818     *  r0 holds class
10819     *  r1 holds array length
10820     */
10821.LOP_NEW_ARRAY_finish:
10822    mov     r2, #ALLOC_DONT_TRACK       @ don't track in local refs table
10823    bl      dvmAllocArrayByClass        @ r0<- call(clazz, length, flags)
10824    cmp     r0, #0                      @ failed?
10825    mov     r2, rINST, lsr #8           @ r2<- A+
10826    beq     common_exceptionThrown      @ yes, handle the exception
10827    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10828    and     r2, r2, #15                 @ r2<- A
10829    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10830    SET_VREG(r0, r2)                    @ vA<- r0
10831    GOTO_OPCODE(ip)                     @ jump to next instruction
10832
10833/* continuation for OP_FILLED_NEW_ARRAY */
10834
10835    /*
10836     * On entry:
10837     *  r0 holds array class
10838     *  r10 holds AA or BA
10839     */
10840.LOP_FILLED_NEW_ARRAY_continue:
10841    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
10842    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
10843    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
10844    .if     0
10845    mov     r1, r10                     @ r1<- AA (length)
10846    .else
10847    mov     r1, r10, lsr #4             @ r1<- B (length)
10848    .endif
10849    cmp     rINST, #'I'                 @ array of ints?
10850    cmpne   rINST, #'L'                 @ array of objects?
10851    cmpne   rINST, #'['                 @ array of arrays?
10852    mov     r9, r1                      @ save length in r9
10853    bne     .LOP_FILLED_NEW_ARRAY_notimpl         @ no, not handled yet
10854    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
10855    cmp     r0, #0                      @ null return?
10856    beq     common_exceptionThrown      @ alloc failed, handle exception
10857
10858    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
10859    str     r0, [rGLUE, #offGlue_retval]      @ retval.l <- new array
10860    str     rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type
10861    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
10862    subs    r9, r9, #1                  @ length--, check for neg
10863    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
10864    bmi     2f                          @ was zero, bail
10865
10866    @ copy values from registers into the array
10867    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
10868    .if     0
10869    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
108701:  ldr     r3, [r2], #4                @ r3<- *r2++
10871    subs    r9, r9, #1                  @ count--
10872    str     r3, [r0], #4                @ *contents++ = vX
10873    bpl     1b
10874    @ continue at 2
10875    .else
10876    cmp     r9, #4                      @ length was initially 5?
10877    and     r2, r10, #15                @ r2<- A
10878    bne     1f                          @ <= 4 args, branch
10879    GET_VREG(r3, r2)                    @ r3<- vA
10880    sub     r9, r9, #1                  @ count--
10881    str     r3, [r0, #16]               @ contents[4] = vA
108821:  and     r2, r1, #15                 @ r2<- F/E/D/C
10883    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
10884    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
10885    subs    r9, r9, #1                  @ count--
10886    str     r3, [r0], #4                @ *contents++ = vX
10887    bpl     1b
10888    @ continue at 2
10889    .endif
10890
108912:
10892    ldr     r0, [rGLUE, #offGlue_retval]     @ r0<- object
10893    ldr     r1, [rGLUE, #offGlue_retval+4]   @ r1<- type
10894    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
10895    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
10896    cmp     r1, #'I'                         @ Is int array?
10897    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
10898    GOTO_OPCODE(ip)                          @ execute it
10899
10900    /*
10901     * Throw an exception indicating that we have not implemented this
10902     * mode of filled-new-array.
10903     */
10904.LOP_FILLED_NEW_ARRAY_notimpl:
10905    ldr     r0, .L_strInternalError
10906    ldr     r1, .L_strFilledNewArrayNotImpl
10907    bl      dvmThrowException
10908    b       common_exceptionThrown
10909
10910    .if     (!0)                 @ define in one or the other, not both
10911.L_strFilledNewArrayNotImpl:
10912    .word   .LstrFilledNewArrayNotImpl
10913.L_strInternalError:
10914    .word   .LstrInternalError
10915    .endif
10916
10917/* continuation for OP_FILLED_NEW_ARRAY_RANGE */
10918
10919    /*
10920     * On entry:
10921     *  r0 holds array class
10922     *  r10 holds AA or BA
10923     */
10924.LOP_FILLED_NEW_ARRAY_RANGE_continue:
10925    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
10926    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
10927    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
10928    .if     1
10929    mov     r1, r10                     @ r1<- AA (length)
10930    .else
10931    mov     r1, r10, lsr #4             @ r1<- B (length)
10932    .endif
10933    cmp     rINST, #'I'                 @ array of ints?
10934    cmpne   rINST, #'L'                 @ array of objects?
10935    cmpne   rINST, #'['                 @ array of arrays?
10936    mov     r9, r1                      @ save length in r9
10937    bne     .LOP_FILLED_NEW_ARRAY_RANGE_notimpl         @ no, not handled yet
10938    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
10939    cmp     r0, #0                      @ null return?
10940    beq     common_exceptionThrown      @ alloc failed, handle exception
10941
10942    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
10943    str     r0, [rGLUE, #offGlue_retval]      @ retval.l <- new array
10944    str     rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type
10945    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
10946    subs    r9, r9, #1                  @ length--, check for neg
10947    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
10948    bmi     2f                          @ was zero, bail
10949
10950    @ copy values from registers into the array
10951    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
10952    .if     1
10953    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
109541:  ldr     r3, [r2], #4                @ r3<- *r2++
10955    subs    r9, r9, #1                  @ count--
10956    str     r3, [r0], #4                @ *contents++ = vX
10957    bpl     1b
10958    @ continue at 2
10959    .else
10960    cmp     r9, #4                      @ length was initially 5?
10961    and     r2, r10, #15                @ r2<- A
10962    bne     1f                          @ <= 4 args, branch
10963    GET_VREG(r3, r2)                    @ r3<- vA
10964    sub     r9, r9, #1                  @ count--
10965    str     r3, [r0, #16]               @ contents[4] = vA
109661:  and     r2, r1, #15                 @ r2<- F/E/D/C
10967    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
10968    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
10969    subs    r9, r9, #1                  @ count--
10970    str     r3, [r0], #4                @ *contents++ = vX
10971    bpl     1b
10972    @ continue at 2
10973    .endif
10974
109752:
10976    ldr     r0, [rGLUE, #offGlue_retval]     @ r0<- object
10977    ldr     r1, [rGLUE, #offGlue_retval+4]   @ r1<- type
10978    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
10979    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
10980    cmp     r1, #'I'                         @ Is int array?
10981    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
10982    GOTO_OPCODE(ip)                          @ execute it
10983
10984    /*
10985     * Throw an exception indicating that we have not implemented this
10986     * mode of filled-new-array.
10987     */
10988.LOP_FILLED_NEW_ARRAY_RANGE_notimpl:
10989    ldr     r0, .L_strInternalError
10990    ldr     r1, .L_strFilledNewArrayNotImpl
10991    bl      dvmThrowException
10992    b       common_exceptionThrown
10993
10994    .if     (!1)                 @ define in one or the other, not both
10995.L_strFilledNewArrayNotImpl:
10996    .word   .LstrFilledNewArrayNotImpl
10997.L_strInternalError:
10998    .word   .LstrInternalError
10999    .endif
11000
11001/* continuation for OP_CMPL_FLOAT */
11002.LOP_CMPL_FLOAT_finish:
11003    SET_VREG(r0, r9)                    @ vAA<- r0
11004    GOTO_OPCODE(ip)                     @ jump to next instruction
11005
11006/* continuation for OP_CMPG_FLOAT */
11007.LOP_CMPG_FLOAT_finish:
11008    SET_VREG(r0, r9)                    @ vAA<- r0
11009    GOTO_OPCODE(ip)                     @ jump to next instruction
11010
11011/* continuation for OP_CMPL_DOUBLE */
11012.LOP_CMPL_DOUBLE_finish:
11013    SET_VREG(r0, r9)                    @ vAA<- r0
11014    GOTO_OPCODE(ip)                     @ jump to next instruction
11015
11016/* continuation for OP_CMPG_DOUBLE */
11017.LOP_CMPG_DOUBLE_finish:
11018    SET_VREG(r0, r9)                    @ vAA<- r0
11019    GOTO_OPCODE(ip)                     @ jump to next instruction
11020
11021/* continuation for OP_CMP_LONG */
11022
11023.LOP_CMP_LONG_less:
11024    mvn     r1, #0                      @ r1<- -1
11025    @ Want to cond code the next mov so we can avoid branch, but don't see it;
11026    @ instead, we just replicate the tail end.
11027    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11028    SET_VREG(r1, r9)                    @ vAA<- r1
11029    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11030    GOTO_OPCODE(ip)                     @ jump to next instruction
11031
11032.LOP_CMP_LONG_greater:
11033    mov     r1, #1                      @ r1<- 1
11034    @ fall through to _finish
11035
11036.LOP_CMP_LONG_finish:
11037    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11038    SET_VREG(r1, r9)                    @ vAA<- r1
11039    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11040    GOTO_OPCODE(ip)                     @ jump to next instruction
11041
11042/* continuation for OP_AGET_WIDE */
11043
11044.LOP_AGET_WIDE_finish:
11045    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11046    ldrd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
11047    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
11048    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11049    stmia   r9, {r2-r3}                 @ vAA/vAA+1<- r2/r3
11050    GOTO_OPCODE(ip)                     @ jump to next instruction
11051
11052/* continuation for OP_APUT_WIDE */
11053
11054.LOP_APUT_WIDE_finish:
11055    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11056    ldmia   r9, {r2-r3}                 @ r2/r3<- vAA/vAA+1
11057    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11058    strd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
11059    GOTO_OPCODE(ip)                     @ jump to next instruction
11060
11061/* continuation for OP_APUT_OBJECT */
11062    /*
11063     * On entry:
11064     *  rINST = vBB (arrayObj)
11065     *  r9 = vAA (obj)
11066     *  r10 = offset into array (vBB + vCC * width)
11067     */
11068.LOP_APUT_OBJECT_finish:
11069    cmp     r9, #0                      @ storing null reference?
11070    beq     .LOP_APUT_OBJECT_skip_check      @ yes, skip type checks
11071    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
11072    ldr     r1, [rINST, #offObject_clazz]  @ r1<- arrayObj->clazz
11073    bl      dvmCanPutArrayElement       @ test object type vs. array type
11074    cmp     r0, #0                      @ okay?
11075    beq     .LOP_APUT_OBJECT_throw           @ no
11076    mov     r1, rINST                   @ r1<- arrayObj
11077    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11078    ldr     r2, [rGLUE, #offGlue_cardTable]     @ get biased CT base
11079    add     r10, #offArrayObject_contents   @ r0<- pointer to slot
11080    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11081    str     r9, [r10]                   @ vBB[vCC]<- vAA
11082    strb    r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head
11083    GOTO_OPCODE(ip)                     @ jump to next instruction
11084.LOP_APUT_OBJECT_skip_check:
11085    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11086    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11087    str     r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA
11088    GOTO_OPCODE(ip)                     @ jump to next instruction
11089.LOP_APUT_OBJECT_throw:
11090    @ The types don't match.  We need to throw an ArrayStoreException.
11091    ldr     r0, [r9, #offObject_clazz]
11092    ldr     r1, [rINST, #offObject_clazz]
11093    EXPORT_PC()
11094    bl      dvmThrowArrayStoreException
11095    b       common_exceptionThrown
11096
11097/* continuation for OP_IGET */
11098
11099    /*
11100     * Currently:
11101     *  r0 holds resolved field
11102     *  r9 holds object
11103     */
11104.LOP_IGET_finish:
11105    @bl      common_squeak0
11106    cmp     r9, #0                      @ check object for null
11107    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11108    beq     common_errNullObject        @ object was null
11109    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11110    @ no-op                             @ acquiring load
11111    mov     r2, rINST, lsr #8           @ r2<- A+
11112    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11113    and     r2, r2, #15                 @ r2<- A
11114    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11115    SET_VREG(r0, r2)                    @ fp[A]<- r0
11116    GOTO_OPCODE(ip)                     @ jump to next instruction
11117
11118/* continuation for OP_IGET_WIDE */
11119
11120    /*
11121     * Currently:
11122     *  r0 holds resolved field
11123     *  r9 holds object
11124     */
11125.LOP_IGET_WIDE_finish:
11126    cmp     r9, #0                      @ check object for null
11127    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11128    beq     common_errNullObject        @ object was null
11129    .if     0
11130    add     r0, r9, r3                  @ r0<- address of field
11131    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
11132    .else
11133    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
11134    .endif
11135    mov     r2, rINST, lsr #8           @ r2<- A+
11136    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11137    and     r2, r2, #15                 @ r2<- A
11138    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
11139    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11140    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
11141    GOTO_OPCODE(ip)                     @ jump to next instruction
11142
11143/* continuation for OP_IGET_OBJECT */
11144
11145    /*
11146     * Currently:
11147     *  r0 holds resolved field
11148     *  r9 holds object
11149     */
11150.LOP_IGET_OBJECT_finish:
11151    @bl      common_squeak0
11152    cmp     r9, #0                      @ check object for null
11153    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11154    beq     common_errNullObject        @ object was null
11155    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11156    @ no-op                             @ acquiring load
11157    mov     r2, rINST, lsr #8           @ r2<- A+
11158    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11159    and     r2, r2, #15                 @ r2<- A
11160    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11161    SET_VREG(r0, r2)                    @ fp[A]<- r0
11162    GOTO_OPCODE(ip)                     @ jump to next instruction
11163
11164/* continuation for OP_IGET_BOOLEAN */
11165
11166    /*
11167     * Currently:
11168     *  r0 holds resolved field
11169     *  r9 holds object
11170     */
11171.LOP_IGET_BOOLEAN_finish:
11172    @bl      common_squeak1
11173    cmp     r9, #0                      @ check object for null
11174    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11175    beq     common_errNullObject        @ object was null
11176    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11177    @ no-op                             @ acquiring load
11178    mov     r2, rINST, lsr #8           @ r2<- A+
11179    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11180    and     r2, r2, #15                 @ r2<- A
11181    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11182    SET_VREG(r0, r2)                    @ fp[A]<- r0
11183    GOTO_OPCODE(ip)                     @ jump to next instruction
11184
11185/* continuation for OP_IGET_BYTE */
11186
11187    /*
11188     * Currently:
11189     *  r0 holds resolved field
11190     *  r9 holds object
11191     */
11192.LOP_IGET_BYTE_finish:
11193    @bl      common_squeak2
11194    cmp     r9, #0                      @ check object for null
11195    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11196    beq     common_errNullObject        @ object was null
11197    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11198    @ no-op                             @ acquiring load
11199    mov     r2, rINST, lsr #8           @ r2<- A+
11200    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11201    and     r2, r2, #15                 @ r2<- A
11202    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11203    SET_VREG(r0, r2)                    @ fp[A]<- r0
11204    GOTO_OPCODE(ip)                     @ jump to next instruction
11205
11206/* continuation for OP_IGET_CHAR */
11207
11208    /*
11209     * Currently:
11210     *  r0 holds resolved field
11211     *  r9 holds object
11212     */
11213.LOP_IGET_CHAR_finish:
11214    @bl      common_squeak3
11215    cmp     r9, #0                      @ check object for null
11216    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11217    beq     common_errNullObject        @ object was null
11218    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11219    @ no-op                             @ acquiring load
11220    mov     r2, rINST, lsr #8           @ r2<- A+
11221    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11222    and     r2, r2, #15                 @ r2<- A
11223    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11224    SET_VREG(r0, r2)                    @ fp[A]<- r0
11225    GOTO_OPCODE(ip)                     @ jump to next instruction
11226
11227/* continuation for OP_IGET_SHORT */
11228
11229    /*
11230     * Currently:
11231     *  r0 holds resolved field
11232     *  r9 holds object
11233     */
11234.LOP_IGET_SHORT_finish:
11235    @bl      common_squeak4
11236    cmp     r9, #0                      @ check object for null
11237    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11238    beq     common_errNullObject        @ object was null
11239    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11240    @ no-op                             @ acquiring load
11241    mov     r2, rINST, lsr #8           @ r2<- A+
11242    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11243    and     r2, r2, #15                 @ r2<- A
11244    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11245    SET_VREG(r0, r2)                    @ fp[A]<- r0
11246    GOTO_OPCODE(ip)                     @ jump to next instruction
11247
11248/* continuation for OP_IPUT */
11249
11250    /*
11251     * Currently:
11252     *  r0 holds resolved field
11253     *  r9 holds object
11254     */
11255.LOP_IPUT_finish:
11256    @bl      common_squeak0
11257    mov     r1, rINST, lsr #8           @ r1<- A+
11258    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11259    and     r1, r1, #15                 @ r1<- A
11260    cmp     r9, #0                      @ check object for null
11261    GET_VREG(r0, r1)                    @ r0<- fp[A]
11262    beq     common_errNullObject        @ object was null
11263    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11264    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11265    @ no-op                             @ releasing store
11266    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11267    GOTO_OPCODE(ip)                     @ jump to next instruction
11268
11269/* continuation for OP_IPUT_WIDE */
11270
11271    /*
11272     * Currently:
11273     *  r0 holds resolved field
11274     *  r9 holds object
11275     */
11276.LOP_IPUT_WIDE_finish:
11277    mov     r2, rINST, lsr #8           @ r2<- A+
11278    cmp     r9, #0                      @ check object for null
11279    and     r2, r2, #15                 @ r2<- A
11280    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11281    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
11282    beq     common_errNullObject        @ object was null
11283    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11284    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
11285    GET_INST_OPCODE(r10)                @ extract opcode from rINST
11286    .if     0
11287    add     r2, r9, r3                  @ r2<- target address
11288    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
11289    .else
11290    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
11291    .endif
11292    GOTO_OPCODE(r10)                    @ jump to next instruction
11293
11294/* continuation for OP_IPUT_OBJECT */
11295
11296    /*
11297     * Currently:
11298     *  r0 holds resolved field
11299     *  r9 holds object
11300     */
11301.LOP_IPUT_OBJECT_finish:
11302    @bl      common_squeak0
11303    mov     r1, rINST, lsr #8           @ r1<- A+
11304    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11305    and     r1, r1, #15                 @ r1<- A
11306    cmp     r9, #0                      @ check object for null
11307    GET_VREG(r0, r1)                    @ r0<- fp[A]
11308    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
11309    beq     common_errNullObject        @ object was null
11310    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11311    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11312    @ no-op                             @ releasing store
11313    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
11314    cmp     r0, #0                      @ stored a null reference?
11315    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
11316    GOTO_OPCODE(ip)                     @ jump to next instruction
11317
11318/* continuation for OP_IPUT_BOOLEAN */
11319
11320    /*
11321     * Currently:
11322     *  r0 holds resolved field
11323     *  r9 holds object
11324     */
11325.LOP_IPUT_BOOLEAN_finish:
11326    @bl      common_squeak1
11327    mov     r1, rINST, lsr #8           @ r1<- A+
11328    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11329    and     r1, r1, #15                 @ r1<- A
11330    cmp     r9, #0                      @ check object for null
11331    GET_VREG(r0, r1)                    @ r0<- fp[A]
11332    beq     common_errNullObject        @ object was null
11333    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11334    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11335    @ no-op                             @ releasing store
11336    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11337    GOTO_OPCODE(ip)                     @ jump to next instruction
11338
11339/* continuation for OP_IPUT_BYTE */
11340
11341    /*
11342     * Currently:
11343     *  r0 holds resolved field
11344     *  r9 holds object
11345     */
11346.LOP_IPUT_BYTE_finish:
11347    @bl      common_squeak2
11348    mov     r1, rINST, lsr #8           @ r1<- A+
11349    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11350    and     r1, r1, #15                 @ r1<- A
11351    cmp     r9, #0                      @ check object for null
11352    GET_VREG(r0, r1)                    @ r0<- fp[A]
11353    beq     common_errNullObject        @ object was null
11354    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11355    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11356    @ no-op                             @ releasing store
11357    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11358    GOTO_OPCODE(ip)                     @ jump to next instruction
11359
11360/* continuation for OP_IPUT_CHAR */
11361
11362    /*
11363     * Currently:
11364     *  r0 holds resolved field
11365     *  r9 holds object
11366     */
11367.LOP_IPUT_CHAR_finish:
11368    @bl      common_squeak3
11369    mov     r1, rINST, lsr #8           @ r1<- A+
11370    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11371    and     r1, r1, #15                 @ r1<- A
11372    cmp     r9, #0                      @ check object for null
11373    GET_VREG(r0, r1)                    @ r0<- fp[A]
11374    beq     common_errNullObject        @ object was null
11375    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11376    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11377    @ no-op                             @ releasing store
11378    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11379    GOTO_OPCODE(ip)                     @ jump to next instruction
11380
11381/* continuation for OP_IPUT_SHORT */
11382
11383    /*
11384     * Currently:
11385     *  r0 holds resolved field
11386     *  r9 holds object
11387     */
11388.LOP_IPUT_SHORT_finish:
11389    @bl      common_squeak4
11390    mov     r1, rINST, lsr #8           @ r1<- A+
11391    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11392    and     r1, r1, #15                 @ r1<- A
11393    cmp     r9, #0                      @ check object for null
11394    GET_VREG(r0, r1)                    @ r0<- fp[A]
11395    beq     common_errNullObject        @ object was null
11396    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11397    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11398    @ no-op                             @ releasing store
11399    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11400    GOTO_OPCODE(ip)                     @ jump to next instruction
11401
11402/* continuation for OP_SGET */
11403
11404    /*
11405     * Continuation if the field has not yet been resolved.
11406     *  r1: BBBB field ref
11407     */
11408.LOP_SGET_resolve:
11409    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11410    EXPORT_PC()                         @ resolve() could throw, so export now
11411    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11412    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11413    cmp     r0, #0                      @ success?
11414    bne     .LOP_SGET_finish          @ yes, finish
11415    b       common_exceptionThrown      @ no, handle exception
11416
11417/* continuation for OP_SGET_WIDE */
11418
11419    /*
11420     * Continuation if the field has not yet been resolved.
11421     *  r1: BBBB field ref
11422     *
11423     * Returns StaticField pointer in r0.
11424     */
11425.LOP_SGET_WIDE_resolve:
11426    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11427    EXPORT_PC()                         @ resolve() could throw, so export now
11428    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11429    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11430    cmp     r0, #0                      @ success?
11431    bne     .LOP_SGET_WIDE_finish          @ yes, finish
11432    b       common_exceptionThrown      @ no, handle exception
11433
11434/* continuation for OP_SGET_OBJECT */
11435
11436    /*
11437     * Continuation if the field has not yet been resolved.
11438     *  r1: BBBB field ref
11439     */
11440.LOP_SGET_OBJECT_resolve:
11441    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11442    EXPORT_PC()                         @ resolve() could throw, so export now
11443    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11444    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11445    cmp     r0, #0                      @ success?
11446    bne     .LOP_SGET_OBJECT_finish          @ yes, finish
11447    b       common_exceptionThrown      @ no, handle exception
11448
11449/* continuation for OP_SGET_BOOLEAN */
11450
11451    /*
11452     * Continuation if the field has not yet been resolved.
11453     *  r1: BBBB field ref
11454     */
11455.LOP_SGET_BOOLEAN_resolve:
11456    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11457    EXPORT_PC()                         @ resolve() could throw, so export now
11458    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11459    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11460    cmp     r0, #0                      @ success?
11461    bne     .LOP_SGET_BOOLEAN_finish          @ yes, finish
11462    b       common_exceptionThrown      @ no, handle exception
11463
11464/* continuation for OP_SGET_BYTE */
11465
11466    /*
11467     * Continuation if the field has not yet been resolved.
11468     *  r1: BBBB field ref
11469     */
11470.LOP_SGET_BYTE_resolve:
11471    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11472    EXPORT_PC()                         @ resolve() could throw, so export now
11473    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11474    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11475    cmp     r0, #0                      @ success?
11476    bne     .LOP_SGET_BYTE_finish          @ yes, finish
11477    b       common_exceptionThrown      @ no, handle exception
11478
11479/* continuation for OP_SGET_CHAR */
11480
11481    /*
11482     * Continuation if the field has not yet been resolved.
11483     *  r1: BBBB field ref
11484     */
11485.LOP_SGET_CHAR_resolve:
11486    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11487    EXPORT_PC()                         @ resolve() could throw, so export now
11488    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11489    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11490    cmp     r0, #0                      @ success?
11491    bne     .LOP_SGET_CHAR_finish          @ yes, finish
11492    b       common_exceptionThrown      @ no, handle exception
11493
11494/* continuation for OP_SGET_SHORT */
11495
11496    /*
11497     * Continuation if the field has not yet been resolved.
11498     *  r1: BBBB field ref
11499     */
11500.LOP_SGET_SHORT_resolve:
11501    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11502    EXPORT_PC()                         @ resolve() could throw, so export now
11503    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11504    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11505    cmp     r0, #0                      @ success?
11506    bne     .LOP_SGET_SHORT_finish          @ yes, finish
11507    b       common_exceptionThrown      @ no, handle exception
11508
11509/* continuation for OP_SPUT */
11510
11511    /*
11512     * Continuation if the field has not yet been resolved.
11513     *  r1: BBBB field ref
11514     */
11515.LOP_SPUT_resolve:
11516    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11517    EXPORT_PC()                         @ resolve() could throw, so export now
11518    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11519    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11520    cmp     r0, #0                      @ success?
11521    bne     .LOP_SPUT_finish          @ yes, finish
11522    b       common_exceptionThrown      @ no, handle exception
11523
11524/* continuation for OP_SPUT_WIDE */
11525
11526    /*
11527     * Continuation if the field has not yet been resolved.
11528     *  r1: BBBB field ref
11529     *  r9: &fp[AA]
11530     *
11531     * Returns StaticField pointer in r2.
11532     */
11533.LOP_SPUT_WIDE_resolve:
11534    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11535    EXPORT_PC()                         @ resolve() could throw, so export now
11536    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11537    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11538    cmp     r0, #0                      @ success?
11539    mov     r2, r0                      @ copy to r2
11540    bne     .LOP_SPUT_WIDE_finish          @ yes, finish
11541    b       common_exceptionThrown      @ no, handle exception
11542
11543/* continuation for OP_SPUT_OBJECT */
11544.LOP_SPUT_OBJECT_finish:   @ field ptr in r0
11545    mov     r2, rINST, lsr #8           @ r2<- AA
11546    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11547    GET_VREG(r1, r2)                    @ r1<- fp[AA]
11548    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
11549    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
11550    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11551    @ no-op                             @ releasing store
11552    str     r1, [r0, #offStaticField_value]  @ field<- vAA
11553    cmp     r1, #0                      @ stored a null object?
11554    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
11555    GOTO_OPCODE(ip)                     @ jump to next instruction
11556
11557/* continuation for OP_SPUT_BOOLEAN */
11558
11559    /*
11560     * Continuation if the field has not yet been resolved.
11561     *  r1: BBBB field ref
11562     */
11563.LOP_SPUT_BOOLEAN_resolve:
11564    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11565    EXPORT_PC()                         @ resolve() could throw, so export now
11566    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11567    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11568    cmp     r0, #0                      @ success?
11569    bne     .LOP_SPUT_BOOLEAN_finish          @ yes, finish
11570    b       common_exceptionThrown      @ no, handle exception
11571
11572/* continuation for OP_SPUT_BYTE */
11573
11574    /*
11575     * Continuation if the field has not yet been resolved.
11576     *  r1: BBBB field ref
11577     */
11578.LOP_SPUT_BYTE_resolve:
11579    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11580    EXPORT_PC()                         @ resolve() could throw, so export now
11581    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11582    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11583    cmp     r0, #0                      @ success?
11584    bne     .LOP_SPUT_BYTE_finish          @ yes, finish
11585    b       common_exceptionThrown      @ no, handle exception
11586
11587/* continuation for OP_SPUT_CHAR */
11588
11589    /*
11590     * Continuation if the field has not yet been resolved.
11591     *  r1: BBBB field ref
11592     */
11593.LOP_SPUT_CHAR_resolve:
11594    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11595    EXPORT_PC()                         @ resolve() could throw, so export now
11596    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11597    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11598    cmp     r0, #0                      @ success?
11599    bne     .LOP_SPUT_CHAR_finish          @ yes, finish
11600    b       common_exceptionThrown      @ no, handle exception
11601
11602/* continuation for OP_SPUT_SHORT */
11603
11604    /*
11605     * Continuation if the field has not yet been resolved.
11606     *  r1: BBBB field ref
11607     */
11608.LOP_SPUT_SHORT_resolve:
11609    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11610    EXPORT_PC()                         @ resolve() could throw, so export now
11611    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11612    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11613    cmp     r0, #0                      @ success?
11614    bne     .LOP_SPUT_SHORT_finish          @ yes, finish
11615    b       common_exceptionThrown      @ no, handle exception
11616
11617/* continuation for OP_INVOKE_VIRTUAL */
11618
11619    /*
11620     * At this point:
11621     *  r0 = resolved base method
11622     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
11623     */
11624.LOP_INVOKE_VIRTUAL_continue:
11625    GET_VREG(r1, r10)                   @ r1<- "this" ptr
11626    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11627    cmp     r1, #0                      @ is "this" null?
11628    beq     common_errNullObject        @ null "this", throw exception
11629    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
11630    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
11631    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
11632    bl      common_invokeMethodNoRange @ continue on
11633
11634/* continuation for OP_INVOKE_SUPER */
11635
11636    /*
11637     * At this point:
11638     *  r0 = resolved base method
11639     *  r9 = method->clazz
11640     */
11641.LOP_INVOKE_SUPER_continue:
11642    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
11643    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11644    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
11645    EXPORT_PC()                         @ must export for invoke
11646    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
11647    bcs     .LOP_INVOKE_SUPER_nsm             @ method not present in superclass
11648    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
11649    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
11650    bl      common_invokeMethodNoRange @ continue on
11651
11652.LOP_INVOKE_SUPER_resolve:
11653    mov     r0, r9                      @ r0<- method->clazz
11654    mov     r2, #METHOD_VIRTUAL         @ resolver method type
11655    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11656    cmp     r0, #0                      @ got null?
11657    bne     .LOP_INVOKE_SUPER_continue        @ no, continue
11658    b       common_exceptionThrown      @ yes, handle exception
11659
11660    /*
11661     * Throw a NoSuchMethodError with the method name as the message.
11662     *  r0 = resolved base method
11663     */
11664.LOP_INVOKE_SUPER_nsm:
11665    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
11666    b       common_errNoSuchMethod
11667
11668/* continuation for OP_INVOKE_DIRECT */
11669
11670    /*
11671     * On entry:
11672     *  r1 = reference (BBBB or CCCC)
11673     *  r10 = "this" register
11674     */
11675.LOP_INVOKE_DIRECT_resolve:
11676    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
11677    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
11678    mov     r2, #METHOD_DIRECT          @ resolver method type
11679    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11680    cmp     r0, #0                      @ got null?
11681    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
11682    bne     .LOP_INVOKE_DIRECT_finish          @ no, continue
11683    b       common_exceptionThrown      @ yes, handle exception
11684
11685/* continuation for OP_INVOKE_VIRTUAL_RANGE */
11686
11687    /*
11688     * At this point:
11689     *  r0 = resolved base method
11690     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
11691     */
11692.LOP_INVOKE_VIRTUAL_RANGE_continue:
11693    GET_VREG(r1, r10)                   @ r1<- "this" ptr
11694    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11695    cmp     r1, #0                      @ is "this" null?
11696    beq     common_errNullObject        @ null "this", throw exception
11697    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
11698    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
11699    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
11700    bl      common_invokeMethodRange @ continue on
11701
11702/* continuation for OP_INVOKE_SUPER_RANGE */
11703
11704    /*
11705     * At this point:
11706     *  r0 = resolved base method
11707     *  r9 = method->clazz
11708     */
11709.LOP_INVOKE_SUPER_RANGE_continue:
11710    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
11711    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11712    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
11713    EXPORT_PC()                         @ must export for invoke
11714    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
11715    bcs     .LOP_INVOKE_SUPER_RANGE_nsm             @ method not present in superclass
11716    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
11717    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
11718    bl      common_invokeMethodRange @ continue on
11719
11720.LOP_INVOKE_SUPER_RANGE_resolve:
11721    mov     r0, r9                      @ r0<- method->clazz
11722    mov     r2, #METHOD_VIRTUAL         @ resolver method type
11723    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11724    cmp     r0, #0                      @ got null?
11725    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ no, continue
11726    b       common_exceptionThrown      @ yes, handle exception
11727
11728    /*
11729     * Throw a NoSuchMethodError with the method name as the message.
11730     *  r0 = resolved base method
11731     */
11732.LOP_INVOKE_SUPER_RANGE_nsm:
11733    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
11734    b       common_errNoSuchMethod
11735
11736/* continuation for OP_INVOKE_DIRECT_RANGE */
11737
11738    /*
11739     * On entry:
11740     *  r1 = reference (BBBB or CCCC)
11741     *  r10 = "this" register
11742     */
11743.LOP_INVOKE_DIRECT_RANGE_resolve:
11744    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
11745    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
11746    mov     r2, #METHOD_DIRECT          @ resolver method type
11747    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11748    cmp     r0, #0                      @ got null?
11749    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
11750    bne     .LOP_INVOKE_DIRECT_RANGE_finish          @ no, continue
11751    b       common_exceptionThrown      @ yes, handle exception
11752
11753/* continuation for OP_FLOAT_TO_LONG */
11754/*
11755 * Convert the float in r0 to a long in r0/r1.
11756 *
11757 * We have to clip values to long min/max per the specification.  The
11758 * expected common case is a "reasonable" value that converts directly
11759 * to modest integer.  The EABI convert function isn't doing this for us.
11760 */
11761f2l_doconv:
11762    stmfd   sp!, {r4, lr}
11763    mov     r1, #0x5f000000             @ (float)maxlong
11764    mov     r4, r0
11765    bl      __aeabi_fcmpge              @ is arg >= maxlong?
11766    cmp     r0, #0                      @ nonzero == yes
11767    mvnne   r0, #0                      @ return maxlong (7fffffff)
11768    mvnne   r1, #0x80000000
11769    ldmnefd sp!, {r4, pc}
11770
11771    mov     r0, r4                      @ recover arg
11772    mov     r1, #0xdf000000             @ (float)minlong
11773    bl      __aeabi_fcmple              @ is arg <= minlong?
11774    cmp     r0, #0                      @ nonzero == yes
11775    movne   r0, #0                      @ return minlong (80000000)
11776    movne   r1, #0x80000000
11777    ldmnefd sp!, {r4, pc}
11778
11779    mov     r0, r4                      @ recover arg
11780    mov     r1, r4
11781    bl      __aeabi_fcmpeq              @ is arg == self?
11782    cmp     r0, #0                      @ zero == no
11783    moveq   r1, #0                      @ return zero for NaN
11784    ldmeqfd sp!, {r4, pc}
11785
11786    mov     r0, r4                      @ recover arg
11787    bl      __aeabi_f2lz                @ convert float to long
11788    ldmfd   sp!, {r4, pc}
11789
11790/* continuation for OP_DOUBLE_TO_LONG */
11791/*
11792 * Convert the double in r0/r1 to a long in r0/r1.
11793 *
11794 * We have to clip values to long min/max per the specification.  The
11795 * expected common case is a "reasonable" value that converts directly
11796 * to modest integer.  The EABI convert function isn't doing this for us.
11797 */
11798d2l_doconv:
11799    stmfd   sp!, {r4, r5, lr}           @ save regs
11800    mov     r3, #0x43000000             @ maxlong, as a double (high word)
11801    add     r3, #0x00e00000             @  0x43e00000
11802    mov     r2, #0                      @ maxlong, as a double (low word)
11803    sub     sp, sp, #4                  @ align for EABI
11804    mov     r4, r0                      @ save a copy of r0
11805    mov     r5, r1                      @  and r1
11806    bl      __aeabi_dcmpge              @ is arg >= maxlong?
11807    cmp     r0, #0                      @ nonzero == yes
11808    mvnne   r0, #0                      @ return maxlong (7fffffffffffffff)
11809    mvnne   r1, #0x80000000
11810    bne     1f
11811
11812    mov     r0, r4                      @ recover arg
11813    mov     r1, r5
11814    mov     r3, #0xc3000000             @ minlong, as a double (high word)
11815    add     r3, #0x00e00000             @  0xc3e00000
11816    mov     r2, #0                      @ minlong, as a double (low word)
11817    bl      __aeabi_dcmple              @ is arg <= minlong?
11818    cmp     r0, #0                      @ nonzero == yes
11819    movne   r0, #0                      @ return minlong (8000000000000000)
11820    movne   r1, #0x80000000
11821    bne     1f
11822
11823    mov     r0, r4                      @ recover arg
11824    mov     r1, r5
11825    mov     r2, r4                      @ compare against self
11826    mov     r3, r5
11827    bl      __aeabi_dcmpeq              @ is arg == self?
11828    cmp     r0, #0                      @ zero == no
11829    moveq   r1, #0                      @ return zero for NaN
11830    beq     1f
11831
11832    mov     r0, r4                      @ recover arg
11833    mov     r1, r5
11834    bl      __aeabi_d2lz                @ convert double to long
11835
118361:
11837    add     sp, sp, #4
11838    ldmfd   sp!, {r4, r5, pc}
11839
11840/* continuation for OP_MUL_LONG */
11841
11842.LOP_MUL_LONG_finish:
11843    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11844    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
11845    GOTO_OPCODE(ip)                     @ jump to next instruction
11846
11847/* continuation for OP_SHL_LONG */
11848
11849.LOP_SHL_LONG_finish:
11850    mov     r0, r0, asl r2              @  r0<- r0 << r2
11851    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11852    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11853    GOTO_OPCODE(ip)                     @ jump to next instruction
11854
11855/* continuation for OP_SHR_LONG */
11856
11857.LOP_SHR_LONG_finish:
11858    mov     r1, r1, asr r2              @  r1<- r1 >> r2
11859    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11860    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11861    GOTO_OPCODE(ip)                     @ jump to next instruction
11862
11863/* continuation for OP_USHR_LONG */
11864
11865.LOP_USHR_LONG_finish:
11866    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
11867    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11868    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11869    GOTO_OPCODE(ip)                     @ jump to next instruction
11870
11871/* continuation for OP_SHL_LONG_2ADDR */
11872
11873.LOP_SHL_LONG_2ADDR_finish:
11874    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11875    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11876    GOTO_OPCODE(ip)                     @ jump to next instruction
11877
11878/* continuation for OP_SHR_LONG_2ADDR */
11879
11880.LOP_SHR_LONG_2ADDR_finish:
11881    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11882    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11883    GOTO_OPCODE(ip)                     @ jump to next instruction
11884
11885/* continuation for OP_USHR_LONG_2ADDR */
11886
11887.LOP_USHR_LONG_2ADDR_finish:
11888    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11889    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11890    GOTO_OPCODE(ip)                     @ jump to next instruction
11891
11892/* continuation for OP_IGET_VOLATILE */
11893
11894    /*
11895     * Currently:
11896     *  r0 holds resolved field
11897     *  r9 holds object
11898     */
11899.LOP_IGET_VOLATILE_finish:
11900    @bl      common_squeak0
11901    cmp     r9, #0                      @ check object for null
11902    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11903    beq     common_errNullObject        @ object was null
11904    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11905    SMP_DMB                            @ acquiring load
11906    mov     r2, rINST, lsr #8           @ r2<- A+
11907    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11908    and     r2, r2, #15                 @ r2<- A
11909    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11910    SET_VREG(r0, r2)                    @ fp[A]<- r0
11911    GOTO_OPCODE(ip)                     @ jump to next instruction
11912
11913/* continuation for OP_IPUT_VOLATILE */
11914
11915    /*
11916     * Currently:
11917     *  r0 holds resolved field
11918     *  r9 holds object
11919     */
11920.LOP_IPUT_VOLATILE_finish:
11921    @bl      common_squeak0
11922    mov     r1, rINST, lsr #8           @ r1<- A+
11923    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11924    and     r1, r1, #15                 @ r1<- A
11925    cmp     r9, #0                      @ check object for null
11926    GET_VREG(r0, r1)                    @ r0<- fp[A]
11927    beq     common_errNullObject        @ object was null
11928    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11929    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11930    SMP_DMB                            @ releasing store
11931    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11932    GOTO_OPCODE(ip)                     @ jump to next instruction
11933
11934/* continuation for OP_SGET_VOLATILE */
11935
11936    /*
11937     * Continuation if the field has not yet been resolved.
11938     *  r1: BBBB field ref
11939     */
11940.LOP_SGET_VOLATILE_resolve:
11941    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11942    EXPORT_PC()                         @ resolve() could throw, so export now
11943    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11944    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11945    cmp     r0, #0                      @ success?
11946    bne     .LOP_SGET_VOLATILE_finish          @ yes, finish
11947    b       common_exceptionThrown      @ no, handle exception
11948
11949/* continuation for OP_SPUT_VOLATILE */
11950
11951    /*
11952     * Continuation if the field has not yet been resolved.
11953     *  r1: BBBB field ref
11954     */
11955.LOP_SPUT_VOLATILE_resolve:
11956    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11957    EXPORT_PC()                         @ resolve() could throw, so export now
11958    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11959    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11960    cmp     r0, #0                      @ success?
11961    bne     .LOP_SPUT_VOLATILE_finish          @ yes, finish
11962    b       common_exceptionThrown      @ no, handle exception
11963
11964/* continuation for OP_IGET_OBJECT_VOLATILE */
11965
11966    /*
11967     * Currently:
11968     *  r0 holds resolved field
11969     *  r9 holds object
11970     */
11971.LOP_IGET_OBJECT_VOLATILE_finish:
11972    @bl      common_squeak0
11973    cmp     r9, #0                      @ check object for null
11974    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11975    beq     common_errNullObject        @ object was null
11976    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11977    SMP_DMB                            @ acquiring load
11978    mov     r2, rINST, lsr #8           @ r2<- A+
11979    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11980    and     r2, r2, #15                 @ r2<- A
11981    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11982    SET_VREG(r0, r2)                    @ fp[A]<- r0
11983    GOTO_OPCODE(ip)                     @ jump to next instruction
11984
11985/* continuation for OP_IGET_WIDE_VOLATILE */
11986
11987    /*
11988     * Currently:
11989     *  r0 holds resolved field
11990     *  r9 holds object
11991     */
11992.LOP_IGET_WIDE_VOLATILE_finish:
11993    cmp     r9, #0                      @ check object for null
11994    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11995    beq     common_errNullObject        @ object was null
11996    .if     1
11997    add     r0, r9, r3                  @ r0<- address of field
11998    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
11999    .else
12000    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
12001    .endif
12002    mov     r2, rINST, lsr #8           @ r2<- A+
12003    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12004    and     r2, r2, #15                 @ r2<- A
12005    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
12006    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12007    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
12008    GOTO_OPCODE(ip)                     @ jump to next instruction
12009
12010/* continuation for OP_IPUT_WIDE_VOLATILE */
12011
12012    /*
12013     * Currently:
12014     *  r0 holds resolved field
12015     *  r9 holds object
12016     */
12017.LOP_IPUT_WIDE_VOLATILE_finish:
12018    mov     r2, rINST, lsr #8           @ r2<- A+
12019    cmp     r9, #0                      @ check object for null
12020    and     r2, r2, #15                 @ r2<- A
12021    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12022    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
12023    beq     common_errNullObject        @ object was null
12024    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12025    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
12026    GET_INST_OPCODE(r10)                @ extract opcode from rINST
12027    .if     1
12028    add     r2, r9, r3                  @ r2<- target address
12029    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
12030    .else
12031    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
12032    .endif
12033    GOTO_OPCODE(r10)                    @ jump to next instruction
12034
12035/* continuation for OP_SGET_WIDE_VOLATILE */
12036
12037    /*
12038     * Continuation if the field has not yet been resolved.
12039     *  r1: BBBB field ref
12040     *
12041     * Returns StaticField pointer in r0.
12042     */
12043.LOP_SGET_WIDE_VOLATILE_resolve:
12044    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12045    EXPORT_PC()                         @ resolve() could throw, so export now
12046    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12047    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12048    cmp     r0, #0                      @ success?
12049    bne     .LOP_SGET_WIDE_VOLATILE_finish          @ yes, finish
12050    b       common_exceptionThrown      @ no, handle exception
12051
12052/* continuation for OP_SPUT_WIDE_VOLATILE */
12053
12054    /*
12055     * Continuation if the field has not yet been resolved.
12056     *  r1: BBBB field ref
12057     *  r9: &fp[AA]
12058     *
12059     * Returns StaticField pointer in r2.
12060     */
12061.LOP_SPUT_WIDE_VOLATILE_resolve:
12062    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12063    EXPORT_PC()                         @ resolve() could throw, so export now
12064    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12065    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12066    cmp     r0, #0                      @ success?
12067    mov     r2, r0                      @ copy to r2
12068    bne     .LOP_SPUT_WIDE_VOLATILE_finish          @ yes, finish
12069    b       common_exceptionThrown      @ no, handle exception
12070
12071/* continuation for OP_EXECUTE_INLINE */
12072
12073    /*
12074     * Extract args, call function.
12075     *  r0 = #of args (0-4)
12076     *  r10 = call index
12077     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
12078     *
12079     * Other ideas:
12080     * - Use a jump table from the main piece to jump directly into the
12081     *   AND/LDR pairs.  Costs a data load, saves a branch.
12082     * - Have five separate pieces that do the loading, so we can work the
12083     *   interleave a little better.  Increases code size.
12084     */
12085.LOP_EXECUTE_INLINE_continue:
12086    rsb     r0, r0, #4                  @ r0<- 4-r0
12087    FETCH(r9, 2)                        @ r9<- FEDC
12088    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
12089    bl      common_abort                @ (skipped due to ARM prefetch)
120904:  and     ip, r9, #0xf000             @ isolate F
12091    ldr     r3, [rFP, ip, lsr #10]      @ r3<- vF (shift right 12, left 2)
120923:  and     ip, r9, #0x0f00             @ isolate E
12093    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vE
120942:  and     ip, r9, #0x00f0             @ isolate D
12095    ldr     r1, [rFP, ip, lsr #2]       @ r1<- vD
120961:  and     ip, r9, #0x000f             @ isolate C
12097    ldr     r0, [rFP, ip, lsl #2]       @ r0<- vC
120980:
12099    ldr     r9, .LOP_EXECUTE_INLINE_table       @ table of InlineOperation
12100    ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
12101    @ (not reached)
12102
12103.LOP_EXECUTE_INLINE_table:
12104    .word   gDvmInlineOpsTable
12105
12106/* continuation for OP_EXECUTE_INLINE_RANGE */
12107
12108    /*
12109     * Extract args, call function.
12110     *  r0 = #of args (0-4)
12111     *  r10 = call index
12112     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
12113     */
12114.LOP_EXECUTE_INLINE_RANGE_continue:
12115    rsb     r0, r0, #4                  @ r0<- 4-r0
12116    FETCH(r9, 2)                        @ r9<- CCCC
12117    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
12118    bl      common_abort                @ (skipped due to ARM prefetch)
121194:  add     ip, r9, #3                  @ base+3
12120    GET_VREG(r3, ip)                    @ r3<- vBase[3]
121213:  add     ip, r9, #2                  @ base+2
12122    GET_VREG(r2, ip)                    @ r2<- vBase[2]
121232:  add     ip, r9, #1                  @ base+1
12124    GET_VREG(r1, ip)                    @ r1<- vBase[1]
121251:  add     ip, r9, #0                  @ (nop)
12126    GET_VREG(r0, ip)                    @ r0<- vBase[0]
121270:
12128    ldr     r9, .LOP_EXECUTE_INLINE_RANGE_table       @ table of InlineOperation
12129    ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
12130    @ (not reached)
12131
12132.LOP_EXECUTE_INLINE_RANGE_table:
12133    .word   gDvmInlineOpsTable
12134
12135/* continuation for OP_IPUT_OBJECT_VOLATILE */
12136
12137    /*
12138     * Currently:
12139     *  r0 holds resolved field
12140     *  r9 holds object
12141     */
12142.LOP_IPUT_OBJECT_VOLATILE_finish:
12143    @bl      common_squeak0
12144    mov     r1, rINST, lsr #8           @ r1<- A+
12145    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12146    and     r1, r1, #15                 @ r1<- A
12147    cmp     r9, #0                      @ check object for null
12148    GET_VREG(r0, r1)                    @ r0<- fp[A]
12149    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12150    beq     common_errNullObject        @ object was null
12151    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12152    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12153    SMP_DMB                            @ releasing store
12154    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
12155    cmp     r0, #0                      @ stored a null reference?
12156    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
12157    GOTO_OPCODE(ip)                     @ jump to next instruction
12158
12159/* continuation for OP_SGET_OBJECT_VOLATILE */
12160
12161    /*
12162     * Continuation if the field has not yet been resolved.
12163     *  r1: BBBB field ref
12164     */
12165.LOP_SGET_OBJECT_VOLATILE_resolve:
12166    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12167    EXPORT_PC()                         @ resolve() could throw, so export now
12168    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12169    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12170    cmp     r0, #0                      @ success?
12171    bne     .LOP_SGET_OBJECT_VOLATILE_finish          @ yes, finish
12172    b       common_exceptionThrown      @ no, handle exception
12173
12174/* continuation for OP_SPUT_OBJECT_VOLATILE */
12175.LOP_SPUT_OBJECT_VOLATILE_finish:   @ field ptr in r0
12176    mov     r2, rINST, lsr #8           @ r2<- AA
12177    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12178    GET_VREG(r1, r2)                    @ r1<- fp[AA]
12179    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12180    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
12181    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12182    SMP_DMB                            @ releasing store
12183    str     r1, [r0, #offStaticField_value]  @ field<- vAA
12184    cmp     r1, #0                      @ stored a null object?
12185    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
12186    GOTO_OPCODE(ip)                     @ jump to next instruction
12187
12188/* continuation for OP_CONST_CLASS_JUMBO */
12189
12190    /*
12191     * Continuation if the Class has not yet been resolved.
12192     *  r1: AAAAAAAA (Class ref)
12193     *  r9: target register
12194     */
12195.LOP_CONST_CLASS_JUMBO_resolve:
12196    EXPORT_PC()
12197    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
12198    mov     r2, #1                      @ r2<- true
12199    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
12200    bl      dvmResolveClass             @ r0<- Class reference
12201    cmp     r0, #0                      @ failed?
12202    beq     common_exceptionThrown      @ yup, handle the exception
12203    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12204    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12205    SET_VREG(r0, r9)                    @ vBBBB<- r0
12206    GOTO_OPCODE(ip)                     @ jump to next instruction
12207
12208/* continuation for OP_CHECK_CAST_JUMBO */
12209
12210    /*
12211     * Trivial test failed, need to perform full check.  This is common.
12212     *  r0 holds obj->clazz
12213     *  r1 holds desired class resolved from AAAAAAAA
12214     *  r9 holds object
12215     */
12216.LOP_CHECK_CAST_JUMBO_fullcheck:
12217    mov     r10, r1                     @ avoid ClassObject getting clobbered
12218    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
12219    cmp     r0, #0                      @ failed?
12220    bne     .LOP_CHECK_CAST_JUMBO_okay            @ no, success
12221
12222    @ A cast has failed.  We need to throw a ClassCastException.
12223    EXPORT_PC()                         @ about to throw
12224    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
12225    mov     r1, r10                     @ r1<- desired class
12226    bl      dvmThrowClassCastException
12227    b       common_exceptionThrown
12228
12229    /*
12230     * Advance PC and get the next opcode.
12231     */
12232.LOP_CHECK_CAST_JUMBO_okay:
12233    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12234    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12235    GOTO_OPCODE(ip)                     @ jump to next instruction
12236
12237    /*
12238     * Resolution required.  This is the least-likely path.
12239     *
12240     *  r2 holds AAAAAAAA
12241     *  r9 holds object
12242     */
12243.LOP_CHECK_CAST_JUMBO_resolve:
12244    EXPORT_PC()                         @ resolve() could throw
12245    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
12246    mov     r1, r2                      @ r1<- AAAAAAAA
12247    mov     r2, #0                      @ r2<- false
12248    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12249    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12250    cmp     r0, #0                      @ got null?
12251    beq     common_exceptionThrown      @ yes, handle exception
12252    mov     r1, r0                      @ r1<- class resolved from AAAAAAAA
12253    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
12254    b       .LOP_CHECK_CAST_JUMBO_resolved        @ pick up where we left off
12255
12256/* continuation for OP_INSTANCE_OF_JUMBO */
12257
12258    /*
12259     * Class resolved, determine type of check necessary.  This is common.
12260     *  r0 holds obj->clazz
12261     *  r1 holds class resolved from AAAAAAAA
12262     *  r9 holds BBBB
12263     */
12264.LOP_INSTANCE_OF_JUMBO_resolved:
12265    cmp     r0, r1                      @ same class (trivial success)?
12266    beq     .LOP_INSTANCE_OF_JUMBO_trivial         @ yes, trivial finish
12267    @ fall through to OP_INSTANCE_OF_JUMBO_fullcheck
12268
12269    /*
12270     * Trivial test failed, need to perform full check.  This is common.
12271     *  r0 holds obj->clazz
12272     *  r1 holds class resolved from AAAAAAAA
12273     *  r9 holds BBBB
12274     */
12275.LOP_INSTANCE_OF_JUMBO_fullcheck:
12276    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
12277    @ fall through to OP_INSTANCE_OF_JUMBO_store
12278
12279    /*
12280     * r0 holds boolean result
12281     * r9 holds BBBB
12282     */
12283.LOP_INSTANCE_OF_JUMBO_store:
12284    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12285    SET_VREG(r0, r9)                    @ vBBBB<- r0
12286    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12287    GOTO_OPCODE(ip)                     @ jump to next instruction
12288
12289    /*
12290     * Trivial test succeeded, save and bail.
12291     *  r9 holds BBBB
12292     */
12293.LOP_INSTANCE_OF_JUMBO_trivial:
12294    mov     r0, #1                      @ indicate success
12295    @ could b OP_INSTANCE_OF_JUMBO_store, but copying is faster and cheaper
12296    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12297    SET_VREG(r0, r9)                    @ vBBBB<- r0
12298    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12299    GOTO_OPCODE(ip)                     @ jump to next instruction
12300
12301    /*
12302     * Resolution required.  This is the least-likely path.
12303     *
12304     *  r3 holds AAAAAAAA
12305     *  r9 holds BBBB
12306     */
12307
12308.LOP_INSTANCE_OF_JUMBO_resolve:
12309    EXPORT_PC()                         @ resolve() could throw
12310    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
12311    mov     r1, r3                      @ r1<- AAAAAAAA
12312    mov     r2, #1                      @ r2<- true
12313    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
12314    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12315    cmp     r0, #0                      @ got null?
12316    beq     common_exceptionThrown      @ yes, handle exception
12317    FETCH(r3, 4)                        @ r3<- vCCCC
12318    mov     r1, r0                      @ r1<- class resolved from AAAAAAAA
12319    GET_VREG(r0, r3)                    @ r0<- vCCCC (object)
12320    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
12321    b       .LOP_INSTANCE_OF_JUMBO_resolved        @ pick up where we left off
12322
12323/* continuation for OP_NEW_INSTANCE_JUMBO */
12324
12325    .balign 32                          @ minimize cache lines
12326.LOP_NEW_INSTANCE_JUMBO_finish: @ r0=new object
12327    FETCH(r3, 3)                        @ r3<- BBBB
12328    cmp     r0, #0                      @ failed?
12329    beq     common_exceptionThrown      @ yes, handle the exception
12330    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12331    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12332    SET_VREG(r0, r3)                    @ vBBBB<- r0
12333    GOTO_OPCODE(ip)                     @ jump to next instruction
12334
12335    /*
12336     * Class initialization required.
12337     *
12338     *  r0 holds class object
12339     */
12340.LOP_NEW_INSTANCE_JUMBO_needinit:
12341    mov     r9, r0                      @ save r0
12342    bl      dvmInitClass                @ initialize class
12343    cmp     r0, #0                      @ check boolean result
12344    mov     r0, r9                      @ restore r0
12345    bne     .LOP_NEW_INSTANCE_JUMBO_initialized     @ success, continue
12346    b       common_exceptionThrown      @ failed, deal with init exception
12347
12348    /*
12349     * Resolution required.  This is the least-likely path.
12350     *
12351     *  r1 holds AAAAAAAA
12352     */
12353.LOP_NEW_INSTANCE_JUMBO_resolve:
12354    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
12355    mov     r2, #0                      @ r2<- false
12356    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12357    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12358    cmp     r0, #0                      @ got null?
12359    bne     .LOP_NEW_INSTANCE_JUMBO_resolved        @ no, continue
12360    b       common_exceptionThrown      @ yes, handle exception
12361
12362/* continuation for OP_NEW_ARRAY_JUMBO */
12363
12364
12365    /*
12366     * Resolve class.  (This is an uncommon case.)
12367     *
12368     *  r1 holds array length
12369     *  r2 holds class ref AAAAAAAA
12370     */
12371.LOP_NEW_ARRAY_JUMBO_resolve:
12372    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
12373    mov     r9, r1                      @ r9<- length (save)
12374    mov     r1, r2                      @ r1<- AAAAAAAA
12375    mov     r2, #0                      @ r2<- false
12376    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12377    bl      dvmResolveClass             @ r0<- call(clazz, ref)
12378    cmp     r0, #0                      @ got null?
12379    mov     r1, r9                      @ r1<- length (restore)
12380    beq     common_exceptionThrown      @ yes, handle exception
12381    @ fall through to OP_NEW_ARRAY_JUMBO_finish
12382
12383    /*
12384     * Finish allocation.
12385     *
12386     *  r0 holds class
12387     *  r1 holds array length
12388     */
12389.LOP_NEW_ARRAY_JUMBO_finish:
12390    mov     r2, #ALLOC_DONT_TRACK       @ don't track in local refs table
12391    bl      dvmAllocArrayByClass        @ r0<- call(clazz, length, flags)
12392    cmp     r0, #0                      @ failed?
12393    FETCH(r2, 3)                        @ r2<- vBBBB
12394    beq     common_exceptionThrown      @ yes, handle the exception
12395    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12396    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12397    SET_VREG(r0, r2)                    @ vBBBB<- r0
12398    GOTO_OPCODE(ip)                     @ jump to next instruction
12399
12400/* continuation for OP_FILLED_NEW_ARRAY_JUMBO */
12401
12402    /*
12403     * On entry:
12404     *  r0 holds array class
12405     */
12406.LOP_FILLED_NEW_ARRAY_JUMBO_continue:
12407    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
12408    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
12409    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
12410    FETCH(r1, 3)                        @ r1<- BBBB (length)
12411    cmp     rINST, #'I'                 @ array of ints?
12412    cmpne   rINST, #'L'                 @ array of objects?
12413    cmpne   rINST, #'['                 @ array of arrays?
12414    mov     r9, r1                      @ save length in r9
12415    bne     .LOP_FILLED_NEW_ARRAY_JUMBO_notimpl         @ no, not handled yet
12416    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
12417    cmp     r0, #0                      @ null return?
12418    beq     common_exceptionThrown      @ alloc failed, handle exception
12419
12420    FETCH(r1, 4)                        @ r1<- CCCC
12421    str     r0, [rGLUE, #offGlue_retval]      @ retval.l <- new array
12422    str     rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type
12423    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
12424    subs    r9, r9, #1                  @ length--, check for neg
12425    FETCH_ADVANCE_INST(5)               @ advance to next instr, load rINST
12426    bmi     2f                          @ was zero, bail
12427
12428    @ copy values from registers into the array
12429    @ r0=array, r1=CCCC, r9=BBBB (length)
12430    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
124311:  ldr     r3, [r2], #4                @ r3<- *r2++
12432    subs    r9, r9, #1                  @ count--
12433    str     r3, [r0], #4                @ *contents++ = vX
12434    bpl     1b
12435
124362:  ldr     r0, [rGLUE, #offGlue_retval]     @ r0<- object
12437    ldr     r1, [rGLUE, #offGlue_retval+4]   @ r1<- type
12438    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12439    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
12440    cmp     r1, #'I'                         @ Is int array?
12441    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
12442    GOTO_OPCODE(ip)                          @ execute it
12443
12444    /*
12445     * Throw an exception indicating that we have not implemented this
12446     * mode of filled-new-array.
12447     */
12448.LOP_FILLED_NEW_ARRAY_JUMBO_notimpl:
12449    ldr     r0, .L_strInternalError
12450    ldr     r1, .L_strFilledNewArrayNotImpl
12451    bl      dvmThrowException
12452    b       common_exceptionThrown
12453
12454/* continuation for OP_IGET_JUMBO */
12455
12456    /*
12457     * Currently:
12458     *  r0 holds resolved field
12459     *  r9 holds object
12460     */
12461.LOP_IGET_JUMBO_resolved:
12462    cmp     r0, #0                      @ resolution unsuccessful?
12463    beq     common_exceptionThrown      @ yes, throw exception
12464    @ fall through to OP_IGET_JUMBO_finish
12465
12466    /*
12467     * Currently:
12468     *  r0 holds resolved field
12469     *  r9 holds object
12470     */
12471.LOP_IGET_JUMBO_finish:
12472    @bl      common_squeak0
12473    cmp     r9, #0                      @ check object for null
12474    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12475    beq     common_errNullObject        @ object was null
12476    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12477    @ no-op                             @ acquiring load
12478    FETCH(r2, 3)                        @ r2<- BBBB
12479    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12480    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12481    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12482    GOTO_OPCODE(ip)                     @ jump to next instruction
12483
12484/* continuation for OP_IGET_WIDE_JUMBO */
12485
12486    /*
12487     * Currently:
12488     *  r0 holds resolved field
12489     *  r9 holds object
12490     */
12491.LOP_IGET_WIDE_JUMBO_resolved:
12492    cmp     r0, #0                      @ resolution unsuccessful?
12493    beq     common_exceptionThrown      @ yes, throw exception
12494    @ fall through to OP_IGET_WIDE_JUMBO_finish
12495
12496    /*
12497     * Currently:
12498     *  r0 holds resolved field
12499     *  r9 holds object
12500     */
12501.LOP_IGET_WIDE_JUMBO_finish:
12502    cmp     r9, #0                      @ check object for null
12503    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12504    beq     common_errNullObject        @ object was null
12505    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
12506    FETCH(r2, 3)                        @ r2<- BBBB
12507    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12508    add     r3, rFP, r2, lsl #2         @ r3<- &fp[BBBB]
12509    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12510    stmia   r3, {r0-r1}                 @ fp[BBBB]<- r0/r1
12511    GOTO_OPCODE(ip)                     @ jump to next instruction
12512
12513/* continuation for OP_IGET_OBJECT_JUMBO */
12514
12515    /*
12516     * Currently:
12517     *  r0 holds resolved field
12518     *  r9 holds object
12519     */
12520.LOP_IGET_OBJECT_JUMBO_resolved:
12521    cmp     r0, #0                      @ resolution unsuccessful?
12522    beq     common_exceptionThrown      @ yes, throw exception
12523    @ fall through to OP_IGET_OBJECT_JUMBO_finish
12524
12525    /*
12526     * Currently:
12527     *  r0 holds resolved field
12528     *  r9 holds object
12529     */
12530.LOP_IGET_OBJECT_JUMBO_finish:
12531    @bl      common_squeak0
12532    cmp     r9, #0                      @ check object for null
12533    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12534    beq     common_errNullObject        @ object was null
12535    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12536    @ no-op                             @ acquiring load
12537    FETCH(r2, 3)                        @ r2<- BBBB
12538    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12539    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12540    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12541    GOTO_OPCODE(ip)                     @ jump to next instruction
12542
12543/* continuation for OP_IGET_BOOLEAN_JUMBO */
12544
12545    /*
12546     * Currently:
12547     *  r0 holds resolved field
12548     *  r9 holds object
12549     */
12550.LOP_IGET_BOOLEAN_JUMBO_resolved:
12551    cmp     r0, #0                      @ resolution unsuccessful?
12552    beq     common_exceptionThrown      @ yes, throw exception
12553    @ fall through to OP_IGET_BOOLEAN_JUMBO_finish
12554
12555    /*
12556     * Currently:
12557     *  r0 holds resolved field
12558     *  r9 holds object
12559     */
12560.LOP_IGET_BOOLEAN_JUMBO_finish:
12561    @bl      common_squeak1
12562    cmp     r9, #0                      @ check object for null
12563    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12564    beq     common_errNullObject        @ object was null
12565    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12566    @ no-op                             @ acquiring load
12567    FETCH(r2, 3)                        @ r2<- BBBB
12568    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12569    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12570    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12571    GOTO_OPCODE(ip)                     @ jump to next instruction
12572
12573/* continuation for OP_IGET_BYTE_JUMBO */
12574
12575    /*
12576     * Currently:
12577     *  r0 holds resolved field
12578     *  r9 holds object
12579     */
12580.LOP_IGET_BYTE_JUMBO_resolved:
12581    cmp     r0, #0                      @ resolution unsuccessful?
12582    beq     common_exceptionThrown      @ yes, throw exception
12583    @ fall through to OP_IGET_BYTE_JUMBO_finish
12584
12585    /*
12586     * Currently:
12587     *  r0 holds resolved field
12588     *  r9 holds object
12589     */
12590.LOP_IGET_BYTE_JUMBO_finish:
12591    @bl      common_squeak2
12592    cmp     r9, #0                      @ check object for null
12593    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12594    beq     common_errNullObject        @ object was null
12595    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12596    @ no-op                             @ acquiring load
12597    FETCH(r2, 3)                        @ r2<- BBBB
12598    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12599    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12600    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12601    GOTO_OPCODE(ip)                     @ jump to next instruction
12602
12603/* continuation for OP_IGET_CHAR_JUMBO */
12604
12605    /*
12606     * Currently:
12607     *  r0 holds resolved field
12608     *  r9 holds object
12609     */
12610.LOP_IGET_CHAR_JUMBO_resolved:
12611    cmp     r0, #0                      @ resolution unsuccessful?
12612    beq     common_exceptionThrown      @ yes, throw exception
12613    @ fall through to OP_IGET_CHAR_JUMBO_finish
12614
12615    /*
12616     * Currently:
12617     *  r0 holds resolved field
12618     *  r9 holds object
12619     */
12620.LOP_IGET_CHAR_JUMBO_finish:
12621    @bl      common_squeak3
12622    cmp     r9, #0                      @ check object for null
12623    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12624    beq     common_errNullObject        @ object was null
12625    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12626    @ no-op                             @ acquiring load
12627    FETCH(r2, 3)                        @ r2<- BBBB
12628    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12629    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12630    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12631    GOTO_OPCODE(ip)                     @ jump to next instruction
12632
12633/* continuation for OP_IGET_SHORT_JUMBO */
12634
12635    /*
12636     * Currently:
12637     *  r0 holds resolved field
12638     *  r9 holds object
12639     */
12640.LOP_IGET_SHORT_JUMBO_resolved:
12641    cmp     r0, #0                      @ resolution unsuccessful?
12642    beq     common_exceptionThrown      @ yes, throw exception
12643    @ fall through to OP_IGET_SHORT_JUMBO_finish
12644
12645    /*
12646     * Currently:
12647     *  r0 holds resolved field
12648     *  r9 holds object
12649     */
12650.LOP_IGET_SHORT_JUMBO_finish:
12651    @bl      common_squeak4
12652    cmp     r9, #0                      @ check object for null
12653    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12654    beq     common_errNullObject        @ object was null
12655    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12656    @ no-op                             @ acquiring load
12657    FETCH(r2, 3)                        @ r2<- BBBB
12658    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12659    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12660    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12661    GOTO_OPCODE(ip)                     @ jump to next instruction
12662
12663/* continuation for OP_IPUT_JUMBO */
12664
12665    /*
12666     * Currently:
12667     *  r0 holds resolved field
12668     *  r9 holds object
12669     */
12670.LOP_IPUT_JUMBO_resolved:
12671     cmp     r0, #0                     @ resolution unsuccessful?
12672     beq     common_exceptionThrown     @ yes, throw exception
12673     @ fall through to OP_IPUT_JUMBO_finish
12674
12675    /*
12676     * Currently:
12677     *  r0 holds resolved field
12678     *  r9 holds object
12679     */
12680.LOP_IPUT_JUMBO_finish:
12681    @bl      common_squeak0
12682    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12683    FETCH(r1, 3)                        @ r1<- BBBB
12684    cmp     r9, #0                      @ check object for null
12685    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12686    beq     common_errNullObject        @ object was null
12687    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12688    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12689    @ no-op                             @ releasing store
12690    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12691    GOTO_OPCODE(ip)                     @ jump to next instruction
12692
12693/* continuation for OP_IPUT_WIDE_JUMBO */
12694
12695    /*
12696     * Currently:
12697     *  r0 holds resolved field
12698     *  r9 holds object
12699     */
12700.LOP_IPUT_WIDE_JUMBO_resolved:
12701     cmp     r0, #0                     @ resolution unsuccessful?
12702     beq     common_exceptionThrown     @ yes, throw exception
12703     @ fall through to OP_IPUT_WIDE_JUMBO_finish
12704
12705    /*
12706     * Currently:
12707     *  r0 holds resolved field
12708     *  r9 holds object
12709     */
12710.LOP_IPUT_WIDE_JUMBO_finish:
12711    cmp     r9, #0                      @ check object for null
12712    FETCH(r2, 3)                        @ r1<- BBBB
12713    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12714    add     r2, rFP, r2, lsl #2         @ r3<- &fp[BBBB]
12715    beq     common_errNullObject        @ object was null
12716    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12717    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[BBBB]
12718    GET_INST_OPCODE(r10)                @ extract opcode from rINST
12719    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
12720    GOTO_OPCODE(r10)                    @ jump to next instruction
12721
12722/* continuation for OP_IPUT_OBJECT_JUMBO */
12723
12724    /*
12725     * Currently:
12726     *  r0 holds resolved field
12727     *  r9 holds object
12728     */
12729.LOP_IPUT_OBJECT_JUMBO_resolved:
12730     cmp     r0, #0                     @ resolution unsuccessful?
12731     beq     common_exceptionThrown     @ yes, throw exception
12732     @ fall through to OP_IPUT_OBJECT_JUMBO_finish
12733
12734    /*
12735     * Currently:
12736     *  r0 holds resolved field
12737     *  r9 holds object
12738     */
12739.LOP_IPUT_OBJECT_JUMBO_finish:
12740    @bl      common_squeak0
12741    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12742    FETCH(r1, 3)                        @ r1<- BBBB
12743    cmp     r9, #0                      @ check object for null
12744    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12745    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12746    beq     common_errNullObject        @ object was null
12747    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12748    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12749    @ no-op                             @ releasing store
12750    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
12751    cmp     r0, #0                      @ stored a null reference?
12752    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
12753    GOTO_OPCODE(ip)                     @ jump to next instruction
12754
12755/* continuation for OP_IPUT_BOOLEAN_JUMBO */
12756
12757    /*
12758     * Currently:
12759     *  r0 holds resolved field
12760     *  r9 holds object
12761     */
12762.LOP_IPUT_BOOLEAN_JUMBO_resolved:
12763     cmp     r0, #0                     @ resolution unsuccessful?
12764     beq     common_exceptionThrown     @ yes, throw exception
12765     @ fall through to OP_IPUT_BOOLEAN_JUMBO_finish
12766
12767    /*
12768     * Currently:
12769     *  r0 holds resolved field
12770     *  r9 holds object
12771     */
12772.LOP_IPUT_BOOLEAN_JUMBO_finish:
12773    @bl      common_squeak1
12774    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12775    FETCH(r1, 3)                        @ r1<- BBBB
12776    cmp     r9, #0                      @ check object for null
12777    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12778    beq     common_errNullObject        @ object was null
12779    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12780    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12781    @ no-op                             @ releasing store
12782    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12783    GOTO_OPCODE(ip)                     @ jump to next instruction
12784
12785/* continuation for OP_IPUT_BYTE_JUMBO */
12786
12787    /*
12788     * Currently:
12789     *  r0 holds resolved field
12790     *  r9 holds object
12791     */
12792.LOP_IPUT_BYTE_JUMBO_resolved:
12793     cmp     r0, #0                     @ resolution unsuccessful?
12794     beq     common_exceptionThrown     @ yes, throw exception
12795     @ fall through to OP_IPUT_BYTE_JUMBO_finish
12796
12797    /*
12798     * Currently:
12799     *  r0 holds resolved field
12800     *  r9 holds object
12801     */
12802.LOP_IPUT_BYTE_JUMBO_finish:
12803    @bl      common_squeak2
12804    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12805    FETCH(r1, 3)                        @ r1<- BBBB
12806    cmp     r9, #0                      @ check object for null
12807    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12808    beq     common_errNullObject        @ object was null
12809    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12810    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12811    @ no-op                             @ releasing store
12812    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12813    GOTO_OPCODE(ip)                     @ jump to next instruction
12814
12815/* continuation for OP_IPUT_CHAR_JUMBO */
12816
12817    /*
12818     * Currently:
12819     *  r0 holds resolved field
12820     *  r9 holds object
12821     */
12822.LOP_IPUT_CHAR_JUMBO_resolved:
12823     cmp     r0, #0                     @ resolution unsuccessful?
12824     beq     common_exceptionThrown     @ yes, throw exception
12825     @ fall through to OP_IPUT_CHAR_JUMBO_finish
12826
12827    /*
12828     * Currently:
12829     *  r0 holds resolved field
12830     *  r9 holds object
12831     */
12832.LOP_IPUT_CHAR_JUMBO_finish:
12833    @bl      common_squeak3
12834    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12835    FETCH(r1, 3)                        @ r1<- BBBB
12836    cmp     r9, #0                      @ check object for null
12837    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12838    beq     common_errNullObject        @ object was null
12839    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12840    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12841    @ no-op                             @ releasing store
12842    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12843    GOTO_OPCODE(ip)                     @ jump to next instruction
12844
12845/* continuation for OP_IPUT_SHORT_JUMBO */
12846
12847    /*
12848     * Currently:
12849     *  r0 holds resolved field
12850     *  r9 holds object
12851     */
12852.LOP_IPUT_SHORT_JUMBO_resolved:
12853     cmp     r0, #0                     @ resolution unsuccessful?
12854     beq     common_exceptionThrown     @ yes, throw exception
12855     @ fall through to OP_IPUT_SHORT_JUMBO_finish
12856
12857    /*
12858     * Currently:
12859     *  r0 holds resolved field
12860     *  r9 holds object
12861     */
12862.LOP_IPUT_SHORT_JUMBO_finish:
12863    @bl      common_squeak4
12864    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12865    FETCH(r1, 3)                        @ r1<- BBBB
12866    cmp     r9, #0                      @ check object for null
12867    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12868    beq     common_errNullObject        @ object was null
12869    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12870    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12871    @ no-op                             @ releasing store
12872    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12873    GOTO_OPCODE(ip)                     @ jump to next instruction
12874
12875/* continuation for OP_SGET_JUMBO */
12876
12877    /*
12878     * Continuation if the field has not yet been resolved.
12879     *  r1: AAAAAAAA field ref
12880     */
12881.LOP_SGET_JUMBO_resolve:
12882    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12883    EXPORT_PC()                         @ resolve() could throw, so export now
12884    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12885    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12886    cmp     r0, #0                      @ success?
12887    bne     .LOP_SGET_JUMBO_finish          @ yes, finish
12888    b       common_exceptionThrown      @ no, handle exception
12889
12890/* continuation for OP_SGET_WIDE_JUMBO */
12891
12892    /*
12893     * Continuation if the field has not yet been resolved.
12894     *  r1: BBBB field ref
12895     *
12896     * Returns StaticField pointer in r0.
12897     */
12898.LOP_SGET_WIDE_JUMBO_resolve:
12899    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12900    EXPORT_PC()                         @ resolve() could throw, so export now
12901    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12902    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12903    cmp     r0, #0                      @ success?
12904    bne     .LOP_SGET_WIDE_JUMBO_finish          @ yes, finish
12905    b       common_exceptionThrown      @ no, handle exception
12906
12907/* continuation for OP_SGET_OBJECT_JUMBO */
12908
12909    /*
12910     * Continuation if the field has not yet been resolved.
12911     *  r1: AAAAAAAA field ref
12912     */
12913.LOP_SGET_OBJECT_JUMBO_resolve:
12914    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12915    EXPORT_PC()                         @ resolve() could throw, so export now
12916    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12917    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12918    cmp     r0, #0                      @ success?
12919    bne     .LOP_SGET_OBJECT_JUMBO_finish          @ yes, finish
12920    b       common_exceptionThrown      @ no, handle exception
12921
12922/* continuation for OP_SGET_BOOLEAN_JUMBO */
12923
12924    /*
12925     * Continuation if the field has not yet been resolved.
12926     *  r1: AAAAAAAA field ref
12927     */
12928.LOP_SGET_BOOLEAN_JUMBO_resolve:
12929    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12930    EXPORT_PC()                         @ resolve() could throw, so export now
12931    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12932    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12933    cmp     r0, #0                      @ success?
12934    bne     .LOP_SGET_BOOLEAN_JUMBO_finish          @ yes, finish
12935    b       common_exceptionThrown      @ no, handle exception
12936
12937/* continuation for OP_SGET_BYTE_JUMBO */
12938
12939    /*
12940     * Continuation if the field has not yet been resolved.
12941     *  r1: AAAAAAAA field ref
12942     */
12943.LOP_SGET_BYTE_JUMBO_resolve:
12944    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12945    EXPORT_PC()                         @ resolve() could throw, so export now
12946    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12947    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12948    cmp     r0, #0                      @ success?
12949    bne     .LOP_SGET_BYTE_JUMBO_finish          @ yes, finish
12950    b       common_exceptionThrown      @ no, handle exception
12951
12952/* continuation for OP_SGET_CHAR_JUMBO */
12953
12954    /*
12955     * Continuation if the field has not yet been resolved.
12956     *  r1: AAAAAAAA field ref
12957     */
12958.LOP_SGET_CHAR_JUMBO_resolve:
12959    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12960    EXPORT_PC()                         @ resolve() could throw, so export now
12961    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12962    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12963    cmp     r0, #0                      @ success?
12964    bne     .LOP_SGET_CHAR_JUMBO_finish          @ yes, finish
12965    b       common_exceptionThrown      @ no, handle exception
12966
12967/* continuation for OP_SGET_SHORT_JUMBO */
12968
12969    /*
12970     * Continuation if the field has not yet been resolved.
12971     *  r1: AAAAAAAA field ref
12972     */
12973.LOP_SGET_SHORT_JUMBO_resolve:
12974    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12975    EXPORT_PC()                         @ resolve() could throw, so export now
12976    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12977    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12978    cmp     r0, #0                      @ success?
12979    bne     .LOP_SGET_SHORT_JUMBO_finish          @ yes, finish
12980    b       common_exceptionThrown      @ no, handle exception
12981
12982/* continuation for OP_SPUT_JUMBO */
12983
12984    /*
12985     * Continuation if the field has not yet been resolved.
12986     *  r1: AAAAAAAA field ref
12987     */
12988.LOP_SPUT_JUMBO_resolve:
12989    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12990    EXPORT_PC()                         @ resolve() could throw, so export now
12991    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12992    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12993    cmp     r0, #0                      @ success?
12994    bne     .LOP_SPUT_JUMBO_finish          @ yes, finish
12995    b       common_exceptionThrown      @ no, handle exception
12996
12997/* continuation for OP_SPUT_WIDE_JUMBO */
12998
12999    /*
13000     * Continuation if the field has not yet been resolved.
13001     *  r1: BBBB field ref
13002     *  r9: &fp[AA]
13003     *
13004     * Returns StaticField pointer in r2.
13005     */
13006.LOP_SPUT_WIDE_JUMBO_resolve:
13007    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13008    EXPORT_PC()                         @ resolve() could throw, so export now
13009    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13010    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13011    cmp     r0, #0                      @ success?
13012    mov     r2, r0                      @ copy to r2
13013    bne     .LOP_SPUT_WIDE_JUMBO_finish          @ yes, finish
13014    b       common_exceptionThrown      @ no, handle exception
13015
13016/* continuation for OP_SPUT_OBJECT_JUMBO */
13017
13018.LOP_SPUT_OBJECT_JUMBO_finish:   @ field ptr in r0
13019    FETCH(r2, 3)                        @ r2<- BBBB
13020    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
13021    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
13022    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
13023    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
13024    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13025    @ no-op                             @ releasing store
13026    str     r1, [r0, #offStaticField_value]  @ field<- vBBBB
13027    cmp     r1, #0                      @ stored a null object?
13028    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
13029    GOTO_OPCODE(ip)                     @ jump to next instruction
13030
13031/* continuation for OP_SPUT_BOOLEAN_JUMBO */
13032
13033    /*
13034     * Continuation if the field has not yet been resolved.
13035     *  r1: AAAAAAAA field ref
13036     */
13037.LOP_SPUT_BOOLEAN_JUMBO_resolve:
13038    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13039    EXPORT_PC()                         @ resolve() could throw, so export now
13040    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13041    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13042    cmp     r0, #0                      @ success?
13043    bne     .LOP_SPUT_BOOLEAN_JUMBO_finish          @ yes, finish
13044    b       common_exceptionThrown      @ no, handle exception
13045
13046/* continuation for OP_SPUT_BYTE_JUMBO */
13047
13048    /*
13049     * Continuation if the field has not yet been resolved.
13050     *  r1: AAAAAAAA field ref
13051     */
13052.LOP_SPUT_BYTE_JUMBO_resolve:
13053    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13054    EXPORT_PC()                         @ resolve() could throw, so export now
13055    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13056    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13057    cmp     r0, #0                      @ success?
13058    bne     .LOP_SPUT_BYTE_JUMBO_finish          @ yes, finish
13059    b       common_exceptionThrown      @ no, handle exception
13060
13061/* continuation for OP_SPUT_CHAR_JUMBO */
13062
13063    /*
13064     * Continuation if the field has not yet been resolved.
13065     *  r1: AAAAAAAA field ref
13066     */
13067.LOP_SPUT_CHAR_JUMBO_resolve:
13068    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13069    EXPORT_PC()                         @ resolve() could throw, so export now
13070    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13071    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13072    cmp     r0, #0                      @ success?
13073    bne     .LOP_SPUT_CHAR_JUMBO_finish          @ yes, finish
13074    b       common_exceptionThrown      @ no, handle exception
13075
13076/* continuation for OP_SPUT_SHORT_JUMBO */
13077
13078    /*
13079     * Continuation if the field has not yet been resolved.
13080     *  r1: AAAAAAAA field ref
13081     */
13082.LOP_SPUT_SHORT_JUMBO_resolve:
13083    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13084    EXPORT_PC()                         @ resolve() could throw, so export now
13085    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13086    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13087    cmp     r0, #0                      @ success?
13088    bne     .LOP_SPUT_SHORT_JUMBO_finish          @ yes, finish
13089    b       common_exceptionThrown      @ no, handle exception
13090
13091/* continuation for OP_INVOKE_VIRTUAL_JUMBO */
13092
13093    /*
13094     * At this point:
13095     *  r0 = resolved base method
13096     */
13097.LOP_INVOKE_VIRTUAL_JUMBO_continue:
13098    FETCH(r10, 4)                       @ r10<- CCCC
13099    GET_VREG(r1, r10)                   @ r1<- "this" ptr
13100    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
13101    cmp     r1, #0                      @ is "this" null?
13102    beq     common_errNullObject        @ null "this", throw exception
13103    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
13104    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
13105    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
13106    bl      common_invokeMethodJumbo    @ continue on
13107
13108/* continuation for OP_INVOKE_SUPER_JUMBO */
13109
13110    /*
13111     * At this point:
13112     *  r0 = resolved base method
13113     *  r9 = method->clazz
13114     */
13115.LOP_INVOKE_SUPER_JUMBO_continue:
13116    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
13117    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
13118    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
13119    EXPORT_PC()                         @ must export for invoke
13120    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
13121    bcs     .LOP_INVOKE_SUPER_JUMBO_nsm             @ method not present in superclass
13122    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
13123    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
13124    bl      common_invokeMethodJumbo    @ continue on
13125
13126.LOP_INVOKE_SUPER_JUMBO_resolve:
13127    mov     r0, r9                      @ r0<- method->clazz
13128    mov     r2, #METHOD_VIRTUAL         @ resolver method type
13129    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
13130    cmp     r0, #0                      @ got null?
13131    bne     .LOP_INVOKE_SUPER_JUMBO_continue        @ no, continue
13132    b       common_exceptionThrown      @ yes, handle exception
13133
13134    /*
13135     * Throw a NoSuchMethodError with the method name as the message.
13136     *  r0 = resolved base method
13137     */
13138.LOP_INVOKE_SUPER_JUMBO_nsm:
13139    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
13140    b       common_errNoSuchMethod
13141
13142/* continuation for OP_INVOKE_DIRECT_JUMBO */
13143
13144    /*
13145     * On entry:
13146     *  r1 = reference (CCCC)
13147     *  r10 = "this" register
13148     */
13149.LOP_INVOKE_DIRECT_JUMBO_resolve:
13150    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
13151    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
13152    mov     r2, #METHOD_DIRECT          @ resolver method type
13153    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
13154    cmp     r0, #0                      @ got null?
13155    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
13156    bne     .LOP_INVOKE_DIRECT_JUMBO_finish          @ no, continue
13157    b       common_exceptionThrown      @ yes, handle exception
13158
13159    .size   dvmAsmSisterStart, .-dvmAsmSisterStart
13160    .global dvmAsmSisterEnd
13161dvmAsmSisterEnd:
13162
13163/* File: armv5te/footer.S */
13164
13165/*
13166 * ===========================================================================
13167 *  Common subroutines and data
13168 * ===========================================================================
13169 */
13170
13171
13172
13173    .text
13174    .align  2
13175
13176#if defined(WITH_JIT)
13177#if defined(WITH_SELF_VERIFICATION)
13178    .global dvmJitToInterpPunt
13179dvmJitToInterpPunt:
13180    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13181    mov    r2,#kSVSPunt                 @ r2<- interpreter entry point
13182    mov    r3, #0
13183    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13184    b      jitSVShadowRunEnd            @ doesn't return
13185
13186    .global dvmJitToInterpSingleStep
13187dvmJitToInterpSingleStep:
13188    str    lr,[rGLUE,#offGlue_jitResumeNPC]
13189    str    r1,[rGLUE,#offGlue_jitResumeDPC]
13190    mov    r2,#kSVSSingleStep           @ r2<- interpreter entry point
13191    b      jitSVShadowRunEnd            @ doesn't return
13192
13193    .global dvmJitToInterpNoChainNoProfile
13194dvmJitToInterpNoChainNoProfile:
13195    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13196    mov    r0,rPC                       @ pass our target PC
13197    mov    r2,#kSVSNoProfile            @ r2<- interpreter entry point
13198    mov    r3, #0                       @ 0 means !inJitCodeCache
13199    str    r3, [r10, #offThread_inJitCodeCache] @ back to the interp land
13200    b      jitSVShadowRunEnd            @ doesn't return
13201
13202    .global dvmJitToInterpTraceSelectNoChain
13203dvmJitToInterpTraceSelectNoChain:
13204    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13205    mov    r0,rPC                       @ pass our target PC
13206    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
13207    mov    r3, #0                       @ 0 means !inJitCodeCache
13208    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13209    b      jitSVShadowRunEnd            @ doesn't return
13210
13211    .global dvmJitToInterpTraceSelect
13212dvmJitToInterpTraceSelect:
13213    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13214    ldr    r0,[lr, #-1]                 @ pass our target PC
13215    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
13216    mov    r3, #0                       @ 0 means !inJitCodeCache
13217    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13218    b      jitSVShadowRunEnd            @ doesn't return
13219
13220    .global dvmJitToInterpBackwardBranch
13221dvmJitToInterpBackwardBranch:
13222    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13223    ldr    r0,[lr, #-1]                 @ pass our target PC
13224    mov    r2,#kSVSBackwardBranch       @ r2<- interpreter entry point
13225    mov    r3, #0                       @ 0 means !inJitCodeCache
13226    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13227    b      jitSVShadowRunEnd            @ doesn't return
13228
13229    .global dvmJitToInterpNormal
13230dvmJitToInterpNormal:
13231    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13232    ldr    r0,[lr, #-1]                 @ pass our target PC
13233    mov    r2,#kSVSNormal               @ r2<- interpreter entry point
13234    mov    r3, #0                       @ 0 means !inJitCodeCache
13235    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13236    b      jitSVShadowRunEnd            @ doesn't return
13237
13238    .global dvmJitToInterpNoChain
13239dvmJitToInterpNoChain:
13240    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13241    mov    r0,rPC                       @ pass our target PC
13242    mov    r2,#kSVSNoChain              @ r2<- interpreter entry point
13243    mov    r3, #0                       @ 0 means !inJitCodeCache
13244    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13245    b      jitSVShadowRunEnd            @ doesn't return
13246#else
13247/*
13248 * Return from the translation cache to the interpreter when the compiler is
13249 * having issues translating/executing a Dalvik instruction. We have to skip
13250 * the code cache lookup otherwise it is possible to indefinitely bouce
13251 * between the interpreter and the code cache if the instruction that fails
13252 * to be compiled happens to be at a trace start.
13253 */
13254    .global dvmJitToInterpPunt
13255dvmJitToInterpPunt:
13256    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13257    mov    rPC, r0
13258#if defined(WITH_JIT_TUNING)
13259    mov    r0,lr
13260    bl     dvmBumpPunt;
13261#endif
13262    EXPORT_PC()
13263    mov    r0, #0
13264    str    r0, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13265    adrl   rIBASE, dvmAsmInstructionStart
13266    FETCH_INST()
13267    GET_INST_OPCODE(ip)
13268    GOTO_OPCODE(ip)
13269
13270/*
13271 * Return to the interpreter to handle a single instruction.
13272 * On entry:
13273 *    r0 <= PC
13274 *    r1 <= PC of resume instruction
13275 *    lr <= resume point in translation
13276 */
13277    .global dvmJitToInterpSingleStep
13278dvmJitToInterpSingleStep:
13279    str    lr,[rGLUE,#offGlue_jitResumeNPC]
13280    str    r1,[rGLUE,#offGlue_jitResumeDPC]
13281    mov    r1,#kInterpEntryInstr
13282    @ enum is 4 byte in aapcs-EABI
13283    str    r1, [rGLUE, #offGlue_entryPoint]
13284    mov    rPC,r0
13285    EXPORT_PC()
13286
13287    adrl   rIBASE, dvmAsmInstructionStart
13288    mov    r2,#kJitSingleStep     @ Ask for single step and then revert
13289    str    r2,[rGLUE,#offGlue_jitState]
13290    mov    r1,#1                  @ set changeInterp to bail to debug interp
13291    b      common_gotoBail
13292
13293/*
13294 * Return from the translation cache and immediately request
13295 * a translation for the exit target.  Commonly used for callees.
13296 */
13297    .global dvmJitToInterpTraceSelectNoChain
13298dvmJitToInterpTraceSelectNoChain:
13299#if defined(WITH_JIT_TUNING)
13300    bl     dvmBumpNoChain
13301#endif
13302    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13303    mov    r0,rPC
13304    bl     dvmJitGetTraceAddr       @ Is there a translation?
13305    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13306    mov    r1, rPC                  @ arg1 of translation may need this
13307    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13308    cmp    r0,#0                    @ !0 means translation exists
13309    bxne   r0                       @ continue native execution if so
13310    b      2f                       @ branch over to use the interpreter
13311
13312/*
13313 * Return from the translation cache and immediately request
13314 * a translation for the exit target.  Commonly used following
13315 * invokes.
13316 */
13317    .global dvmJitToInterpTraceSelect
13318dvmJitToInterpTraceSelect:
13319    ldr    rPC,[lr, #-1]           @ get our target PC
13320    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13321    add    rINST,lr,#-5            @ save start of chain branch
13322    add    rINST, #-4              @  .. which is 9 bytes back
13323    mov    r0,rPC
13324    bl     dvmJitGetTraceAddr      @ Is there a translation?
13325    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13326    cmp    r0,#0
13327    beq    2f
13328    mov    r1,rINST
13329    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
13330    mov    r1, rPC                  @ arg1 of translation may need this
13331    mov    lr, #0                   @ in case target is HANDLER_INTERPRET
13332    cmp    r0,#0                    @ successful chain?
13333    bxne   r0                       @ continue native execution
13334    b      toInterpreter            @ didn't chain - resume with interpreter
13335
13336/* No translation, so request one if profiling isn't disabled*/
133372:
13338    adrl   rIBASE, dvmAsmInstructionStart
13339    GET_JIT_PROF_TABLE(r0)
13340    FETCH_INST()
13341    cmp    r0, #0
13342    movne  r2,#kJitTSelectRequestHot   @ ask for trace selection
13343    bne    common_selectTrace
13344    GET_INST_OPCODE(ip)
13345    GOTO_OPCODE(ip)
13346
13347/*
13348 * Return from the translation cache to the interpreter.
13349 * The return was done with a BLX from thumb mode, and
13350 * the following 32-bit word contains the target rPC value.
13351 * Note that lr (r14) will have its low-order bit set to denote
13352 * its thumb-mode origin.
13353 *
13354 * We'll need to stash our lr origin away, recover the new
13355 * target and then check to see if there is a translation available
13356 * for our new target.  If so, we do a translation chain and
13357 * go back to native execution.  Otherwise, it's back to the
13358 * interpreter (after treating this entry as a potential
13359 * trace start).
13360 */
13361    .global dvmJitToInterpNormal
13362dvmJitToInterpNormal:
13363    ldr    rPC,[lr, #-1]           @ get our target PC
13364    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13365    add    rINST,lr,#-5            @ save start of chain branch
13366    add    rINST,#-4               @ .. which is 9 bytes back
13367#if defined(WITH_JIT_TUNING)
13368    bl     dvmBumpNormal
13369#endif
13370    mov    r0,rPC
13371    bl     dvmJitGetTraceAddr      @ Is there a translation?
13372    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13373    cmp    r0,#0
13374    beq    toInterpreter            @ go if not, otherwise do chain
13375    mov    r1,rINST
13376    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
13377    mov    r1, rPC                  @ arg1 of translation may need this
13378    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13379    cmp    r0,#0                    @ successful chain?
13380    bxne   r0                       @ continue native execution
13381    b      toInterpreter            @ didn't chain - resume with interpreter
13382
13383/*
13384 * Return from the translation cache to the interpreter to do method invocation.
13385 * Check if translation exists for the callee, but don't chain to it.
13386 */
13387    .global dvmJitToInterpNoChainNoProfile
13388dvmJitToInterpNoChainNoProfile:
13389#if defined(WITH_JIT_TUNING)
13390    bl     dvmBumpNoChain
13391#endif
13392    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13393    mov    r0,rPC
13394    bl     dvmJitGetTraceAddr       @ Is there a translation?
13395    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13396    mov    r1, rPC                  @ arg1 of translation may need this
13397    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13398    cmp    r0,#0
13399    bxne   r0                       @ continue native execution if so
13400    EXPORT_PC()
13401    adrl   rIBASE, dvmAsmInstructionStart
13402    FETCH_INST()
13403    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13404    GOTO_OPCODE(ip)                     @ jump to next instruction
13405
13406/*
13407 * Return from the translation cache to the interpreter to do method invocation.
13408 * Check if translation exists for the callee, but don't chain to it.
13409 */
13410    .global dvmJitToInterpNoChain
13411dvmJitToInterpNoChain:
13412#if defined(WITH_JIT_TUNING)
13413    bl     dvmBumpNoChain
13414#endif
13415    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13416    mov    r0,rPC
13417    bl     dvmJitGetTraceAddr       @ Is there a translation?
13418    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13419    mov    r1, rPC                  @ arg1 of translation may need this
13420    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13421    cmp    r0,#0
13422    bxne   r0                       @ continue native execution if so
13423#endif
13424
13425/*
13426 * No translation, restore interpreter regs and start interpreting.
13427 * rGLUE & rFP were preserved in the translated code, and rPC has
13428 * already been restored by the time we get here.  We'll need to set
13429 * up rIBASE & rINST, and load the address of the JitTable into r0.
13430 */
13431toInterpreter:
13432    EXPORT_PC()
13433    adrl   rIBASE, dvmAsmInstructionStart
13434    FETCH_INST()
13435    GET_JIT_PROF_TABLE(r0)
13436    @ NOTE: intended fallthrough
13437
13438/*
13439 * Common code to update potential trace start counter, and initiate
13440 * a trace-build if appropriate.  On entry, rPC should point to the
13441 * next instruction to execute, and rINST should be already loaded with
13442 * the next opcode word, and r0 holds a pointer to the jit profile
13443 * table (pJitProfTable).
13444 */
13445common_testUpdateProfile:
13446    cmp     r0,#0
13447    GET_INST_OPCODE(ip)
13448    GOTO_OPCODE_IFEQ(ip)       @ if not profiling, fallthrough otherwise */
13449
13450common_updateProfile:
13451    eor     r3,rPC,rPC,lsr #12 @ cheap, but fast hash function
13452    lsl     r3,r3,#(32 - JIT_PROF_SIZE_LOG_2)          @ shift out excess bits
13453    ldrb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter
13454    GET_INST_OPCODE(ip)
13455    subs    r1,r1,#1           @ decrement counter
13456    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it
13457    GOTO_OPCODE_IFNE(ip)       @ if not threshold, fallthrough otherwise */
13458
13459/*
13460 * Here, we switch to the debug interpreter to request
13461 * trace selection.  First, though, check to see if there
13462 * is already a native translation in place (and, if so,
13463 * jump to it now).
13464 */
13465    GET_JIT_THRESHOLD(r1)
13466    ldr     r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
13467    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter
13468    EXPORT_PC()
13469    mov     r0,rPC
13470    bl      dvmJitGetTraceAddr          @ r0<- dvmJitGetTraceAddr(rPC)
13471    str     r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13472    mov     r1, rPC                     @ arg1 of translation may need this
13473    mov     lr, #0                      @  in case target is HANDLER_INTERPRET
13474    cmp     r0,#0
13475#if !defined(WITH_SELF_VERIFICATION)
13476    bxne    r0                          @ jump to the translation
13477    mov     r2,#kJitTSelectRequest      @ ask for trace selection
13478    @ fall-through to common_selectTrace
13479#else
13480    moveq   r2,#kJitTSelectRequest      @ ask for trace selection
13481    beq     common_selectTrace
13482    /*
13483     * At this point, we have a target translation.  However, if
13484     * that translation is actually the interpret-only pseudo-translation
13485     * we want to treat it the same as no translation.
13486     */
13487    mov     r10, r0                     @ save target
13488    bl      dvmCompilerGetInterpretTemplate
13489    cmp     r0, r10                     @ special case?
13490    bne     jitSVShadowRunStart         @ set up self verification shadow space
13491    @ Need to clear the inJitCodeCache flag
13492    ldr    r10, [rGLUE, #offGlue_self]  @ r10 <- glue->self
13493    mov    r3, #0                       @ 0 means not in the JIT code cache
13494    str    r3, [r10, #offThread_inJitCodeCache] @ back to the interp land
13495    GET_INST_OPCODE(ip)
13496    GOTO_OPCODE(ip)
13497    /* no return */
13498#endif
13499
13500/*
13501 * On entry:
13502 *  r2 is jit state, e.g. kJitTSelectRequest or kJitTSelectRequestHot
13503 */
13504common_selectTrace:
13505    str     r2,[rGLUE,#offGlue_jitState]
13506    mov     r2,#kInterpEntryInstr       @ normal entry reason
13507    str     r2,[rGLUE,#offGlue_entryPoint]
13508    mov     r1,#1                       @ set changeInterp
13509    b       common_gotoBail
13510
13511#if defined(WITH_SELF_VERIFICATION)
13512/*
13513 * Save PC and registers to shadow memory for self verification mode
13514 * before jumping to native translation.
13515 * On entry:
13516 *    rPC, rFP, rGLUE: the values that they should contain
13517 *    r10: the address of the target translation.
13518 */
13519jitSVShadowRunStart:
13520    mov     r0,rPC                      @ r0<- program counter
13521    mov     r1,rFP                      @ r1<- frame pointer
13522    mov     r2,rGLUE                    @ r2<- InterpState pointer
13523    mov     r3,r10                      @ r3<- target translation
13524    bl      dvmSelfVerificationSaveState @ save registers to shadow space
13525    ldr     rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space
13526    add     rGLUE,r0,#offShadowSpace_interpState @ rGLUE<- rGLUE in shadow space
13527    bx      r10                         @ jump to the translation
13528
13529/*
13530 * Restore PC, registers, and interpState to original values
13531 * before jumping back to the interpreter.
13532 */
13533jitSVShadowRunEnd:
13534    mov    r1,rFP                        @ pass ending fp
13535    bl     dvmSelfVerificationRestoreState @ restore pc and fp values
13536    ldr    rPC,[r0,#offShadowSpace_startPC] @ restore PC
13537    ldr    rFP,[r0,#offShadowSpace_fp]   @ restore FP
13538    ldr    rGLUE,[r0,#offShadowSpace_glue] @ restore InterpState
13539    ldr    r1,[r0,#offShadowSpace_svState] @ get self verification state
13540    cmp    r1,#0                         @ check for punt condition
13541    beq    1f
13542    mov    r2,#kJitSelfVerification      @ ask for self verification
13543    str    r2,[rGLUE,#offGlue_jitState]
13544    mov    r2,#kInterpEntryInstr         @ normal entry reason
13545    str    r2,[rGLUE,#offGlue_entryPoint]
13546    mov    r1,#1                         @ set changeInterp
13547    b      common_gotoBail
13548
135491:                                       @ exit to interpreter without check
13550    EXPORT_PC()
13551    adrl   rIBASE, dvmAsmInstructionStart
13552    FETCH_INST()
13553    GET_INST_OPCODE(ip)
13554    GOTO_OPCODE(ip)
13555#endif
13556
13557#endif
13558
13559/*
13560 * Common code when a backward branch is taken.
13561 *
13562 * TODO: we could avoid a branch by just setting r0 and falling through
13563 * into the common_periodicChecks code, and having a test on r0 at the
13564 * end determine if we should return to the caller or update & branch to
13565 * the next instr.
13566 *
13567 * On entry:
13568 *  r9 is PC adjustment *in bytes*
13569 */
13570common_backwardBranch:
13571    mov     r0, #kInterpEntryInstr
13572    bl      common_periodicChecks
13573#if defined(WITH_JIT)
13574    GET_JIT_PROF_TABLE(r0)
13575    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
13576    cmp     r0,#0
13577    bne     common_updateProfile
13578    GET_INST_OPCODE(ip)
13579    GOTO_OPCODE(ip)
13580#else
13581    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
13582    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13583    GOTO_OPCODE(ip)                     @ jump to next instruction
13584#endif
13585
13586
13587/*
13588 * Need to see if the thread needs to be suspended or debugger/profiler
13589 * activity has begun.  If so, we suspend the thread or side-exit to
13590 * the debug interpreter as appropriate.
13591 *
13592 * The common case is no activity on any of these, so we want to figure
13593 * that out quickly.  If something is up, we can then sort out what.
13594 *
13595 * We want to be fast if the VM was built without debugger or profiler
13596 * support, but we also need to recognize that the system is usually
13597 * shipped with both of these enabled.
13598 *
13599 * TODO: reduce this so we're just checking a single location.
13600 *
13601 * On entry:
13602 *  r0 is reentry type, e.g. kInterpEntryInstr (for debugger/profiling)
13603 *  r9 is trampoline PC adjustment *in bytes*
13604 */
13605common_periodicChecks:
13606    ldr     r1, [rGLUE, #offGlue_pInterpBreak] @ r3<- &interpBreak
13607    /* speculatively load address of thread-specific suspend count */
13608    ldr     r3, [rGLUE, #offGlue_pSelfSuspendCount] @ r3<- &suspendCount
13609    ldr     r1, [r1]                                @ r1<- interpBreak
13610    /* speculatively load thread-specific suspend count */
13611    ldr     ip, [r3]                    @ ip<- suspendCount (int)
13612    cmp     r1, #0                                  @ anything unusual?
13613    bxeq    lr                                      @ return if not
13614    /*
13615     * One or more interesting events have happened.  Figure out what.
13616     *
13617     * r0 still holds the reentry type.
13618     */
13619    cmp     ip, #0                      @ want suspend?
13620    beq     3f                          @ no, must be something else
13621
13622    stmfd   sp!, {r0, lr}               @ preserve r0 and lr
13623#if defined(WITH_JIT)
13624    /*
13625     * Refresh the Jit's cached copy of profile table pointer.  This pointer
13626     * doubles as the Jit's on/off switch.
13627     */
13628    ldr     r3, [rGLUE, #offGlue_ppJitProfTable] @ r3<-&gDvmJit.pJitProfTable
13629    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
13630    ldr     r3, [r3] @ r3 <- pJitProfTable
13631    EXPORT_PC()                         @ need for precise GC
13632    str     r3, [rGLUE, #offGlue_pJitProfTable] @ refresh Jit's on/off switch
13633#else
13634    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
13635    EXPORT_PC()                         @ need for precise GC
13636#endif
13637    bl      dvmCheckSuspendPending      @ do full check, suspend if necessary
13638    ldmfd   sp!, {r0, lr}               @ restore r0 and lr
13639
13640    /*
13641     * Reload the interpBreak flags - they may have changed while we
13642     * were suspended.
13643     */
13644    ldr     r1, [rGLUE, #offGlue_pInterpBreak]   @ r1<- &interpBreak
13645    ldr     r1, [r1]                    @ r1<- interpBreak
136463:
13647    /*
13648     * TODO: this code is too fragile.  Need a general mechanism
13649     * to identify what actions to take by submode.  Some profiling modes
13650     * (instruction count) need to single-step, while method tracing
13651     * may not.  Debugging with breakpoints can run unfettered, but
13652     * source-level single-stepping requires Dalvik singlestepping.
13653     * GC may require a one-shot action and then full-speed resumption.
13654     */
13655    ands    r1, #(kSubModeDebuggerActive | kSubModeEmulatorTrace | kSubModeInstCounting)
13656    bxeq    lr                          @ nothing to do, return
13657
13658    @ debugger/profiler enabled, bail out; glue->entryPoint was set above
13659    str     r0, [rGLUE, #offGlue_entryPoint]    @ store r0, need for debug/prof
13660    add     rPC, rPC, r9                @ update rPC
13661    mov     r1, #1                      @ "want switch" = true
13662    b       common_gotoBail             @ side exit
13663
13664
13665/*
13666 * The equivalent of "goto bail", this calls through the "bail handler".
13667 *
13668 * State registers will be saved to the "glue" area before bailing.
13669 *
13670 * On entry:
13671 *  r1 is "bool changeInterp", indicating if we want to switch to the
13672 *     other interpreter or just bail all the way out
13673 */
13674common_gotoBail:
13675    SAVE_PC_FP_TO_GLUE()                @ export state to "glue"
13676    mov     r0, rGLUE                   @ r0<- glue ptr
13677    b       dvmMterpStdBail             @ call(glue, changeInterp)
13678
13679    @add     r1, r1, #1                  @ using (boolean+1)
13680    @add     r0, rGLUE, #offGlue_jmpBuf  @ r0<- &glue->jmpBuf
13681    @bl      _longjmp                    @ does not return
13682    @bl      common_abort
13683
13684
13685/*
13686 * Common code for jumbo method invocation.
13687 * NOTE: this adjusts rPC to account for the difference in instruction width.
13688 * As a result, the savedPc in the stack frame will not be wholly accurate. So
13689 * long as that is only used for source file line number calculations, we're
13690 * okay.
13691 *
13692 * On entry:
13693 *  r0 is "Method* methodToCall", the method we're trying to call
13694 */
13695common_invokeMethodJumbo:
13696.LinvokeNewJumbo:
13697    @ prepare to copy args to "outs" area of current frame
13698    add     rPC, rPC, #4                @ adjust pc to make return consistent
13699    FETCH(r2, 1)                        @ r2<- BBBB (arg count)
13700    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13701    cmp     r2, #0                      @ no args?
13702    beq     .LinvokeArgsDone            @ if no args, skip the rest
13703    FETCH(r1, 2)                        @ r1<- CCCC
13704    b       .LinvokeRangeArgs           @ handle args like invoke range
13705
13706/*
13707 * Common code for method invocation with range.
13708 *
13709 * On entry:
13710 *  r0 is "Method* methodToCall", the method we're trying to call
13711 */
13712common_invokeMethodRange:
13713.LinvokeNewRange:
13714    @ prepare to copy args to "outs" area of current frame
13715    movs    r2, rINST, lsr #8           @ r2<- AA (arg count) -- test for zero
13716    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13717    beq     .LinvokeArgsDone            @ if no args, skip the rest
13718    FETCH(r1, 2)                        @ r1<- CCCC
13719
13720.LinvokeRangeArgs:
13721    @ r0=methodToCall, r1=CCCC, r2=count, r10=outs
13722    @ (very few methods have > 10 args; could unroll for common cases)
13723    add     r3, rFP, r1, lsl #2         @ r3<- &fp[CCCC]
13724    sub     r10, r10, r2, lsl #2        @ r10<- "outs" area, for call args
137251:  ldr     r1, [r3], #4                @ val = *fp++
13726    subs    r2, r2, #1                  @ count--
13727    str     r1, [r10], #4               @ *outs++ = val
13728    bne     1b                          @ ...while count != 0
13729    b       .LinvokeArgsDone
13730
13731/*
13732 * Common code for method invocation without range.
13733 *
13734 * On entry:
13735 *  r0 is "Method* methodToCall", the method we're trying to call
13736 */
13737common_invokeMethodNoRange:
13738.LinvokeNewNoRange:
13739    @ prepare to copy args to "outs" area of current frame
13740    movs    r2, rINST, lsr #12          @ r2<- B (arg count) -- test for zero
13741    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13742    FETCH(r1, 2)                        @ r1<- GFED (load here to hide latency)
13743    beq     .LinvokeArgsDone
13744
13745    @ r0=methodToCall, r1=GFED, r2=count, r10=outs
13746.LinvokeNonRange:
13747    rsb     r2, r2, #5                  @ r2<- 5-r2
13748    add     pc, pc, r2, lsl #4          @ computed goto, 4 instrs each
13749    bl      common_abort                @ (skipped due to ARM prefetch)
137505:  and     ip, rINST, #0x0f00          @ isolate A
13751    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vA (shift right 8, left 2)
13752    mov     r0, r0                      @ nop
13753    str     r2, [r10, #-4]!             @ *--outs = vA
137544:  and     ip, r1, #0xf000             @ isolate G
13755    ldr     r2, [rFP, ip, lsr #10]      @ r2<- vG (shift right 12, left 2)
13756    mov     r0, r0                      @ nop
13757    str     r2, [r10, #-4]!             @ *--outs = vG
137583:  and     ip, r1, #0x0f00             @ isolate F
13759    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vF
13760    mov     r0, r0                      @ nop
13761    str     r2, [r10, #-4]!             @ *--outs = vF
137622:  and     ip, r1, #0x00f0             @ isolate E
13763    ldr     r2, [rFP, ip, lsr #2]       @ r2<- vE
13764    mov     r0, r0                      @ nop
13765    str     r2, [r10, #-4]!             @ *--outs = vE
137661:  and     ip, r1, #0x000f             @ isolate D
13767    ldr     r2, [rFP, ip, lsl #2]       @ r2<- vD
13768    mov     r0, r0                      @ nop
13769    str     r2, [r10, #-4]!             @ *--outs = vD
137700:  @ fall through to .LinvokeArgsDone
13771
13772.LinvokeArgsDone: @ r0=methodToCall
13773    ldrh    r9, [r0, #offMethod_registersSize]  @ r9<- methodToCall->regsSize
13774    ldrh    r3, [r0, #offMethod_outsSize]  @ r3<- methodToCall->outsSize
13775    ldr     r2, [r0, #offMethod_insns]  @ r2<- method->insns
13776    ldr     rINST, [r0, #offMethod_clazz]  @ rINST<- method->clazz
13777    @ find space for the new stack frame, check for overflow
13778    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- stack save area
13779    sub     r1, r1, r9, lsl #2          @ r1<- newFp (old savearea - regsSize)
13780    SAVEAREA_FROM_FP(r10, r1)           @ r10<- newSaveArea
13781@    bl      common_dumpRegs
13782    ldr     r9, [rGLUE, #offGlue_interpStackEnd]    @ r9<- interpStackEnd
13783    sub     r3, r10, r3, lsl #2         @ r3<- bottom (newsave - outsSize)
13784    cmp     r3, r9                      @ bottom < interpStackEnd?
13785    ldr     lr, [rGLUE, #offGlue_pInterpBreak]
13786    ldr     r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags
13787    blo     .LstackOverflow             @ yes, this frame will overflow stack
13788
13789    @ set up newSaveArea
13790    ldr     lr, [lr]                    @ lr<- active submodes
13791#ifdef EASY_GDB
13792    SAVEAREA_FROM_FP(ip, rFP)           @ ip<- stack save area
13793    str     ip, [r10, #offStackSaveArea_prevSave]
13794#endif
13795    str     rFP, [r10, #offStackSaveArea_prevFrame]
13796    str     rPC, [r10, #offStackSaveArea_savedPc]
13797#if defined(WITH_JIT)
13798    mov     r9, #0
13799    str     r9, [r10, #offStackSaveArea_returnAddr]
13800#endif
13801    ands    lr, #kSubModeMethodTrace    @ method tracing?
13802    beq     1f                          @ skip if not
13803    stmfd   sp!, {r0-r3}                @ preserve r0-r3
13804    mov     r1, r6
13805    @ r0=methodToCall, r1=rGlue
13806    bl      dvmFastMethodTraceEnter
13807    ldmfd   sp!, {r0-r3}                @ restore r0-r3
138081:
13809    str     r0, [r10, #offStackSaveArea_method]
13810    tst     r3, #ACC_NATIVE
13811    bne     .LinvokeNative
13812
13813    /*
13814    stmfd   sp!, {r0-r3}
13815    bl      common_printNewline
13816    mov     r0, rFP
13817    mov     r1, #0
13818    bl      dvmDumpFp
13819    ldmfd   sp!, {r0-r3}
13820    stmfd   sp!, {r0-r3}
13821    mov     r0, r1
13822    mov     r1, r10
13823    bl      dvmDumpFp
13824    bl      common_printNewline
13825    ldmfd   sp!, {r0-r3}
13826    */
13827
13828    ldrh    r9, [r2]                        @ r9 <- load INST from new PC
13829    ldr     r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
13830    mov     rPC, r2                         @ publish new rPC
13831    ldr     r2, [rGLUE, #offGlue_self]      @ r2<- glue->self
13832
13833    @ Update "glue" values for the new method
13834    @ r0=methodToCall, r1=newFp, r2=self, r3=newMethodClass, r9=newINST
13835    str     r0, [rGLUE, #offGlue_method]    @ glue->method = methodToCall
13836    str     r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ...
13837#if defined(WITH_JIT)
13838    GET_JIT_PROF_TABLE(r0)
13839    mov     rFP, r1                         @ fp = newFp
13840    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
13841    mov     rINST, r9                       @ publish new rINST
13842    str     r1, [r2, #offThread_curFrame]   @ self->curFrame = newFp
13843    cmp     r0,#0
13844    bne     common_updateProfile
13845    GOTO_OPCODE(ip)                         @ jump to next instruction
13846#else
13847    mov     rFP, r1                         @ fp = newFp
13848    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
13849    mov     rINST, r9                       @ publish new rINST
13850    str     r1, [r2, #offThread_curFrame]   @ self->curFrame = newFp
13851    GOTO_OPCODE(ip)                         @ jump to next instruction
13852#endif
13853
13854.LinvokeNative:
13855    @ Prep for the native call
13856    @ r0=methodToCall, r1=newFp, r10=newSaveArea
13857    ldr     r3, [rGLUE, #offGlue_self]      @ r3<- glue->self
13858    ldr     lr, [rGLUE, #offGlue_pInterpBreak]
13859    ldr     r9, [r3, #offThread_jniLocal_topCookie] @ r9<- thread->localRef->...
13860    str     r1, [r3, #offThread_curFrame]   @ self->curFrame = newFp
13861    str     r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top
13862    ldr     lr, [lr]                    @ lr<- active submodes
13863    mov     r9, r3                      @ r9<- glue->self (preserve)
13864
13865    mov     r2, r0                      @ r2<- methodToCall
13866    mov     r0, r1                      @ r0<- newFp (points to args)
13867    add     r1, rGLUE, #offGlue_retval  @ r1<- &retval
13868
13869#ifdef ASSIST_DEBUGGER
13870    /* insert fake function header to help gdb find the stack frame */
13871    b       .Lskip
13872    .type   dalvik_mterp, %function
13873dalvik_mterp:
13874    .fnstart
13875    MTERP_ENTRY1
13876    MTERP_ENTRY2
13877.Lskip:
13878#endif
13879
13880    ands    lr, #kSubModeMethodTrace    @ method tracing?
13881    beq     110f                        @ hop if not
13882    @ r2=JNIMethod, r6=rGLUE
13883    stmfd   sp!, {r2,r6}
13884
13885    mov     lr, pc                      @ set return addr
13886    ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
13887
13888    @ r0=JNIMethod, r1=rGLUE
13889    ldmfd   sp!, {r0-r1}
13890    bl      dvmFastNativeMethodTraceExit
13891    b       220f
13892110:
13893    mov     lr, pc                      @ set return addr
13894    ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
13895220:
13896#if defined(WITH_JIT)
13897    ldr     r3, [rGLUE, #offGlue_ppJitProfTable] @ Refresh Jit's on/off status
13898#endif
13899
13900    @ native return; r9=self, r10=newSaveArea
13901    @ equivalent to dvmPopJniLocals
13902    ldr     r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top
13903    ldr     r1, [r9, #offThread_exception] @ check for exception
13904#if defined(WITH_JIT)
13905    ldr     r3, [r3]                    @ r3 <- gDvmJit.pProfTable
13906#endif
13907    str     rFP, [r9, #offThread_curFrame]  @ self->curFrame = fp
13908    cmp     r1, #0                      @ null?
13909    str     r0, [r9, #offThread_jniLocal_topCookie] @ new top <- old top
13910#if defined(WITH_JIT)
13911    str     r3, [rGLUE, #offGlue_pJitProfTable] @ refresh cached on/off switch
13912#endif
13913    bne     common_exceptionThrown      @ no, handle exception
13914
13915    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
13916    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13917    GOTO_OPCODE(ip)                     @ jump to next instruction
13918
13919.LstackOverflow:    @ r0=methodToCall
13920    mov     r1, r0                      @ r1<- methodToCall
13921    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- self
13922    bl      dvmHandleStackOverflow
13923    b       common_exceptionThrown
13924#ifdef ASSIST_DEBUGGER
13925    .fnend
13926    .size   dalvik_mterp, .-dalvik_mterp
13927#endif
13928
13929
13930    /*
13931     * Common code for method invocation, calling through "glue code".
13932     *
13933     * TODO: now that we have range and non-range invoke handlers, this
13934     *       needs to be split into two.  Maybe just create entry points
13935     *       that set r9 and jump here?
13936     *
13937     * On entry:
13938     *  r0 is "Method* methodToCall", the method we're trying to call
13939     *  r9 is "bool methodCallRange", indicating if this is a /range variant
13940     */
13941     .if    0
13942.LinvokeOld:
13943    sub     sp, sp, #8                  @ space for args + pad
13944    FETCH(ip, 2)                        @ ip<- FEDC or CCCC
13945    mov     r2, r0                      @ A2<- methodToCall
13946    mov     r0, rGLUE                   @ A0<- glue
13947    SAVE_PC_FP_TO_GLUE()                @ export state to "glue"
13948    mov     r1, r9                      @ A1<- methodCallRange
13949    mov     r3, rINST, lsr #8           @ A3<- AA
13950    str     ip, [sp, #0]                @ A4<- ip
13951    bl      dvmMterp_invokeMethod       @ call the C invokeMethod
13952    add     sp, sp, #8                  @ remove arg area
13953    b       common_resumeAfterGlueCall  @ continue to next instruction
13954    .endif
13955
13956
13957
13958/*
13959 * Common code for handling a return instruction.
13960 *
13961 * This does not return.
13962 */
13963common_returnFromMethod:
13964.LreturnNew:
13965    mov     r0, #kInterpEntryReturn
13966    mov     r9, #0
13967    bl      common_periodicChecks
13968
13969    ldr     lr, [rGLUE, #offGlue_pInterpBreak]
13970    SAVEAREA_FROM_FP(r0, rFP)
13971    ldr     lr, [lr]                    @ lr<- active submodes
13972    ldr     r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc
13973    ands    lr, #kSubModeMethodTrace    @ method tracing?
13974    beq     333f
13975    stmfd   sp!, {r0-r3}                @ preserve r0-r3
13976    mov     r0, r6
13977    @ r0=rGlue
13978    bl      dvmFastJavaMethodTraceExit
13979    ldmfd   sp!, {r0-r3}                @ restore r0-r3
13980333:
13981    ldr     rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame
13982    ldr     r3, [rGLUE, #offGlue_self]  @ r3<- glue->self
13983    ldr     r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)]
13984                                        @ r2<- method we're returning to
13985    cmp     r2, #0                      @ is this a break frame?
13986#if defined(WORKAROUND_CORTEX_A9_745320)
13987    /* Don't use conditional loads if the HW defect exists */
13988    beq     101f
13989    ldr     r10, [r2, #offMethod_clazz] @ r10<- method->clazz
13990101:
13991#else
13992    ldrne   r10, [r2, #offMethod_clazz] @ r10<- method->clazz
13993#endif
13994    mov     r1, #0                      @ "want switch" = false
13995    beq     common_gotoBail             @ break frame, bail out completely
13996
13997    PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST
13998    str     r2, [rGLUE, #offGlue_method]@ glue->method = newSave->method
13999    ldr     r1, [r10, #offClassObject_pDvmDex]   @ r1<- method->clazz->pDvmDex
14000    str     rFP, [r3, #offThread_curFrame]  @ self->curFrame = fp
14001#if defined(WITH_JIT)
14002    ldr     r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr
14003    mov     rPC, r9                     @ publish new rPC
14004    str     r1, [rGLUE, #offGlue_methodClassDex]
14005    str     r10, [r3, #offThread_inJitCodeCache]  @ may return to JIT'ed land
14006    cmp     r10, #0                      @ caller is compiled code
14007    blxne   r10
14008    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14009    GOTO_OPCODE(ip)                     @ jump to next instruction
14010#else
14011    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14012    mov     rPC, r9                     @ publish new rPC
14013    str     r1, [rGLUE, #offGlue_methodClassDex]
14014    GOTO_OPCODE(ip)                     @ jump to next instruction
14015#endif
14016
14017    /*
14018     * Return handling, calls through "glue code".
14019     */
14020     .if    0
14021.LreturnOld:
14022    SAVE_PC_FP_TO_GLUE()                @ export state
14023    mov     r0, rGLUE                   @ arg to function
14024    bl      dvmMterp_returnFromMethod
14025    b       common_resumeAfterGlueCall
14026    .endif
14027
14028
14029/*
14030 * Somebody has thrown an exception.  Handle it.
14031 *
14032 * If the exception processing code returns to us (instead of falling
14033 * out of the interpreter), continue with whatever the next instruction
14034 * now happens to be.
14035 *
14036 * This does not return.
14037 */
14038     .global dvmMterpCommonExceptionThrown
14039dvmMterpCommonExceptionThrown:
14040common_exceptionThrown:
14041.LexceptionNew:
14042    mov     r0, #kInterpEntryThrow
14043    mov     r9, #0
14044    bl      common_periodicChecks
14045
14046    ldr     r10, [rGLUE, #offGlue_self] @ r10<- glue->self
14047    ldr     r9, [r10, #offThread_exception] @ r9<- self->exception
14048    mov     r1, r10                     @ r1<- self
14049    mov     r0, r9                      @ r0<- exception
14050    bl      dvmAddTrackedAlloc          @ don't let the exception be GCed
14051    mov     r3, #0                      @ r3<- NULL
14052    str     r3, [r10, #offThread_exception] @ self->exception = NULL
14053
14054    /* set up args and a local for "&fp" */
14055    /* (str sp, [sp, #-4]!  would be perfect here, but is discouraged) */
14056    str     rFP, [sp, #-4]!             @ *--sp = fp
14057    mov     ip, sp                      @ ip<- &fp
14058    mov     r3, #0                      @ r3<- false
14059    str     ip, [sp, #-4]!              @ *--sp = &fp
14060    ldr     r1, [rGLUE, #offGlue_method] @ r1<- glue->method
14061    mov     r0, r10                     @ r0<- self
14062    ldr     r1, [r1, #offMethod_insns]  @ r1<- method->insns
14063    mov     r2, r9                      @ r2<- exception
14064    sub     r1, rPC, r1                 @ r1<- pc - method->insns
14065    mov     r1, r1, asr #1              @ r1<- offset in code units
14066
14067    /* call, r0 gets catchRelPc (a code-unit offset) */
14068    bl      dvmFindCatchBlock           @ call(self, relPc, exc, scan?, &fp)
14069
14070    /* fix earlier stack overflow if necessary; may trash rFP */
14071    ldrb    r1, [r10, #offThread_stackOverflowed]
14072    cmp     r1, #0                      @ did we overflow earlier?
14073    beq     1f                          @ no, skip ahead
14074    mov     rFP, r0                     @ save relPc result in rFP
14075    mov     r0, r10                     @ r0<- self
14076    mov     r1, r9                      @ r1<- exception
14077    bl      dvmCleanupStackOverflow     @ call(self)
14078    mov     r0, rFP                     @ restore result
140791:
14080
14081    /* update frame pointer and check result from dvmFindCatchBlock */
14082    ldr     rFP, [sp, #4]               @ retrieve the updated rFP
14083    cmp     r0, #0                      @ is catchRelPc < 0?
14084    add     sp, sp, #8                  @ restore stack
14085    bmi     .LnotCaughtLocally
14086
14087    /* adjust locals to match self->curFrame and updated PC */
14088    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- new save area
14089    ldr     r1, [r1, #offStackSaveArea_method] @ r1<- new method
14090    str     r1, [rGLUE, #offGlue_method]    @ glue->method = new method
14091    ldr     r2, [r1, #offMethod_clazz]      @ r2<- method->clazz
14092    ldr     r3, [r1, #offMethod_insns]      @ r3<- method->insns
14093    ldr     r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex
14094    add     rPC, r3, r0, asl #1             @ rPC<- method->insns + catchRelPc
14095    str     r2, [rGLUE, #offGlue_methodClassDex] @ glue->pDvmDex = meth...
14096
14097    /* release the tracked alloc on the exception */
14098    mov     r0, r9                      @ r0<- exception
14099    mov     r1, r10                     @ r1<- self
14100    bl      dvmReleaseTrackedAlloc      @ release the exception
14101
14102    /* restore the exception if the handler wants it */
14103    FETCH_INST()                        @ load rINST from rPC
14104    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14105    cmp     ip, #OP_MOVE_EXCEPTION      @ is it "move-exception"?
14106    streq   r9, [r10, #offThread_exception] @ yes, restore the exception
14107    GOTO_OPCODE(ip)                     @ jump to next instruction
14108
14109.LnotCaughtLocally: @ r9=exception, r10=self
14110    /* fix stack overflow if necessary */
14111    ldrb    r1, [r10, #offThread_stackOverflowed]
14112    cmp     r1, #0                      @ did we overflow earlier?
14113    movne   r0, r10                     @ if yes: r0<- self
14114    movne   r1, r9                      @ if yes: r1<- exception
14115    blne    dvmCleanupStackOverflow     @ if yes: call(self)
14116
14117    @ may want to show "not caught locally" debug messages here
14118#if DVM_SHOW_EXCEPTION >= 2
14119    /* call __android_log_print(prio, tag, format, ...) */
14120    /* "Exception %s from %s:%d not caught locally" */
14121    @ dvmLineNumFromPC(method, pc - method->insns)
14122    ldr     r0, [rGLUE, #offGlue_method]
14123    ldr     r1, [r0, #offMethod_insns]
14124    sub     r1, rPC, r1
14125    asr     r1, r1, #1
14126    bl      dvmLineNumFromPC
14127    str     r0, [sp, #-4]!
14128    @ dvmGetMethodSourceFile(method)
14129    ldr     r0, [rGLUE, #offGlue_method]
14130    bl      dvmGetMethodSourceFile
14131    str     r0, [sp, #-4]!
14132    @ exception->clazz->descriptor
14133    ldr     r3, [r9, #offObject_clazz]
14134    ldr     r3, [r3, #offClassObject_descriptor]
14135    @
14136    ldr     r2, strExceptionNotCaughtLocally
14137    ldr     r1, strLogTag
14138    mov     r0, #3                      @ LOG_DEBUG
14139    bl      __android_log_print
14140#endif
14141    str     r9, [r10, #offThread_exception] @ restore exception
14142    mov     r0, r9                      @ r0<- exception
14143    mov     r1, r10                     @ r1<- self
14144    bl      dvmReleaseTrackedAlloc      @ release the exception
14145    mov     r1, #0                      @ "want switch" = false
14146    b       common_gotoBail             @ bail out
14147
14148
14149    /*
14150     * Exception handling, calls through "glue code".
14151     */
14152    .if     0
14153.LexceptionOld:
14154    SAVE_PC_FP_TO_GLUE()                @ export state
14155    mov     r0, rGLUE                   @ arg to function
14156    bl      dvmMterp_exceptionThrown
14157    b       common_resumeAfterGlueCall
14158    .endif
14159
14160
14161/*
14162 * After returning from a "glued" function, pull out the updated
14163 * values and start executing at the next instruction.
14164 */
14165common_resumeAfterGlueCall:
14166    LOAD_PC_FP_FROM_GLUE()              @ pull rPC and rFP out of glue
14167    FETCH_INST()                        @ load rINST from rPC
14168    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14169    GOTO_OPCODE(ip)                     @ jump to next instruction
14170
14171/*
14172 * Invalid array index. Note that our calling convention is strange; we use r1
14173 * and r3 because those just happen to be the registers all our callers are
14174 * using. We shuffle them here before calling the C function.
14175 * r1: index
14176 * r3: size
14177 */
14178common_errArrayIndex:
14179    EXPORT_PC()
14180    mov     r0, r1
14181    mov     r1, r3
14182    bl      dvmThrowAIOOBE
14183    b       common_exceptionThrown
14184
14185/*
14186 * Integer divide or mod by zero.
14187 */
14188common_errDivideByZero:
14189    EXPORT_PC()
14190    ldr     r0, strArithmeticException
14191    ldr     r1, strDivideByZero
14192    bl      dvmThrowException
14193    b       common_exceptionThrown
14194
14195/*
14196 * Attempt to allocate an array with a negative size.
14197 */
14198common_errNegativeArraySize:
14199    EXPORT_PC()
14200    ldr     r0, strNegativeArraySizeException
14201    mov     r1, #0
14202    bl      dvmThrowException
14203    b       common_exceptionThrown
14204
14205/*
14206 * Invocation of a non-existent method.
14207 */
14208common_errNoSuchMethod:
14209    EXPORT_PC()
14210    ldr     r0, strNoSuchMethodError
14211    mov     r1, #0
14212    bl      dvmThrowException
14213    b       common_exceptionThrown
14214
14215/*
14216 * We encountered a null object when we weren't expecting one.  We
14217 * export the PC, throw a NullPointerException, and goto the exception
14218 * processing code.
14219 */
14220common_errNullObject:
14221    EXPORT_PC()
14222    ldr     r0, strNullPointerException
14223    mov     r1, #0
14224    bl      dvmThrowException
14225    b       common_exceptionThrown
14226
14227/*
14228 * For debugging, cause an immediate fault.  The source address will
14229 * be in lr (use a bl instruction to jump here).
14230 */
14231common_abort:
14232    ldr     pc, .LdeadFood
14233.LdeadFood:
14234    .word   0xdeadf00d
14235
14236/*
14237 * Spit out a "we were here", preserving all registers.  (The attempt
14238 * to save ip won't work, but we need to save an even number of
14239 * registers for EABI 64-bit stack alignment.)
14240 */
14241    .macro  SQUEAK num
14242common_squeak\num:
14243    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14244    ldr     r0, strSqueak
14245    mov     r1, #\num
14246    bl      printf
14247    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14248    bx      lr
14249    .endm
14250
14251    SQUEAK  0
14252    SQUEAK  1
14253    SQUEAK  2
14254    SQUEAK  3
14255    SQUEAK  4
14256    SQUEAK  5
14257
14258/*
14259 * Spit out the number in r0, preserving registers.
14260 */
14261common_printNum:
14262    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14263    mov     r1, r0
14264    ldr     r0, strSqueak
14265    bl      printf
14266    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14267    bx      lr
14268
14269/*
14270 * Print a newline, preserving registers.
14271 */
14272common_printNewline:
14273    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14274    ldr     r0, strNewline
14275    bl      printf
14276    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14277    bx      lr
14278
14279    /*
14280     * Print the 32-bit quantity in r0 as a hex value, preserving registers.
14281     */
14282common_printHex:
14283    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14284    mov     r1, r0
14285    ldr     r0, strPrintHex
14286    bl      printf
14287    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14288    bx      lr
14289
14290/*
14291 * Print the 64-bit quantity in r0-r1, preserving registers.
14292 */
14293common_printLong:
14294    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14295    mov     r3, r1
14296    mov     r2, r0
14297    ldr     r0, strPrintLong
14298    bl      printf
14299    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14300    bx      lr
14301
14302/*
14303 * Print full method info.  Pass the Method* in r0.  Preserves regs.
14304 */
14305common_printMethod:
14306    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14307    bl      dvmMterpPrintMethod
14308    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14309    bx      lr
14310
14311/*
14312 * Call a C helper function that dumps regs and possibly some
14313 * additional info.  Requires the C function to be compiled in.
14314 */
14315    .if     0
14316common_dumpRegs:
14317    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14318    bl      dvmMterpDumpArmRegs
14319    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14320    bx      lr
14321    .endif
14322
14323#if 0
14324/*
14325 * Experiment on VFP mode.
14326 *
14327 * uint32_t setFPSCR(uint32_t val, uint32_t mask)
14328 *
14329 * Updates the bits specified by "mask", setting them to the values in "val".
14330 */
14331setFPSCR:
14332    and     r0, r0, r1                  @ make sure no stray bits are set
14333    fmrx    r2, fpscr                   @ get VFP reg
14334    mvn     r1, r1                      @ bit-invert mask
14335    and     r2, r2, r1                  @ clear masked bits
14336    orr     r2, r2, r0                  @ set specified bits
14337    fmxr    fpscr, r2                   @ set VFP reg
14338    mov     r0, r2                      @ return new value
14339    bx      lr
14340
14341    .align  2
14342    .global dvmConfigureFP
14343    .type   dvmConfigureFP, %function
14344dvmConfigureFP:
14345    stmfd   sp!, {ip, lr}
14346    /* 0x03000000 sets DN/FZ */
14347    /* 0x00009f00 clears the six exception enable flags */
14348    bl      common_squeak0
14349    mov     r0, #0x03000000             @ r0<- 0x03000000
14350    add     r1, r0, #0x9f00             @ r1<- 0x03009f00
14351    bl      setFPSCR
14352    ldmfd   sp!, {ip, pc}
14353#endif
14354
14355
14356/*
14357 * String references, must be close to the code that uses them.
14358 */
14359    .align  2
14360strArithmeticException:
14361    .word   .LstrArithmeticException
14362strDivideByZero:
14363    .word   .LstrDivideByZero
14364strNegativeArraySizeException:
14365    .word   .LstrNegativeArraySizeException
14366strNoSuchMethodError:
14367    .word   .LstrNoSuchMethodError
14368strNullPointerException:
14369    .word   .LstrNullPointerException
14370
14371strLogTag:
14372    .word   .LstrLogTag
14373strExceptionNotCaughtLocally:
14374    .word   .LstrExceptionNotCaughtLocally
14375
14376strNewline:
14377    .word   .LstrNewline
14378strSqueak:
14379    .word   .LstrSqueak
14380strPrintHex:
14381    .word   .LstrPrintHex
14382strPrintLong:
14383    .word   .LstrPrintLong
14384
14385/*
14386 * Zero-terminated ASCII string data.
14387 *
14388 * On ARM we have two choices: do like gcc does, and LDR from a .word
14389 * with the address, or use an ADR pseudo-op to get the address
14390 * directly.  ADR saves 4 bytes and an indirection, but it's using a
14391 * PC-relative addressing mode and hence has a limited range, which
14392 * makes it not work well with mergeable string sections.
14393 */
14394    .section .rodata.str1.4,"aMS",%progbits,1
14395
14396.LstrBadEntryPoint:
14397    .asciz  "Bad entry point %d\n"
14398.LstrArithmeticException:
14399    .asciz  "Ljava/lang/ArithmeticException;"
14400.LstrDivideByZero:
14401    .asciz  "divide by zero"
14402.LstrFilledNewArrayNotImpl:
14403    .asciz  "filled-new-array only implemented for objects and 'int'"
14404.LstrInternalError:
14405    .asciz  "Ljava/lang/InternalError;"
14406.LstrInstantiationError:
14407    .asciz  "Ljava/lang/InstantiationError;"
14408.LstrNegativeArraySizeException:
14409    .asciz  "Ljava/lang/NegativeArraySizeException;"
14410.LstrNoSuchMethodError:
14411    .asciz  "Ljava/lang/NoSuchMethodError;"
14412.LstrNullPointerException:
14413    .asciz  "Ljava/lang/NullPointerException;"
14414
14415.LstrLogTag:
14416    .asciz  "mterp"
14417.LstrExceptionNotCaughtLocally:
14418    .asciz  "Exception %s from %s:%d not caught locally\n"
14419
14420.LstrNewline:
14421    .asciz  "\n"
14422.LstrSqueak:
14423    .asciz  "<%d>"
14424.LstrPrintHex:
14425    .asciz  "<0x%x>"
14426.LstrPrintLong:
14427    .asciz  "<%lld>"
14428
14429