InterpAsm-armv5te-vfp.S revision b387fe1b970a216c09d2abc98c893ff1fff3e512
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 is a no-op in a "standard" interpreter.
7416     */
7417    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
7418    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
7419    GOTO_OPCODE(ip)                     @ execute it
7420
7421/* ------------------------------ */
7422    .balign 64
7423.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */
7424/* File: armv5te/OP_RETURN_VOID_BARRIER.S */
7425    SMP_DMB_ST
7426    b       common_returnFromMethod
7427
7428/* ------------------------------ */
7429    .balign 64
7430.L_OP_IGET_QUICK: /* 0xf2 */
7431/* File: armv5te/OP_IGET_QUICK.S */
7432    /* For: iget-quick, iget-object-quick */
7433    /* op vA, vB, offset@CCCC */
7434    mov     r2, rINST, lsr #12          @ r2<- B
7435    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7436    FETCH(r1, 1)                        @ r1<- field byte offset
7437    cmp     r3, #0                      @ check object for null
7438    mov     r2, rINST, lsr #8           @ r2<- A(+)
7439    beq     common_errNullObject        @ object was null
7440    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7441    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7442    and     r2, r2, #15
7443    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7444    SET_VREG(r0, r2)                    @ fp[A]<- r0
7445    GOTO_OPCODE(ip)                     @ jump to next instruction
7446
7447/* ------------------------------ */
7448    .balign 64
7449.L_OP_IGET_WIDE_QUICK: /* 0xf3 */
7450/* File: armv5te/OP_IGET_WIDE_QUICK.S */
7451    /* iget-wide-quick vA, vB, offset@CCCC */
7452    mov     r2, rINST, lsr #12          @ r2<- B
7453    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7454    FETCH(ip, 1)                        @ ip<- field byte offset
7455    cmp     r3, #0                      @ check object for null
7456    mov     r2, rINST, lsr #8           @ r2<- A(+)
7457    beq     common_errNullObject        @ object was null
7458    ldrd    r0, [r3, ip]                @ r0<- obj.field (64 bits, aligned)
7459    and     r2, r2, #15
7460    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7461    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
7462    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7463    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
7464    GOTO_OPCODE(ip)                     @ jump to next instruction
7465
7466/* ------------------------------ */
7467    .balign 64
7468.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */
7469/* File: armv5te/OP_IGET_OBJECT_QUICK.S */
7470/* File: armv5te/OP_IGET_QUICK.S */
7471    /* For: iget-quick, iget-object-quick */
7472    /* op vA, vB, offset@CCCC */
7473    mov     r2, rINST, lsr #12          @ r2<- B
7474    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7475    FETCH(r1, 1)                        @ r1<- field byte offset
7476    cmp     r3, #0                      @ check object for null
7477    mov     r2, rINST, lsr #8           @ r2<- A(+)
7478    beq     common_errNullObject        @ object was null
7479    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7480    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7481    and     r2, r2, #15
7482    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7483    SET_VREG(r0, r2)                    @ fp[A]<- r0
7484    GOTO_OPCODE(ip)                     @ jump to next instruction
7485
7486
7487/* ------------------------------ */
7488    .balign 64
7489.L_OP_IPUT_QUICK: /* 0xf5 */
7490/* File: armv5te/OP_IPUT_QUICK.S */
7491    /* For: iput-quick */
7492    /* op vA, vB, offset@CCCC */
7493    mov     r2, rINST, lsr #12          @ r2<- B
7494    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7495    FETCH(r1, 1)                        @ r1<- field byte offset
7496    cmp     r3, #0                      @ check object for null
7497    mov     r2, rINST, lsr #8           @ r2<- A(+)
7498    beq     common_errNullObject        @ object was null
7499    and     r2, r2, #15
7500    GET_VREG(r0, r2)                    @ r0<- fp[A]
7501    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7502    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7503    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7504    GOTO_OPCODE(ip)                     @ jump to next instruction
7505
7506/* ------------------------------ */
7507    .balign 64
7508.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */
7509/* File: armv5te/OP_IPUT_WIDE_QUICK.S */
7510    /* iput-wide-quick vA, vB, offset@CCCC */
7511    mov     r0, rINST, lsr #8           @ r0<- A(+)
7512    mov     r1, rINST, lsr #12          @ r1<- B
7513    and     r0, r0, #15
7514    GET_VREG(r2, r1)                    @ r2<- fp[B], the object pointer
7515    add     r3, rFP, r0, lsl #2         @ r3<- &fp[A]
7516    cmp     r2, #0                      @ check object for null
7517    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[A]
7518    beq     common_errNullObject        @ object was null
7519    FETCH(r3, 1)                        @ r3<- field byte offset
7520    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7521    strd    r0, [r2, r3]                @ obj.field (64 bits, aligned)<- r0/r1
7522    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7523    GOTO_OPCODE(ip)                     @ jump to next instruction
7524
7525/* ------------------------------ */
7526    .balign 64
7527.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
7528/* File: armv5te/OP_IPUT_OBJECT_QUICK.S */
7529    /* For: iput-object-quick */
7530    /* op vA, vB, offset@CCCC */
7531    mov     r2, rINST, lsr #12          @ r2<- B
7532    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7533    FETCH(r1, 1)                        @ r1<- field byte offset
7534    cmp     r3, #0                      @ check object for null
7535    mov     r2, rINST, lsr #8           @ r2<- A(+)
7536    beq     common_errNullObject        @ object was null
7537    and     r2, r2, #15
7538    GET_VREG(r0, r2)                    @ r0<- fp[A]
7539    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
7540    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7541    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7542    cmp     r0, #0
7543    strneb  r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head
7544    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7545    GOTO_OPCODE(ip)                     @ jump to next instruction
7546
7547/* ------------------------------ */
7548    .balign 64
7549.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
7550/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7551    /*
7552     * Handle an optimized virtual method call.
7553     *
7554     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7555     */
7556    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7557    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7558    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7559    FETCH(r1, 1)                        @ r1<- BBBB
7560    .if     (!0)
7561    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7562    .endif
7563    GET_VREG(r2, r3)                    @ r2<- vC ("this" ptr)
7564    cmp     r2, #0                      @ is "this" null?
7565    beq     common_errNullObject        @ null "this", throw exception
7566    ldr     r2, [r2, #offObject_clazz]  @ r2<- thisPtr->clazz
7567    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7568    EXPORT_PC()                         @ invoke must export
7569    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7570    bl      common_invokeMethodNoRange @ continue on
7571
7572/* ------------------------------ */
7573    .balign 64
7574.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
7575/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */
7576/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7577    /*
7578     * Handle an optimized virtual method call.
7579     *
7580     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7581     */
7582    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7583    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7584    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7585    FETCH(r1, 1)                        @ r1<- BBBB
7586    .if     (!1)
7587    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7588    .endif
7589    GET_VREG(r2, r3)                    @ r2<- vC ("this" ptr)
7590    cmp     r2, #0                      @ is "this" null?
7591    beq     common_errNullObject        @ null "this", throw exception
7592    ldr     r2, [r2, #offObject_clazz]  @ r2<- thisPtr->clazz
7593    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7594    EXPORT_PC()                         @ invoke must export
7595    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7596    bl      common_invokeMethodRange @ continue on
7597
7598
7599/* ------------------------------ */
7600    .balign 64
7601.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */
7602/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7603    /*
7604     * Handle an optimized "super" method call.
7605     *
7606     * for: [opt] invoke-super-quick, invoke-super-quick/range
7607     */
7608    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7609    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7610    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7611    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7612    .if     (!0)
7613    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7614    .endif
7615    FETCH(r1, 1)                        @ r1<- BBBB
7616    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7617    EXPORT_PC()                         @ must export for invoke
7618    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7619    GET_VREG(r3, r10)                   @ r3<- "this"
7620    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7621    cmp     r3, #0                      @ null "this" ref?
7622    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7623    beq     common_errNullObject        @ "this" is null, throw exception
7624    bl      common_invokeMethodNoRange @ continue on
7625
7626/* ------------------------------ */
7627    .balign 64
7628.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
7629/* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */
7630/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7631    /*
7632     * Handle an optimized "super" method call.
7633     *
7634     * for: [opt] invoke-super-quick, invoke-super-quick/range
7635     */
7636    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7637    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7638    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7639    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7640    .if     (!1)
7641    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7642    .endif
7643    FETCH(r1, 1)                        @ r1<- BBBB
7644    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7645    EXPORT_PC()                         @ must export for invoke
7646    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7647    GET_VREG(r3, r10)                   @ r3<- "this"
7648    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7649    cmp     r3, #0                      @ null "this" ref?
7650    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7651    beq     common_errNullObject        @ "this" is null, throw exception
7652    bl      common_invokeMethodRange @ continue on
7653
7654
7655/* ------------------------------ */
7656    .balign 64
7657.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
7658/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */
7659/* File: armv5te/OP_IPUT_OBJECT.S */
7660    /*
7661     * 32-bit instance field put.
7662     *
7663     * for: iput-object, iput-object-volatile
7664     */
7665    /* op vA, vB, field@CCCC */
7666    mov     r0, rINST, lsr #12          @ r0<- B
7667    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7668    FETCH(r1, 1)                        @ r1<- field ref CCCC
7669    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7670    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7671    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7672    cmp     r0, #0                      @ is resolved entry null?
7673    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ no, already resolved
76748:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7675    EXPORT_PC()                         @ resolve() could throw
7676    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7677    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7678    cmp     r0, #0                      @ success?
7679    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ yes, finish up
7680    b       common_exceptionThrown
7681
7682
7683/* ------------------------------ */
7684    .balign 64
7685.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
7686/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */
7687/* File: armv5te/OP_SGET.S */
7688    /*
7689     * General 32-bit SGET handler.
7690     *
7691     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7692     */
7693    /* op vAA, field@BBBB */
7694    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7695    FETCH(r1, 1)                        @ r1<- field ref BBBB
7696    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7697    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7698    cmp     r0, #0                      @ is resolved entry null?
7699    beq     .LOP_SGET_OBJECT_VOLATILE_resolve         @ yes, do resolve
7700.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0
7701    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7702    SMP_DMB                            @ acquiring load
7703    mov     r2, rINST, lsr #8           @ r2<- AA
7704    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7705    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7706    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7707    GOTO_OPCODE(ip)                     @ jump to next instruction
7708
7709
7710/* ------------------------------ */
7711    .balign 64
7712.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
7713/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */
7714/* File: armv5te/OP_SPUT_OBJECT.S */
7715    /*
7716     * 32-bit SPUT handler for objects
7717     *
7718     * for: sput-object, sput-object-volatile
7719     */
7720    /* op vAA, field@BBBB */
7721    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
7722    FETCH(r1, 1)                        @ r1<- field ref BBBB
7723    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7724    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7725    cmp     r0, #0                      @ is resolved entry null?
7726    bne     .LOP_SPUT_OBJECT_VOLATILE_finish          @ no, continue
7727    ldr     r9, [rGLUE, #offGlue_method]    @ r9<- current method
7728    EXPORT_PC()                         @ resolve() could throw, so export now
7729    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
7730    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
7731    cmp     r0, #0                      @ success?
7732    bne     .LOP_SPUT_OBJECT_VOLATILE_finish          @ yes, finish
7733    b       common_exceptionThrown      @ no, handle exception
7734
7735
7736
7737/* ------------------------------ */
7738    .balign 64
7739.L_OP_DISPATCH_FF: /* 0xff */
7740/* File: armv5te/OP_DISPATCH_FF.S */
7741    mov     ip, rINST, lsr #8           @ r9<- extended opcode
7742    add     ip, ip, #256                @ add offset for extended opcodes
7743    GOTO_OPCODE(ip)                     @ go to proper extended handler
7744
7745
7746/* ------------------------------ */
7747    .balign 64
7748.L_OP_CONST_CLASS_JUMBO: /* 0x100 */
7749/* File: armv5te/OP_CONST_CLASS_JUMBO.S */
7750    /* const-class/jumbo vBBBB, Class@AAAAAAAA */
7751    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7752    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- glue->methodClassDex
7753    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7754    ldr     r2, [r2, #offDvmDex_pResClasses]   @ r2<- dvmDex->pResClasses
7755    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7756    FETCH(r9, 3)                        @ r9<- BBBB
7757    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResClasses[AAAAaaaa]
7758    cmp     r0, #0                      @ not yet resolved?
7759    beq     .LOP_CONST_CLASS_JUMBO_resolve
7760    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
7761    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7762    SET_VREG(r0, r9)                    @ vBBBB<- r0
7763    GOTO_OPCODE(ip)                     @ jump to next instruction
7764
7765/* ------------------------------ */
7766    .balign 64
7767.L_OP_CHECK_CAST_JUMBO: /* 0x101 */
7768/* File: armv5te/OP_CHECK_CAST_JUMBO.S */
7769    /*
7770     * Check to see if a cast from one class to another is allowed.
7771     */
7772    /* check-cast/jumbo vBBBB, class@AAAAAAAA */
7773    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7774    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7775    FETCH(r3, 3)                        @ r3<- BBBB
7776    orr     r2, r0, r2, lsl #16         @ r2<- AAAAaaaa
7777    GET_VREG(r9, r3)                    @ r9<- object
7778    ldr     r0, [rGLUE, #offGlue_methodClassDex]    @ r0<- pDvmDex
7779    cmp     r9, #0                      @ is object null?
7780    ldr     r0, [r0, #offDvmDex_pResClasses]    @ r0<- pDvmDex->pResClasses
7781    beq     .LOP_CHECK_CAST_JUMBO_okay            @ null obj, cast always succeeds
7782    ldr     r1, [r0, r2, lsl #2]        @ r1<- resolved class
7783    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
7784    cmp     r1, #0                      @ have we resolved this before?
7785    beq     .LOP_CHECK_CAST_JUMBO_resolve         @ not resolved, do it now
7786.LOP_CHECK_CAST_JUMBO_resolved:
7787    cmp     r0, r1                      @ same class (trivial success)?
7788    bne     .LOP_CHECK_CAST_JUMBO_fullcheck       @ no, do full check
7789    b       .LOP_CHECK_CAST_JUMBO_okay            @ yes, finish up
7790
7791/* ------------------------------ */
7792    .balign 64
7793.L_OP_INSTANCE_OF_JUMBO: /* 0x102 */
7794/* File: armv5te/OP_INSTANCE_OF_JUMBO.S */
7795    /*
7796     * Check to see if an object reference is an instance of a class.
7797     *
7798     * Most common situation is a non-null object, being compared against
7799     * an already-resolved class.
7800     *
7801     * TODO: convert most of this into a common subroutine, shared with
7802     *       OP_INSTANCE_OF.S.
7803     */
7804    /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */
7805    FETCH(r3, 4)                        @ r3<- vCCCC
7806    FETCH(r9, 3)                        @ r9<- vBBBB
7807    GET_VREG(r0, r3)                    @ r0<- vCCCC (object)
7808    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- pDvmDex
7809    cmp     r0, #0                      @ is object null?
7810    beq     .LOP_INSTANCE_OF_JUMBO_store           @ null obj, not an instance, store r0
7811    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7812    FETCH(r3, 2)                        @ r3<- AAAA (hi)
7813    ldr     r2, [r2, #offDvmDex_pResClasses]    @ r2<- pDvmDex->pResClasses
7814    orr     r3, r1, r3, lsl #16         @ r3<- AAAAaaaa
7815    ldr     r1, [r2, r3, lsl #2]        @ r1<- resolved class
7816    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
7817    cmp     r1, #0                      @ have we resolved this before?
7818    beq     .LOP_INSTANCE_OF_JUMBO_resolve         @ not resolved, do it now
7819    b       .LOP_INSTANCE_OF_JUMBO_resolved        @ resolved, continue
7820
7821/* ------------------------------ */
7822    .balign 64
7823.L_OP_NEW_INSTANCE_JUMBO: /* 0x103 */
7824/* File: armv5te/OP_NEW_INSTANCE_JUMBO.S */
7825    /*
7826     * Create a new instance of a class.
7827     */
7828    /* new-instance/jumbo vBBBB, class@AAAAAAAA */
7829    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7830    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7831    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
7832    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7833    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7834    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
7835    EXPORT_PC()                         @ req'd for init, resolve, alloc
7836    cmp     r0, #0                      @ already resolved?
7837    beq     .LOP_NEW_INSTANCE_JUMBO_resolve         @ no, resolve it now
7838.LOP_NEW_INSTANCE_JUMBO_resolved:   @ r0=class
7839    ldrb    r1, [r0, #offClassObject_status]    @ r1<- ClassStatus enum
7840    cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
7841    bne     .LOP_NEW_INSTANCE_JUMBO_needinit        @ no, init class now
7842.LOP_NEW_INSTANCE_JUMBO_initialized: @ r0=class
7843    mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
7844    bl      dvmAllocObject              @ r0<- new object
7845    b       .LOP_NEW_INSTANCE_JUMBO_finish          @ continue
7846
7847/* ------------------------------ */
7848    .balign 64
7849.L_OP_NEW_ARRAY_JUMBO: /* 0x104 */
7850/* File: armv5te/OP_NEW_ARRAY_JUMBO.S */
7851    /*
7852     * Allocate an array of objects, specified with the array class
7853     * and a count.
7854     *
7855     * The verifier guarantees that this is an array class, so we don't
7856     * check for it here.
7857     */
7858    /* new-array/jumbo vBBBB, vCCCC, class@AAAAAAAA */
7859    FETCH(r2, 1)                        @ r2<- aaaa (lo)
7860    FETCH(r3, 2)                        @ r3<- AAAA (hi)
7861    FETCH(r0, 4)                        @ r0<- vCCCC
7862    orr     r2, r2, r3, lsl #16         @ r2<- AAAAaaaa
7863    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
7864    GET_VREG(r1, r0)                    @ r1<- vCCCC (array length)
7865    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7866    cmp     r1, #0                      @ check length
7867    ldr     r0, [r3, r2, lsl #2]        @ r0<- resolved class
7868    bmi     common_errNegativeArraySize @ negative length, bail
7869    cmp     r0, #0                      @ already resolved?
7870    EXPORT_PC()                         @ req'd for resolve, alloc
7871    bne     .LOP_NEW_ARRAY_JUMBO_finish          @ resolved, continue
7872    b       .LOP_NEW_ARRAY_JUMBO_resolve         @ do resolve now
7873
7874/* ------------------------------ */
7875    .balign 64
7876.L_OP_FILLED_NEW_ARRAY_JUMBO: /* 0x105 */
7877/* File: armv5te/OP_FILLED_NEW_ARRAY_JUMBO.S */
7878    /*
7879     * Create a new array with elements filled from registers.
7880     *
7881     * TODO: convert most of this into a common subroutine, shared with
7882     *       OP_FILLED_NEW_ARRAY.S.
7883     */
7884    /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */
7885    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
7886    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7887    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7888    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7889    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7890    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
7891    EXPORT_PC()                         @ need for resolve and alloc
7892    cmp     r0, #0                      @ already resolved?
7893    bne     .LOP_FILLED_NEW_ARRAY_JUMBO_continue        @ yes, continue on
78948:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
7895    mov     r2, #0                      @ r2<- false
7896    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
7897    bl      dvmResolveClass             @ r0<- call(clazz, ref)
7898    cmp     r0, #0                      @ got null?
7899    beq     common_exceptionThrown      @ yes, handle exception
7900    b       .LOP_FILLED_NEW_ARRAY_JUMBO_continue
7901
7902/* ------------------------------ */
7903    .balign 64
7904.L_OP_IGET_JUMBO: /* 0x106 */
7905/* File: armv5te/OP_IGET_JUMBO.S */
7906    /*
7907     * Jumbo 32-bit instance field get.
7908     *
7909     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7910     *      iget-char/jumbo, iget-short/jumbo
7911     */
7912    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7913    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7914    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7915    FETCH(r0, 4)                        @ r0<- CCCC
7916    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7917    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7918    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7919    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7920    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7921    cmp     r0, #0                      @ is resolved entry null?
7922    bne     .LOP_IGET_JUMBO_finish          @ no, already resolved
79238:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7924    EXPORT_PC()                         @ resolve() could throw
7925    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7926    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7927    b       .LOP_IGET_JUMBO_resolved        @ resolved, continue
7928
7929/* ------------------------------ */
7930    .balign 64
7931.L_OP_IGET_WIDE_JUMBO: /* 0x107 */
7932/* File: armv5te/OP_IGET_WIDE_JUMBO.S */
7933    /*
7934     * Jumbo 64-bit instance field get.
7935     */
7936    /* iget-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
7937    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7938    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7939    FETCH(r0, 4)                        @ r0<- CCCC
7940    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7941    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7942    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7943    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7944    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7945    cmp     r0, #0                      @ is resolved entry null?
7946    bne     .LOP_IGET_WIDE_JUMBO_finish          @ no, already resolved
79478:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
7948    EXPORT_PC()                         @ resolve() could throw
7949    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7950    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7951    b       .LOP_IGET_WIDE_JUMBO_resolved        @ resolved, continue
7952
7953/* ------------------------------ */
7954    .balign 64
7955.L_OP_IGET_OBJECT_JUMBO: /* 0x108 */
7956/* File: armv5te/OP_IGET_OBJECT_JUMBO.S */
7957/* File: armv5te/OP_IGET_JUMBO.S */
7958    /*
7959     * Jumbo 32-bit instance field get.
7960     *
7961     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7962     *      iget-char/jumbo, iget-short/jumbo
7963     */
7964    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7965    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7966    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7967    FETCH(r0, 4)                        @ r0<- CCCC
7968    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7969    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7970    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7971    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7972    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7973    cmp     r0, #0                      @ is resolved entry null?
7974    bne     .LOP_IGET_OBJECT_JUMBO_finish          @ no, already resolved
79758:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
7976    EXPORT_PC()                         @ resolve() could throw
7977    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7978    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7979    b       .LOP_IGET_OBJECT_JUMBO_resolved        @ resolved, continue
7980
7981
7982/* ------------------------------ */
7983    .balign 64
7984.L_OP_IGET_BOOLEAN_JUMBO: /* 0x109 */
7985/* File: armv5te/OP_IGET_BOOLEAN_JUMBO.S */
7986@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrb", "sqnum":"1" }
7987/* File: armv5te/OP_IGET_JUMBO.S */
7988    /*
7989     * Jumbo 32-bit instance field get.
7990     *
7991     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7992     *      iget-char/jumbo, iget-short/jumbo
7993     */
7994    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7995    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7996    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7997    FETCH(r0, 4)                        @ r0<- CCCC
7998    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
7999    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8000    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8001    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8002    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8003    cmp     r0, #0                      @ is resolved entry null?
8004    bne     .LOP_IGET_BOOLEAN_JUMBO_finish          @ no, already resolved
80058:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8006    EXPORT_PC()                         @ resolve() could throw
8007    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8008    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8009    b       .LOP_IGET_BOOLEAN_JUMBO_resolved        @ resolved, continue
8010
8011
8012/* ------------------------------ */
8013    .balign 64
8014.L_OP_IGET_BYTE_JUMBO: /* 0x10a */
8015/* File: armv5te/OP_IGET_BYTE_JUMBO.S */
8016@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsb", "sqnum":"2" }
8017/* File: armv5te/OP_IGET_JUMBO.S */
8018    /*
8019     * Jumbo 32-bit instance field get.
8020     *
8021     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8022     *      iget-char/jumbo, iget-short/jumbo
8023     */
8024    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8025    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8026    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8027    FETCH(r0, 4)                        @ r0<- CCCC
8028    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8029    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8030    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8031    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8032    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8033    cmp     r0, #0                      @ is resolved entry null?
8034    bne     .LOP_IGET_BYTE_JUMBO_finish          @ no, already resolved
80358:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8036    EXPORT_PC()                         @ resolve() could throw
8037    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8038    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8039    b       .LOP_IGET_BYTE_JUMBO_resolved        @ resolved, continue
8040
8041
8042/* ------------------------------ */
8043    .balign 64
8044.L_OP_IGET_CHAR_JUMBO: /* 0x10b */
8045/* File: armv5te/OP_IGET_CHAR_JUMBO.S */
8046@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrh", "sqnum":"3" }
8047/* File: armv5te/OP_IGET_JUMBO.S */
8048    /*
8049     * Jumbo 32-bit instance field get.
8050     *
8051     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8052     *      iget-char/jumbo, iget-short/jumbo
8053     */
8054    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8055    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8056    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8057    FETCH(r0, 4)                        @ r0<- CCCC
8058    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8059    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8060    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8061    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8062    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8063    cmp     r0, #0                      @ is resolved entry null?
8064    bne     .LOP_IGET_CHAR_JUMBO_finish          @ no, already resolved
80658:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8066    EXPORT_PC()                         @ resolve() could throw
8067    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8068    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8069    b       .LOP_IGET_CHAR_JUMBO_resolved        @ resolved, continue
8070
8071
8072/* ------------------------------ */
8073    .balign 64
8074.L_OP_IGET_SHORT_JUMBO: /* 0x10c */
8075/* File: armv5te/OP_IGET_SHORT_JUMBO.S */
8076@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsh", "sqnum":"4" }
8077/* File: armv5te/OP_IGET_JUMBO.S */
8078    /*
8079     * Jumbo 32-bit instance field get.
8080     *
8081     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8082     *      iget-char/jumbo, iget-short/jumbo
8083     */
8084    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8085    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8086    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8087    FETCH(r0, 4)                        @ r0<- CCCC
8088    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8089    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8090    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8091    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8092    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8093    cmp     r0, #0                      @ is resolved entry null?
8094    bne     .LOP_IGET_SHORT_JUMBO_finish          @ no, already resolved
80958:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8096    EXPORT_PC()                         @ resolve() could throw
8097    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8098    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8099    b       .LOP_IGET_SHORT_JUMBO_resolved        @ resolved, continue
8100
8101
8102/* ------------------------------ */
8103    .balign 64
8104.L_OP_IPUT_JUMBO: /* 0x10d */
8105/* File: armv5te/OP_IPUT_JUMBO.S */
8106    /*
8107     * Jumbo 32-bit instance field put.
8108     *
8109     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8110     *      iput-short/jumbo
8111     */
8112    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8113    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8114    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8115    FETCH(r0, 4)                        @ r0<- CCCC
8116    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8117    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8118    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8119    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8120    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8121    cmp     r0, #0                      @ is resolved entry null?
8122    bne     .LOP_IPUT_JUMBO_finish          @ no, already resolved
81238:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8124    EXPORT_PC()                         @ resolve() could throw
8125    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8126    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8127    b       .LOP_IPUT_JUMBO_resolved        @ resolved, continue
8128
8129/* ------------------------------ */
8130    .balign 64
8131.L_OP_IPUT_WIDE_JUMBO: /* 0x10e */
8132/* File: armv5te/OP_IPUT_WIDE_JUMBO.S */
8133    /* iput-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
8134    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8135    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8136    FETCH(r0, 4)                        @ r0<- CCCC
8137    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8138    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8139    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
8140    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
8141    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8142    cmp     r0, #0                      @ is resolved entry null?
8143    bne     .LOP_IPUT_WIDE_JUMBO_finish          @ no, already resolved
81448:  ldr     r2, [rGLUE, #offGlue_method] @ r2<- current method
8145    EXPORT_PC()                         @ resolve() could throw
8146    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8147    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8148    b       .LOP_IPUT_WIDE_JUMBO_resolved        @ resolved, continue
8149
8150/* ------------------------------ */
8151    .balign 64
8152.L_OP_IPUT_OBJECT_JUMBO: /* 0x10f */
8153/* File: armv5te/OP_IPUT_OBJECT_JUMBO.S */
8154    /*
8155     * Jumbo 32-bit instance field put.
8156     */
8157    /* iput-object/jumbo vBBBB, vCCCC, field@AAAAAAAA */
8158    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8159    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8160    FETCH(r0, 4)                        @ r0<- CCCC
8161    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8162    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8163    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8164    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8165    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8166    cmp     r0, #0                      @ is resolved entry null?
8167    bne     .LOP_IPUT_OBJECT_JUMBO_finish          @ no, already resolved
81688:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8169    EXPORT_PC()                         @ resolve() could throw
8170    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8171    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8172    b       .LOP_IPUT_OBJECT_JUMBO_resolved        @ resolved, continue
8173
8174/* ------------------------------ */
8175    .balign 64
8176.L_OP_IPUT_BOOLEAN_JUMBO: /* 0x110 */
8177/* File: armv5te/OP_IPUT_BOOLEAN_JUMBO.S */
8178@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"1" }
8179/* File: armv5te/OP_IPUT_JUMBO.S */
8180    /*
8181     * Jumbo 32-bit instance field put.
8182     *
8183     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8184     *      iput-short/jumbo
8185     */
8186    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8187    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8188    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8189    FETCH(r0, 4)                        @ r0<- CCCC
8190    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8191    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8192    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8193    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8194    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8195    cmp     r0, #0                      @ is resolved entry null?
8196    bne     .LOP_IPUT_BOOLEAN_JUMBO_finish          @ no, already resolved
81978:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8198    EXPORT_PC()                         @ resolve() could throw
8199    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8200    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8201    b       .LOP_IPUT_BOOLEAN_JUMBO_resolved        @ resolved, continue
8202
8203
8204/* ------------------------------ */
8205    .balign 64
8206.L_OP_IPUT_BYTE_JUMBO: /* 0x111 */
8207/* File: armv5te/OP_IPUT_BYTE_JUMBO.S */
8208@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"2" }
8209/* File: armv5te/OP_IPUT_JUMBO.S */
8210    /*
8211     * Jumbo 32-bit instance field put.
8212     *
8213     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8214     *      iput-short/jumbo
8215     */
8216    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8217    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8218    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8219    FETCH(r0, 4)                        @ r0<- CCCC
8220    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8221    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8222    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8223    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8224    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8225    cmp     r0, #0                      @ is resolved entry null?
8226    bne     .LOP_IPUT_BYTE_JUMBO_finish          @ no, already resolved
82278:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8228    EXPORT_PC()                         @ resolve() could throw
8229    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8230    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8231    b       .LOP_IPUT_BYTE_JUMBO_resolved        @ resolved, continue
8232
8233
8234/* ------------------------------ */
8235    .balign 64
8236.L_OP_IPUT_CHAR_JUMBO: /* 0x112 */
8237/* File: armv5te/OP_IPUT_CHAR_JUMBO.S */
8238@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"3" }
8239/* File: armv5te/OP_IPUT_JUMBO.S */
8240    /*
8241     * Jumbo 32-bit instance field put.
8242     *
8243     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8244     *      iput-short/jumbo
8245     */
8246    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8247    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8248    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8249    FETCH(r0, 4)                        @ r0<- CCCC
8250    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8251    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8252    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8253    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8254    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8255    cmp     r0, #0                      @ is resolved entry null?
8256    bne     .LOP_IPUT_CHAR_JUMBO_finish          @ no, already resolved
82578:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8258    EXPORT_PC()                         @ resolve() could throw
8259    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8260    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8261    b       .LOP_IPUT_CHAR_JUMBO_resolved        @ resolved, continue
8262
8263
8264/* ------------------------------ */
8265    .balign 64
8266.L_OP_IPUT_SHORT_JUMBO: /* 0x113 */
8267/* File: armv5te/OP_IPUT_SHORT_JUMBO.S */
8268@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"4" }
8269/* File: armv5te/OP_IPUT_JUMBO.S */
8270    /*
8271     * Jumbo 32-bit instance field put.
8272     *
8273     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8274     *      iput-short/jumbo
8275     */
8276    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8277    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8278    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8279    FETCH(r0, 4)                        @ r0<- CCCC
8280    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- DvmDex
8281    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8282    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8283    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8284    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8285    cmp     r0, #0                      @ is resolved entry null?
8286    bne     .LOP_IPUT_SHORT_JUMBO_finish          @ no, already resolved
82878:  ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
8288    EXPORT_PC()                         @ resolve() could throw
8289    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8290    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8291    b       .LOP_IPUT_SHORT_JUMBO_resolved        @ resolved, continue
8292
8293
8294/* ------------------------------ */
8295    .balign 64
8296.L_OP_SGET_JUMBO: /* 0x114 */
8297/* File: armv5te/OP_SGET_JUMBO.S */
8298    /*
8299     * Jumbo 32-bit SGET handler.
8300     *
8301     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8302     *      sget-char/jumbo, sget-short/jumbo
8303     */
8304    /* exop vBBBB, field@AAAAAAAA */
8305    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8306    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8307    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8308    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8309    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8310    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8311    cmp     r0, #0                      @ is resolved entry null?
8312    beq     .LOP_SGET_JUMBO_resolve         @ yes, do resolve
8313.LOP_SGET_JUMBO_finish: @ field ptr in r0
8314    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8315    @ no-op                             @ acquiring load
8316    FETCH(r2, 3)                        @ r2<- BBBB
8317    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8318    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8319    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8320    GOTO_OPCODE(ip)                     @ jump to next instruction
8321
8322/* ------------------------------ */
8323    .balign 64
8324.L_OP_SGET_WIDE_JUMBO: /* 0x115 */
8325/* File: armv5te/OP_SGET_WIDE_JUMBO.S */
8326    /*
8327     * Jumbo 64-bit SGET handler.
8328     */
8329    /* sget-wide/jumbo vBBBB, field@AAAAAAAA */
8330    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8331    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8332    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8333    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8334    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8335    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8336    cmp     r0, #0                      @ is resolved entry null?
8337    beq     .LOP_SGET_WIDE_JUMBO_resolve         @ yes, do resolve
8338.LOP_SGET_WIDE_JUMBO_finish:
8339    FETCH(r9, 3)                        @ r9<- BBBB
8340    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
8341    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BBBB]
8342    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8343    stmia   r9, {r0-r1}                 @ vBBBB/vBBBB+1<- r0/r1
8344    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8345    GOTO_OPCODE(ip)                     @ jump to next instruction
8346
8347/* ------------------------------ */
8348    .balign 64
8349.L_OP_SGET_OBJECT_JUMBO: /* 0x116 */
8350/* File: armv5te/OP_SGET_OBJECT_JUMBO.S */
8351/* File: armv5te/OP_SGET_JUMBO.S */
8352    /*
8353     * Jumbo 32-bit SGET handler.
8354     *
8355     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8356     *      sget-char/jumbo, sget-short/jumbo
8357     */
8358    /* exop vBBBB, field@AAAAAAAA */
8359    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8360    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8361    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8362    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8363    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8364    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8365    cmp     r0, #0                      @ is resolved entry null?
8366    beq     .LOP_SGET_OBJECT_JUMBO_resolve         @ yes, do resolve
8367.LOP_SGET_OBJECT_JUMBO_finish: @ field ptr in r0
8368    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8369    @ no-op                             @ acquiring load
8370    FETCH(r2, 3)                        @ r2<- BBBB
8371    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8372    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8373    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8374    GOTO_OPCODE(ip)                     @ jump to next instruction
8375
8376
8377/* ------------------------------ */
8378    .balign 64
8379.L_OP_SGET_BOOLEAN_JUMBO: /* 0x117 */
8380/* File: armv5te/OP_SGET_BOOLEAN_JUMBO.S */
8381/* File: armv5te/OP_SGET_JUMBO.S */
8382    /*
8383     * Jumbo 32-bit SGET handler.
8384     *
8385     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8386     *      sget-char/jumbo, sget-short/jumbo
8387     */
8388    /* exop vBBBB, field@AAAAAAAA */
8389    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8390    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8391    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8392    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8393    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8394    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8395    cmp     r0, #0                      @ is resolved entry null?
8396    beq     .LOP_SGET_BOOLEAN_JUMBO_resolve         @ yes, do resolve
8397.LOP_SGET_BOOLEAN_JUMBO_finish: @ field ptr in r0
8398    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8399    @ no-op                             @ acquiring load
8400    FETCH(r2, 3)                        @ r2<- BBBB
8401    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8402    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8403    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8404    GOTO_OPCODE(ip)                     @ jump to next instruction
8405
8406
8407/* ------------------------------ */
8408    .balign 64
8409.L_OP_SGET_BYTE_JUMBO: /* 0x118 */
8410/* File: armv5te/OP_SGET_BYTE_JUMBO.S */
8411/* File: armv5te/OP_SGET_JUMBO.S */
8412    /*
8413     * Jumbo 32-bit SGET handler.
8414     *
8415     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8416     *      sget-char/jumbo, sget-short/jumbo
8417     */
8418    /* exop vBBBB, field@AAAAAAAA */
8419    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8420    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8421    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8422    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8423    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8424    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8425    cmp     r0, #0                      @ is resolved entry null?
8426    beq     .LOP_SGET_BYTE_JUMBO_resolve         @ yes, do resolve
8427.LOP_SGET_BYTE_JUMBO_finish: @ field ptr in r0
8428    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8429    @ no-op                             @ acquiring load
8430    FETCH(r2, 3)                        @ r2<- BBBB
8431    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8432    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8433    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8434    GOTO_OPCODE(ip)                     @ jump to next instruction
8435
8436
8437/* ------------------------------ */
8438    .balign 64
8439.L_OP_SGET_CHAR_JUMBO: /* 0x119 */
8440/* File: armv5te/OP_SGET_CHAR_JUMBO.S */
8441/* File: armv5te/OP_SGET_JUMBO.S */
8442    /*
8443     * Jumbo 32-bit SGET handler.
8444     *
8445     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8446     *      sget-char/jumbo, sget-short/jumbo
8447     */
8448    /* exop vBBBB, field@AAAAAAAA */
8449    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8450    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8451    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8452    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8453    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8454    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8455    cmp     r0, #0                      @ is resolved entry null?
8456    beq     .LOP_SGET_CHAR_JUMBO_resolve         @ yes, do resolve
8457.LOP_SGET_CHAR_JUMBO_finish: @ field ptr in r0
8458    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8459    @ no-op                             @ acquiring load
8460    FETCH(r2, 3)                        @ r2<- BBBB
8461    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8462    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8463    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8464    GOTO_OPCODE(ip)                     @ jump to next instruction
8465
8466
8467/* ------------------------------ */
8468    .balign 64
8469.L_OP_SGET_SHORT_JUMBO: /* 0x11a */
8470/* File: armv5te/OP_SGET_SHORT_JUMBO.S */
8471/* File: armv5te/OP_SGET_JUMBO.S */
8472    /*
8473     * Jumbo 32-bit SGET handler.
8474     *
8475     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8476     *      sget-char/jumbo, sget-short/jumbo
8477     */
8478    /* exop vBBBB, field@AAAAAAAA */
8479    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8480    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8481    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8482    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8483    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8484    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8485    cmp     r0, #0                      @ is resolved entry null?
8486    beq     .LOP_SGET_SHORT_JUMBO_resolve         @ yes, do resolve
8487.LOP_SGET_SHORT_JUMBO_finish: @ field ptr in r0
8488    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8489    @ no-op                             @ acquiring load
8490    FETCH(r2, 3)                        @ r2<- BBBB
8491    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8492    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8493    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8494    GOTO_OPCODE(ip)                     @ jump to next instruction
8495
8496
8497/* ------------------------------ */
8498    .balign 64
8499.L_OP_SPUT_JUMBO: /* 0x11b */
8500/* File: armv5te/OP_SPUT_JUMBO.S */
8501    /*
8502     * Jumbo 32-bit SPUT handler.
8503     *
8504     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8505     *      sput-short/jumbo
8506     */
8507    /* exop vBBBB, field@AAAAAAAA */
8508    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8509    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8510    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8511    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8512    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8513    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8514    cmp     r0, #0                      @ is resolved entry null?
8515    beq     .LOP_SPUT_JUMBO_resolve         @ yes, do resolve
8516.LOP_SPUT_JUMBO_finish:   @ field ptr in r0
8517    FETCH(r2, 3)                        @ r2<- BBBB
8518    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8519    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8520    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8521    @ no-op                             @ releasing store
8522    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8523    GOTO_OPCODE(ip)                     @ jump to next instruction
8524
8525/* ------------------------------ */
8526    .balign 64
8527.L_OP_SPUT_WIDE_JUMBO: /* 0x11c */
8528/* File: armv5te/OP_SPUT_WIDE_JUMBO.S */
8529    /*
8530     * Jumbo 64-bit SPUT handler.
8531     */
8532    /* sput-wide/jumbo vBBBB, field@AAAAAAAA */
8533    ldr     r0, [rGLUE, #offGlue_methodClassDex]  @ r0<- DvmDex
8534    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8535    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8536    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
8537    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8538    FETCH(r9, 3)                        @ r9<- BBBB
8539    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
8540    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BBBB]
8541    cmp     r2, #0                      @ is resolved entry null?
8542    beq     .LOP_SPUT_WIDE_JUMBO_resolve         @ yes, do resolve
8543.LOP_SPUT_WIDE_JUMBO_finish: @ field ptr in r2, BBBB in r9
8544    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8545    ldmia   r9, {r0-r1}                 @ r0/r1<- vBBBB/vBBBB+1
8546    GET_INST_OPCODE(r10)                @ extract opcode from rINST
8547    strd    r0, [r2, #offStaticField_value] @ field<- vBBBB/vBBBB+1
8548    GOTO_OPCODE(r10)                    @ jump to next instruction
8549
8550/* ------------------------------ */
8551    .balign 64
8552.L_OP_SPUT_OBJECT_JUMBO: /* 0x11d */
8553/* File: armv5te/OP_SPUT_OBJECT_JUMBO.S */
8554    /*
8555     * Jumbo 32-bit SPUT handler for objects
8556     */
8557    /* sput-object/jumbo vBBBB, field@AAAAAAAA */
8558    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8559    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8560    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8561    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8562    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8563    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8564    cmp     r0, #0                      @ is resolved entry null?
8565    bne     .LOP_SPUT_OBJECT_JUMBO_finish          @ no, continue
8566    ldr     r9, [rGLUE, #offGlue_method]    @ r9<- current method
8567    EXPORT_PC()                         @ resolve() could throw, so export now
8568    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
8569    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8570    cmp     r0, #0                      @ success?
8571    bne     .LOP_SPUT_OBJECT_JUMBO_finish          @ yes, finish
8572    b       common_exceptionThrown      @ no, handle exception
8573
8574/* ------------------------------ */
8575    .balign 64
8576.L_OP_SPUT_BOOLEAN_JUMBO: /* 0x11e */
8577/* File: armv5te/OP_SPUT_BOOLEAN_JUMBO.S */
8578/* File: armv5te/OP_SPUT_JUMBO.S */
8579    /*
8580     * Jumbo 32-bit SPUT handler.
8581     *
8582     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8583     *      sput-short/jumbo
8584     */
8585    /* exop vBBBB, field@AAAAAAAA */
8586    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8587    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8588    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8589    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8590    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8591    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8592    cmp     r0, #0                      @ is resolved entry null?
8593    beq     .LOP_SPUT_BOOLEAN_JUMBO_resolve         @ yes, do resolve
8594.LOP_SPUT_BOOLEAN_JUMBO_finish:   @ field ptr in r0
8595    FETCH(r2, 3)                        @ r2<- BBBB
8596    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8597    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8598    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8599    @ no-op                             @ releasing store
8600    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8601    GOTO_OPCODE(ip)                     @ jump to next instruction
8602
8603
8604/* ------------------------------ */
8605    .balign 64
8606.L_OP_SPUT_BYTE_JUMBO: /* 0x11f */
8607/* File: armv5te/OP_SPUT_BYTE_JUMBO.S */
8608/* File: armv5te/OP_SPUT_JUMBO.S */
8609    /*
8610     * Jumbo 32-bit SPUT handler.
8611     *
8612     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8613     *      sput-short/jumbo
8614     */
8615    /* exop vBBBB, field@AAAAAAAA */
8616    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8617    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8618    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8619    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8620    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8621    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8622    cmp     r0, #0                      @ is resolved entry null?
8623    beq     .LOP_SPUT_BYTE_JUMBO_resolve         @ yes, do resolve
8624.LOP_SPUT_BYTE_JUMBO_finish:   @ field ptr in r0
8625    FETCH(r2, 3)                        @ r2<- BBBB
8626    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8627    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8628    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8629    @ no-op                             @ releasing store
8630    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8631    GOTO_OPCODE(ip)                     @ jump to next instruction
8632
8633
8634/* ------------------------------ */
8635    .balign 64
8636.L_OP_SPUT_CHAR_JUMBO: /* 0x120 */
8637/* File: armv5te/OP_SPUT_CHAR_JUMBO.S */
8638/* File: armv5te/OP_SPUT_JUMBO.S */
8639    /*
8640     * Jumbo 32-bit SPUT handler.
8641     *
8642     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8643     *      sput-short/jumbo
8644     */
8645    /* exop vBBBB, field@AAAAAAAA */
8646    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8647    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8648    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8649    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8650    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8651    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8652    cmp     r0, #0                      @ is resolved entry null?
8653    beq     .LOP_SPUT_CHAR_JUMBO_resolve         @ yes, do resolve
8654.LOP_SPUT_CHAR_JUMBO_finish:   @ field ptr in r0
8655    FETCH(r2, 3)                        @ r2<- BBBB
8656    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8657    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8658    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8659    @ no-op                             @ releasing store
8660    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8661    GOTO_OPCODE(ip)                     @ jump to next instruction
8662
8663
8664/* ------------------------------ */
8665    .balign 64
8666.L_OP_SPUT_SHORT_JUMBO: /* 0x121 */
8667/* File: armv5te/OP_SPUT_SHORT_JUMBO.S */
8668/* File: armv5te/OP_SPUT_JUMBO.S */
8669    /*
8670     * Jumbo 32-bit SPUT handler.
8671     *
8672     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8673     *      sput-short/jumbo
8674     */
8675    /* exop vBBBB, field@AAAAAAAA */
8676    ldr     r2, [rGLUE, #offGlue_methodClassDex]    @ r2<- DvmDex
8677    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8678    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8679    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8680    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8681    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8682    cmp     r0, #0                      @ is resolved entry null?
8683    beq     .LOP_SPUT_SHORT_JUMBO_resolve         @ yes, do resolve
8684.LOP_SPUT_SHORT_JUMBO_finish:   @ field ptr in r0
8685    FETCH(r2, 3)                        @ r2<- BBBB
8686    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8687    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8688    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8689    @ no-op                             @ releasing store
8690    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8691    GOTO_OPCODE(ip)                     @ jump to next instruction
8692
8693
8694/* ------------------------------ */
8695    .balign 64
8696.L_OP_INVOKE_VIRTUAL_JUMBO: /* 0x122 */
8697/* File: armv5te/OP_INVOKE_VIRTUAL_JUMBO.S */
8698    /*
8699     * Handle a virtual method call.
8700     */
8701    /* invoke-virtual/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8702    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8703    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8704    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8705    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8706    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8707    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
8708    cmp     r0, #0                      @ already resolved?
8709    EXPORT_PC()                         @ must export for invoke
8710    bne     .LOP_INVOKE_VIRTUAL_JUMBO_continue        @ yes, continue on
8711    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
8712    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8713    mov     r2, #METHOD_VIRTUAL         @ resolver method type
8714    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8715    cmp     r0, #0                      @ got null?
8716    bne     .LOP_INVOKE_VIRTUAL_JUMBO_continue        @ no, continue
8717    b       common_exceptionThrown      @ yes, handle exception
8718
8719/* ------------------------------ */
8720    .balign 64
8721.L_OP_INVOKE_SUPER_JUMBO: /* 0x123 */
8722/* File: armv5te/OP_INVOKE_SUPER_JUMBO.S */
8723    /*
8724     * Handle a "super" method call.
8725     */
8726    /* invoke-super/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8727    FETCH(r10, 4)                       @ r10<- CCCC
8728    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8729    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8730    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8731    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8732    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8733    GET_VREG(r2, r10)                   @ r2<- "this" ptr
8734    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
8735    cmp     r2, #0                      @ null "this"?
8736    ldr     r9, [rGLUE, #offGlue_method] @ r9<- current method
8737    beq     common_errNullObject        @ null "this", throw exception
8738    cmp     r0, #0                      @ already resolved?
8739    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
8740    EXPORT_PC()                         @ must export for invoke
8741    bne     .LOP_INVOKE_SUPER_JUMBO_continue        @ resolved, continue on
8742    b       .LOP_INVOKE_SUPER_JUMBO_resolve         @ do resolve now
8743
8744/* ------------------------------ */
8745    .balign 64
8746.L_OP_INVOKE_DIRECT_JUMBO: /* 0x124 */
8747/* File: armv5te/OP_INVOKE_DIRECT_JUMBO.S */
8748    /*
8749     * Handle a direct method call.
8750     *
8751     * (We could defer the "is 'this' pointer null" test to the common
8752     * method invocation code, and use a flag to indicate that static
8753     * calls don't count.  If we do this as part of copying the arguments
8754     * out we could avoiding loading the first arg twice.)
8755     *
8756     */
8757    /* invoke-direct/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8758    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8759    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8760    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8761    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8762    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8763    FETCH(r10, 4)                       @ r10<- CCCC
8764    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
8765    cmp     r0, #0                      @ already resolved?
8766    EXPORT_PC()                         @ must export for invoke
8767    GET_VREG(r2, r10)                   @ r2<- "this" ptr
8768    beq     .LOP_INVOKE_DIRECT_JUMBO_resolve         @ not resolved, do it now
8769.LOP_INVOKE_DIRECT_JUMBO_finish:
8770    cmp     r2, #0                      @ null "this" ref?
8771    bne     common_invokeMethodJumbo    @ no, continue on
8772    b       common_errNullObject        @ yes, throw exception
8773
8774/* ------------------------------ */
8775    .balign 64
8776.L_OP_INVOKE_STATIC_JUMBO: /* 0x125 */
8777/* File: armv5te/OP_INVOKE_STATIC_JUMBO.S */
8778    /*
8779     * Handle a static method call.
8780     */
8781    /* invoke-static/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8782    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- pDvmDex
8783    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8784    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8785    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8786    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8787    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
8788    cmp     r0, #0                      @ already resolved?
8789    EXPORT_PC()                         @ must export for invoke
8790    bne     common_invokeMethodJumbo    @ yes, continue on
87910:  ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
8792    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8793    mov     r2, #METHOD_STATIC          @ resolver method type
8794    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8795    cmp     r0, #0                      @ got null?
8796    bne     common_invokeMethodJumbo    @ no, continue
8797    b       common_exceptionThrown      @ yes, handle exception
8798
8799/* ------------------------------ */
8800    .balign 64
8801.L_OP_INVOKE_INTERFACE_JUMBO: /* 0x126 */
8802/* File: armv5te/OP_INVOKE_INTERFACE_JUMBO.S */
8803    /*
8804     * Handle an interface method call.
8805     */
8806    /* invoke-interface/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8807    FETCH(r2, 4)                        @ r2<- CCCC
8808    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8809    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8810    EXPORT_PC()                         @ must export for invoke
8811    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8812    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
8813    ldr     r3, [rGLUE, #offGlue_methodClassDex]    @ r3<- methodClassDex
8814    cmp     r0, #0                      @ null obj?
8815    ldr     r2, [rGLUE, #offGlue_method]  @ r2<- method
8816    beq     common_errNullObject        @ yes, fail
8817    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
8818    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
8819    cmp     r0, #0                      @ failed?
8820    beq     common_exceptionThrown      @ yes, handle exception
8821    b       common_invokeMethodJumbo    @ jump to common handler
8822
8823/* ------------------------------ */
8824    .balign 64
8825.L_OP_UNUSED_27FF: /* 0x127 */
8826/* File: armv5te/OP_UNUSED_27FF.S */
8827/* File: armv5te/unused.S */
8828    bl      common_abort
8829
8830
8831/* ------------------------------ */
8832    .balign 64
8833.L_OP_UNUSED_28FF: /* 0x128 */
8834/* File: armv5te/OP_UNUSED_28FF.S */
8835/* File: armv5te/unused.S */
8836    bl      common_abort
8837
8838
8839/* ------------------------------ */
8840    .balign 64
8841.L_OP_UNUSED_29FF: /* 0x129 */
8842/* File: armv5te/OP_UNUSED_29FF.S */
8843/* File: armv5te/unused.S */
8844    bl      common_abort
8845
8846
8847/* ------------------------------ */
8848    .balign 64
8849.L_OP_UNUSED_2AFF: /* 0x12a */
8850/* File: armv5te/OP_UNUSED_2AFF.S */
8851/* File: armv5te/unused.S */
8852    bl      common_abort
8853
8854
8855/* ------------------------------ */
8856    .balign 64
8857.L_OP_UNUSED_2BFF: /* 0x12b */
8858/* File: armv5te/OP_UNUSED_2BFF.S */
8859/* File: armv5te/unused.S */
8860    bl      common_abort
8861
8862
8863/* ------------------------------ */
8864    .balign 64
8865.L_OP_UNUSED_2CFF: /* 0x12c */
8866/* File: armv5te/OP_UNUSED_2CFF.S */
8867/* File: armv5te/unused.S */
8868    bl      common_abort
8869
8870
8871/* ------------------------------ */
8872    .balign 64
8873.L_OP_UNUSED_2DFF: /* 0x12d */
8874/* File: armv5te/OP_UNUSED_2DFF.S */
8875/* File: armv5te/unused.S */
8876    bl      common_abort
8877
8878
8879/* ------------------------------ */
8880    .balign 64
8881.L_OP_UNUSED_2EFF: /* 0x12e */
8882/* File: armv5te/OP_UNUSED_2EFF.S */
8883/* File: armv5te/unused.S */
8884    bl      common_abort
8885
8886
8887/* ------------------------------ */
8888    .balign 64
8889.L_OP_UNUSED_2FFF: /* 0x12f */
8890/* File: armv5te/OP_UNUSED_2FFF.S */
8891/* File: armv5te/unused.S */
8892    bl      common_abort
8893
8894
8895/* ------------------------------ */
8896    .balign 64
8897.L_OP_UNUSED_30FF: /* 0x130 */
8898/* File: armv5te/OP_UNUSED_30FF.S */
8899/* File: armv5te/unused.S */
8900    bl      common_abort
8901
8902
8903/* ------------------------------ */
8904    .balign 64
8905.L_OP_UNUSED_31FF: /* 0x131 */
8906/* File: armv5te/OP_UNUSED_31FF.S */
8907/* File: armv5te/unused.S */
8908    bl      common_abort
8909
8910
8911/* ------------------------------ */
8912    .balign 64
8913.L_OP_UNUSED_32FF: /* 0x132 */
8914/* File: armv5te/OP_UNUSED_32FF.S */
8915/* File: armv5te/unused.S */
8916    bl      common_abort
8917
8918
8919/* ------------------------------ */
8920    .balign 64
8921.L_OP_UNUSED_33FF: /* 0x133 */
8922/* File: armv5te/OP_UNUSED_33FF.S */
8923/* File: armv5te/unused.S */
8924    bl      common_abort
8925
8926
8927/* ------------------------------ */
8928    .balign 64
8929.L_OP_UNUSED_34FF: /* 0x134 */
8930/* File: armv5te/OP_UNUSED_34FF.S */
8931/* File: armv5te/unused.S */
8932    bl      common_abort
8933
8934
8935/* ------------------------------ */
8936    .balign 64
8937.L_OP_UNUSED_35FF: /* 0x135 */
8938/* File: armv5te/OP_UNUSED_35FF.S */
8939/* File: armv5te/unused.S */
8940    bl      common_abort
8941
8942
8943/* ------------------------------ */
8944    .balign 64
8945.L_OP_UNUSED_36FF: /* 0x136 */
8946/* File: armv5te/OP_UNUSED_36FF.S */
8947/* File: armv5te/unused.S */
8948    bl      common_abort
8949
8950
8951/* ------------------------------ */
8952    .balign 64
8953.L_OP_UNUSED_37FF: /* 0x137 */
8954/* File: armv5te/OP_UNUSED_37FF.S */
8955/* File: armv5te/unused.S */
8956    bl      common_abort
8957
8958
8959/* ------------------------------ */
8960    .balign 64
8961.L_OP_UNUSED_38FF: /* 0x138 */
8962/* File: armv5te/OP_UNUSED_38FF.S */
8963/* File: armv5te/unused.S */
8964    bl      common_abort
8965
8966
8967/* ------------------------------ */
8968    .balign 64
8969.L_OP_UNUSED_39FF: /* 0x139 */
8970/* File: armv5te/OP_UNUSED_39FF.S */
8971/* File: armv5te/unused.S */
8972    bl      common_abort
8973
8974
8975/* ------------------------------ */
8976    .balign 64
8977.L_OP_UNUSED_3AFF: /* 0x13a */
8978/* File: armv5te/OP_UNUSED_3AFF.S */
8979/* File: armv5te/unused.S */
8980    bl      common_abort
8981
8982
8983/* ------------------------------ */
8984    .balign 64
8985.L_OP_UNUSED_3BFF: /* 0x13b */
8986/* File: armv5te/OP_UNUSED_3BFF.S */
8987/* File: armv5te/unused.S */
8988    bl      common_abort
8989
8990
8991/* ------------------------------ */
8992    .balign 64
8993.L_OP_UNUSED_3CFF: /* 0x13c */
8994/* File: armv5te/OP_UNUSED_3CFF.S */
8995/* File: armv5te/unused.S */
8996    bl      common_abort
8997
8998
8999/* ------------------------------ */
9000    .balign 64
9001.L_OP_UNUSED_3DFF: /* 0x13d */
9002/* File: armv5te/OP_UNUSED_3DFF.S */
9003/* File: armv5te/unused.S */
9004    bl      common_abort
9005
9006
9007/* ------------------------------ */
9008    .balign 64
9009.L_OP_UNUSED_3EFF: /* 0x13e */
9010/* File: armv5te/OP_UNUSED_3EFF.S */
9011/* File: armv5te/unused.S */
9012    bl      common_abort
9013
9014
9015/* ------------------------------ */
9016    .balign 64
9017.L_OP_UNUSED_3FFF: /* 0x13f */
9018/* File: armv5te/OP_UNUSED_3FFF.S */
9019/* File: armv5te/unused.S */
9020    bl      common_abort
9021
9022
9023/* ------------------------------ */
9024    .balign 64
9025.L_OP_UNUSED_40FF: /* 0x140 */
9026/* File: armv5te/OP_UNUSED_40FF.S */
9027/* File: armv5te/unused.S */
9028    bl      common_abort
9029
9030
9031/* ------------------------------ */
9032    .balign 64
9033.L_OP_UNUSED_41FF: /* 0x141 */
9034/* File: armv5te/OP_UNUSED_41FF.S */
9035/* File: armv5te/unused.S */
9036    bl      common_abort
9037
9038
9039/* ------------------------------ */
9040    .balign 64
9041.L_OP_UNUSED_42FF: /* 0x142 */
9042/* File: armv5te/OP_UNUSED_42FF.S */
9043/* File: armv5te/unused.S */
9044    bl      common_abort
9045
9046
9047/* ------------------------------ */
9048    .balign 64
9049.L_OP_UNUSED_43FF: /* 0x143 */
9050/* File: armv5te/OP_UNUSED_43FF.S */
9051/* File: armv5te/unused.S */
9052    bl      common_abort
9053
9054
9055/* ------------------------------ */
9056    .balign 64
9057.L_OP_UNUSED_44FF: /* 0x144 */
9058/* File: armv5te/OP_UNUSED_44FF.S */
9059/* File: armv5te/unused.S */
9060    bl      common_abort
9061
9062
9063/* ------------------------------ */
9064    .balign 64
9065.L_OP_UNUSED_45FF: /* 0x145 */
9066/* File: armv5te/OP_UNUSED_45FF.S */
9067/* File: armv5te/unused.S */
9068    bl      common_abort
9069
9070
9071/* ------------------------------ */
9072    .balign 64
9073.L_OP_UNUSED_46FF: /* 0x146 */
9074/* File: armv5te/OP_UNUSED_46FF.S */
9075/* File: armv5te/unused.S */
9076    bl      common_abort
9077
9078
9079/* ------------------------------ */
9080    .balign 64
9081.L_OP_UNUSED_47FF: /* 0x147 */
9082/* File: armv5te/OP_UNUSED_47FF.S */
9083/* File: armv5te/unused.S */
9084    bl      common_abort
9085
9086
9087/* ------------------------------ */
9088    .balign 64
9089.L_OP_UNUSED_48FF: /* 0x148 */
9090/* File: armv5te/OP_UNUSED_48FF.S */
9091/* File: armv5te/unused.S */
9092    bl      common_abort
9093
9094
9095/* ------------------------------ */
9096    .balign 64
9097.L_OP_UNUSED_49FF: /* 0x149 */
9098/* File: armv5te/OP_UNUSED_49FF.S */
9099/* File: armv5te/unused.S */
9100    bl      common_abort
9101
9102
9103/* ------------------------------ */
9104    .balign 64
9105.L_OP_UNUSED_4AFF: /* 0x14a */
9106/* File: armv5te/OP_UNUSED_4AFF.S */
9107/* File: armv5te/unused.S */
9108    bl      common_abort
9109
9110
9111/* ------------------------------ */
9112    .balign 64
9113.L_OP_UNUSED_4BFF: /* 0x14b */
9114/* File: armv5te/OP_UNUSED_4BFF.S */
9115/* File: armv5te/unused.S */
9116    bl      common_abort
9117
9118
9119/* ------------------------------ */
9120    .balign 64
9121.L_OP_UNUSED_4CFF: /* 0x14c */
9122/* File: armv5te/OP_UNUSED_4CFF.S */
9123/* File: armv5te/unused.S */
9124    bl      common_abort
9125
9126
9127/* ------------------------------ */
9128    .balign 64
9129.L_OP_UNUSED_4DFF: /* 0x14d */
9130/* File: armv5te/OP_UNUSED_4DFF.S */
9131/* File: armv5te/unused.S */
9132    bl      common_abort
9133
9134
9135/* ------------------------------ */
9136    .balign 64
9137.L_OP_UNUSED_4EFF: /* 0x14e */
9138/* File: armv5te/OP_UNUSED_4EFF.S */
9139/* File: armv5te/unused.S */
9140    bl      common_abort
9141
9142
9143/* ------------------------------ */
9144    .balign 64
9145.L_OP_UNUSED_4FFF: /* 0x14f */
9146/* File: armv5te/OP_UNUSED_4FFF.S */
9147/* File: armv5te/unused.S */
9148    bl      common_abort
9149
9150
9151/* ------------------------------ */
9152    .balign 64
9153.L_OP_UNUSED_50FF: /* 0x150 */
9154/* File: armv5te/OP_UNUSED_50FF.S */
9155/* File: armv5te/unused.S */
9156    bl      common_abort
9157
9158
9159/* ------------------------------ */
9160    .balign 64
9161.L_OP_UNUSED_51FF: /* 0x151 */
9162/* File: armv5te/OP_UNUSED_51FF.S */
9163/* File: armv5te/unused.S */
9164    bl      common_abort
9165
9166
9167/* ------------------------------ */
9168    .balign 64
9169.L_OP_UNUSED_52FF: /* 0x152 */
9170/* File: armv5te/OP_UNUSED_52FF.S */
9171/* File: armv5te/unused.S */
9172    bl      common_abort
9173
9174
9175/* ------------------------------ */
9176    .balign 64
9177.L_OP_UNUSED_53FF: /* 0x153 */
9178/* File: armv5te/OP_UNUSED_53FF.S */
9179/* File: armv5te/unused.S */
9180    bl      common_abort
9181
9182
9183/* ------------------------------ */
9184    .balign 64
9185.L_OP_UNUSED_54FF: /* 0x154 */
9186/* File: armv5te/OP_UNUSED_54FF.S */
9187/* File: armv5te/unused.S */
9188    bl      common_abort
9189
9190
9191/* ------------------------------ */
9192    .balign 64
9193.L_OP_UNUSED_55FF: /* 0x155 */
9194/* File: armv5te/OP_UNUSED_55FF.S */
9195/* File: armv5te/unused.S */
9196    bl      common_abort
9197
9198
9199/* ------------------------------ */
9200    .balign 64
9201.L_OP_UNUSED_56FF: /* 0x156 */
9202/* File: armv5te/OP_UNUSED_56FF.S */
9203/* File: armv5te/unused.S */
9204    bl      common_abort
9205
9206
9207/* ------------------------------ */
9208    .balign 64
9209.L_OP_UNUSED_57FF: /* 0x157 */
9210/* File: armv5te/OP_UNUSED_57FF.S */
9211/* File: armv5te/unused.S */
9212    bl      common_abort
9213
9214
9215/* ------------------------------ */
9216    .balign 64
9217.L_OP_UNUSED_58FF: /* 0x158 */
9218/* File: armv5te/OP_UNUSED_58FF.S */
9219/* File: armv5te/unused.S */
9220    bl      common_abort
9221
9222
9223/* ------------------------------ */
9224    .balign 64
9225.L_OP_UNUSED_59FF: /* 0x159 */
9226/* File: armv5te/OP_UNUSED_59FF.S */
9227/* File: armv5te/unused.S */
9228    bl      common_abort
9229
9230
9231/* ------------------------------ */
9232    .balign 64
9233.L_OP_UNUSED_5AFF: /* 0x15a */
9234/* File: armv5te/OP_UNUSED_5AFF.S */
9235/* File: armv5te/unused.S */
9236    bl      common_abort
9237
9238
9239/* ------------------------------ */
9240    .balign 64
9241.L_OP_UNUSED_5BFF: /* 0x15b */
9242/* File: armv5te/OP_UNUSED_5BFF.S */
9243/* File: armv5te/unused.S */
9244    bl      common_abort
9245
9246
9247/* ------------------------------ */
9248    .balign 64
9249.L_OP_UNUSED_5CFF: /* 0x15c */
9250/* File: armv5te/OP_UNUSED_5CFF.S */
9251/* File: armv5te/unused.S */
9252    bl      common_abort
9253
9254
9255/* ------------------------------ */
9256    .balign 64
9257.L_OP_UNUSED_5DFF: /* 0x15d */
9258/* File: armv5te/OP_UNUSED_5DFF.S */
9259/* File: armv5te/unused.S */
9260    bl      common_abort
9261
9262
9263/* ------------------------------ */
9264    .balign 64
9265.L_OP_UNUSED_5EFF: /* 0x15e */
9266/* File: armv5te/OP_UNUSED_5EFF.S */
9267/* File: armv5te/unused.S */
9268    bl      common_abort
9269
9270
9271/* ------------------------------ */
9272    .balign 64
9273.L_OP_UNUSED_5FFF: /* 0x15f */
9274/* File: armv5te/OP_UNUSED_5FFF.S */
9275/* File: armv5te/unused.S */
9276    bl      common_abort
9277
9278
9279/* ------------------------------ */
9280    .balign 64
9281.L_OP_UNUSED_60FF: /* 0x160 */
9282/* File: armv5te/OP_UNUSED_60FF.S */
9283/* File: armv5te/unused.S */
9284    bl      common_abort
9285
9286
9287/* ------------------------------ */
9288    .balign 64
9289.L_OP_UNUSED_61FF: /* 0x161 */
9290/* File: armv5te/OP_UNUSED_61FF.S */
9291/* File: armv5te/unused.S */
9292    bl      common_abort
9293
9294
9295/* ------------------------------ */
9296    .balign 64
9297.L_OP_UNUSED_62FF: /* 0x162 */
9298/* File: armv5te/OP_UNUSED_62FF.S */
9299/* File: armv5te/unused.S */
9300    bl      common_abort
9301
9302
9303/* ------------------------------ */
9304    .balign 64
9305.L_OP_UNUSED_63FF: /* 0x163 */
9306/* File: armv5te/OP_UNUSED_63FF.S */
9307/* File: armv5te/unused.S */
9308    bl      common_abort
9309
9310
9311/* ------------------------------ */
9312    .balign 64
9313.L_OP_UNUSED_64FF: /* 0x164 */
9314/* File: armv5te/OP_UNUSED_64FF.S */
9315/* File: armv5te/unused.S */
9316    bl      common_abort
9317
9318
9319/* ------------------------------ */
9320    .balign 64
9321.L_OP_UNUSED_65FF: /* 0x165 */
9322/* File: armv5te/OP_UNUSED_65FF.S */
9323/* File: armv5te/unused.S */
9324    bl      common_abort
9325
9326
9327/* ------------------------------ */
9328    .balign 64
9329.L_OP_UNUSED_66FF: /* 0x166 */
9330/* File: armv5te/OP_UNUSED_66FF.S */
9331/* File: armv5te/unused.S */
9332    bl      common_abort
9333
9334
9335/* ------------------------------ */
9336    .balign 64
9337.L_OP_UNUSED_67FF: /* 0x167 */
9338/* File: armv5te/OP_UNUSED_67FF.S */
9339/* File: armv5te/unused.S */
9340    bl      common_abort
9341
9342
9343/* ------------------------------ */
9344    .balign 64
9345.L_OP_UNUSED_68FF: /* 0x168 */
9346/* File: armv5te/OP_UNUSED_68FF.S */
9347/* File: armv5te/unused.S */
9348    bl      common_abort
9349
9350
9351/* ------------------------------ */
9352    .balign 64
9353.L_OP_UNUSED_69FF: /* 0x169 */
9354/* File: armv5te/OP_UNUSED_69FF.S */
9355/* File: armv5te/unused.S */
9356    bl      common_abort
9357
9358
9359/* ------------------------------ */
9360    .balign 64
9361.L_OP_UNUSED_6AFF: /* 0x16a */
9362/* File: armv5te/OP_UNUSED_6AFF.S */
9363/* File: armv5te/unused.S */
9364    bl      common_abort
9365
9366
9367/* ------------------------------ */
9368    .balign 64
9369.L_OP_UNUSED_6BFF: /* 0x16b */
9370/* File: armv5te/OP_UNUSED_6BFF.S */
9371/* File: armv5te/unused.S */
9372    bl      common_abort
9373
9374
9375/* ------------------------------ */
9376    .balign 64
9377.L_OP_UNUSED_6CFF: /* 0x16c */
9378/* File: armv5te/OP_UNUSED_6CFF.S */
9379/* File: armv5te/unused.S */
9380    bl      common_abort
9381
9382
9383/* ------------------------------ */
9384    .balign 64
9385.L_OP_UNUSED_6DFF: /* 0x16d */
9386/* File: armv5te/OP_UNUSED_6DFF.S */
9387/* File: armv5te/unused.S */
9388    bl      common_abort
9389
9390
9391/* ------------------------------ */
9392    .balign 64
9393.L_OP_UNUSED_6EFF: /* 0x16e */
9394/* File: armv5te/OP_UNUSED_6EFF.S */
9395/* File: armv5te/unused.S */
9396    bl      common_abort
9397
9398
9399/* ------------------------------ */
9400    .balign 64
9401.L_OP_UNUSED_6FFF: /* 0x16f */
9402/* File: armv5te/OP_UNUSED_6FFF.S */
9403/* File: armv5te/unused.S */
9404    bl      common_abort
9405
9406
9407/* ------------------------------ */
9408    .balign 64
9409.L_OP_UNUSED_70FF: /* 0x170 */
9410/* File: armv5te/OP_UNUSED_70FF.S */
9411/* File: armv5te/unused.S */
9412    bl      common_abort
9413
9414
9415/* ------------------------------ */
9416    .balign 64
9417.L_OP_UNUSED_71FF: /* 0x171 */
9418/* File: armv5te/OP_UNUSED_71FF.S */
9419/* File: armv5te/unused.S */
9420    bl      common_abort
9421
9422
9423/* ------------------------------ */
9424    .balign 64
9425.L_OP_UNUSED_72FF: /* 0x172 */
9426/* File: armv5te/OP_UNUSED_72FF.S */
9427/* File: armv5te/unused.S */
9428    bl      common_abort
9429
9430
9431/* ------------------------------ */
9432    .balign 64
9433.L_OP_UNUSED_73FF: /* 0x173 */
9434/* File: armv5te/OP_UNUSED_73FF.S */
9435/* File: armv5te/unused.S */
9436    bl      common_abort
9437
9438
9439/* ------------------------------ */
9440    .balign 64
9441.L_OP_UNUSED_74FF: /* 0x174 */
9442/* File: armv5te/OP_UNUSED_74FF.S */
9443/* File: armv5te/unused.S */
9444    bl      common_abort
9445
9446
9447/* ------------------------------ */
9448    .balign 64
9449.L_OP_UNUSED_75FF: /* 0x175 */
9450/* File: armv5te/OP_UNUSED_75FF.S */
9451/* File: armv5te/unused.S */
9452    bl      common_abort
9453
9454
9455/* ------------------------------ */
9456    .balign 64
9457.L_OP_UNUSED_76FF: /* 0x176 */
9458/* File: armv5te/OP_UNUSED_76FF.S */
9459/* File: armv5te/unused.S */
9460    bl      common_abort
9461
9462
9463/* ------------------------------ */
9464    .balign 64
9465.L_OP_UNUSED_77FF: /* 0x177 */
9466/* File: armv5te/OP_UNUSED_77FF.S */
9467/* File: armv5te/unused.S */
9468    bl      common_abort
9469
9470
9471/* ------------------------------ */
9472    .balign 64
9473.L_OP_UNUSED_78FF: /* 0x178 */
9474/* File: armv5te/OP_UNUSED_78FF.S */
9475/* File: armv5te/unused.S */
9476    bl      common_abort
9477
9478
9479/* ------------------------------ */
9480    .balign 64
9481.L_OP_UNUSED_79FF: /* 0x179 */
9482/* File: armv5te/OP_UNUSED_79FF.S */
9483/* File: armv5te/unused.S */
9484    bl      common_abort
9485
9486
9487/* ------------------------------ */
9488    .balign 64
9489.L_OP_UNUSED_7AFF: /* 0x17a */
9490/* File: armv5te/OP_UNUSED_7AFF.S */
9491/* File: armv5te/unused.S */
9492    bl      common_abort
9493
9494
9495/* ------------------------------ */
9496    .balign 64
9497.L_OP_UNUSED_7BFF: /* 0x17b */
9498/* File: armv5te/OP_UNUSED_7BFF.S */
9499/* File: armv5te/unused.S */
9500    bl      common_abort
9501
9502
9503/* ------------------------------ */
9504    .balign 64
9505.L_OP_UNUSED_7CFF: /* 0x17c */
9506/* File: armv5te/OP_UNUSED_7CFF.S */
9507/* File: armv5te/unused.S */
9508    bl      common_abort
9509
9510
9511/* ------------------------------ */
9512    .balign 64
9513.L_OP_UNUSED_7DFF: /* 0x17d */
9514/* File: armv5te/OP_UNUSED_7DFF.S */
9515/* File: armv5te/unused.S */
9516    bl      common_abort
9517
9518
9519/* ------------------------------ */
9520    .balign 64
9521.L_OP_UNUSED_7EFF: /* 0x17e */
9522/* File: armv5te/OP_UNUSED_7EFF.S */
9523/* File: armv5te/unused.S */
9524    bl      common_abort
9525
9526
9527/* ------------------------------ */
9528    .balign 64
9529.L_OP_UNUSED_7FFF: /* 0x17f */
9530/* File: armv5te/OP_UNUSED_7FFF.S */
9531/* File: armv5te/unused.S */
9532    bl      common_abort
9533
9534
9535/* ------------------------------ */
9536    .balign 64
9537.L_OP_UNUSED_80FF: /* 0x180 */
9538/* File: armv5te/OP_UNUSED_80FF.S */
9539/* File: armv5te/unused.S */
9540    bl      common_abort
9541
9542
9543/* ------------------------------ */
9544    .balign 64
9545.L_OP_UNUSED_81FF: /* 0x181 */
9546/* File: armv5te/OP_UNUSED_81FF.S */
9547/* File: armv5te/unused.S */
9548    bl      common_abort
9549
9550
9551/* ------------------------------ */
9552    .balign 64
9553.L_OP_UNUSED_82FF: /* 0x182 */
9554/* File: armv5te/OP_UNUSED_82FF.S */
9555/* File: armv5te/unused.S */
9556    bl      common_abort
9557
9558
9559/* ------------------------------ */
9560    .balign 64
9561.L_OP_UNUSED_83FF: /* 0x183 */
9562/* File: armv5te/OP_UNUSED_83FF.S */
9563/* File: armv5te/unused.S */
9564    bl      common_abort
9565
9566
9567/* ------------------------------ */
9568    .balign 64
9569.L_OP_UNUSED_84FF: /* 0x184 */
9570/* File: armv5te/OP_UNUSED_84FF.S */
9571/* File: armv5te/unused.S */
9572    bl      common_abort
9573
9574
9575/* ------------------------------ */
9576    .balign 64
9577.L_OP_UNUSED_85FF: /* 0x185 */
9578/* File: armv5te/OP_UNUSED_85FF.S */
9579/* File: armv5te/unused.S */
9580    bl      common_abort
9581
9582
9583/* ------------------------------ */
9584    .balign 64
9585.L_OP_UNUSED_86FF: /* 0x186 */
9586/* File: armv5te/OP_UNUSED_86FF.S */
9587/* File: armv5te/unused.S */
9588    bl      common_abort
9589
9590
9591/* ------------------------------ */
9592    .balign 64
9593.L_OP_UNUSED_87FF: /* 0x187 */
9594/* File: armv5te/OP_UNUSED_87FF.S */
9595/* File: armv5te/unused.S */
9596    bl      common_abort
9597
9598
9599/* ------------------------------ */
9600    .balign 64
9601.L_OP_UNUSED_88FF: /* 0x188 */
9602/* File: armv5te/OP_UNUSED_88FF.S */
9603/* File: armv5te/unused.S */
9604    bl      common_abort
9605
9606
9607/* ------------------------------ */
9608    .balign 64
9609.L_OP_UNUSED_89FF: /* 0x189 */
9610/* File: armv5te/OP_UNUSED_89FF.S */
9611/* File: armv5te/unused.S */
9612    bl      common_abort
9613
9614
9615/* ------------------------------ */
9616    .balign 64
9617.L_OP_UNUSED_8AFF: /* 0x18a */
9618/* File: armv5te/OP_UNUSED_8AFF.S */
9619/* File: armv5te/unused.S */
9620    bl      common_abort
9621
9622
9623/* ------------------------------ */
9624    .balign 64
9625.L_OP_UNUSED_8BFF: /* 0x18b */
9626/* File: armv5te/OP_UNUSED_8BFF.S */
9627/* File: armv5te/unused.S */
9628    bl      common_abort
9629
9630
9631/* ------------------------------ */
9632    .balign 64
9633.L_OP_UNUSED_8CFF: /* 0x18c */
9634/* File: armv5te/OP_UNUSED_8CFF.S */
9635/* File: armv5te/unused.S */
9636    bl      common_abort
9637
9638
9639/* ------------------------------ */
9640    .balign 64
9641.L_OP_UNUSED_8DFF: /* 0x18d */
9642/* File: armv5te/OP_UNUSED_8DFF.S */
9643/* File: armv5te/unused.S */
9644    bl      common_abort
9645
9646
9647/* ------------------------------ */
9648    .balign 64
9649.L_OP_UNUSED_8EFF: /* 0x18e */
9650/* File: armv5te/OP_UNUSED_8EFF.S */
9651/* File: armv5te/unused.S */
9652    bl      common_abort
9653
9654
9655/* ------------------------------ */
9656    .balign 64
9657.L_OP_UNUSED_8FFF: /* 0x18f */
9658/* File: armv5te/OP_UNUSED_8FFF.S */
9659/* File: armv5te/unused.S */
9660    bl      common_abort
9661
9662
9663/* ------------------------------ */
9664    .balign 64
9665.L_OP_UNUSED_90FF: /* 0x190 */
9666/* File: armv5te/OP_UNUSED_90FF.S */
9667/* File: armv5te/unused.S */
9668    bl      common_abort
9669
9670
9671/* ------------------------------ */
9672    .balign 64
9673.L_OP_UNUSED_91FF: /* 0x191 */
9674/* File: armv5te/OP_UNUSED_91FF.S */
9675/* File: armv5te/unused.S */
9676    bl      common_abort
9677
9678
9679/* ------------------------------ */
9680    .balign 64
9681.L_OP_UNUSED_92FF: /* 0x192 */
9682/* File: armv5te/OP_UNUSED_92FF.S */
9683/* File: armv5te/unused.S */
9684    bl      common_abort
9685
9686
9687/* ------------------------------ */
9688    .balign 64
9689.L_OP_UNUSED_93FF: /* 0x193 */
9690/* File: armv5te/OP_UNUSED_93FF.S */
9691/* File: armv5te/unused.S */
9692    bl      common_abort
9693
9694
9695/* ------------------------------ */
9696    .balign 64
9697.L_OP_UNUSED_94FF: /* 0x194 */
9698/* File: armv5te/OP_UNUSED_94FF.S */
9699/* File: armv5te/unused.S */
9700    bl      common_abort
9701
9702
9703/* ------------------------------ */
9704    .balign 64
9705.L_OP_UNUSED_95FF: /* 0x195 */
9706/* File: armv5te/OP_UNUSED_95FF.S */
9707/* File: armv5te/unused.S */
9708    bl      common_abort
9709
9710
9711/* ------------------------------ */
9712    .balign 64
9713.L_OP_UNUSED_96FF: /* 0x196 */
9714/* File: armv5te/OP_UNUSED_96FF.S */
9715/* File: armv5te/unused.S */
9716    bl      common_abort
9717
9718
9719/* ------------------------------ */
9720    .balign 64
9721.L_OP_UNUSED_97FF: /* 0x197 */
9722/* File: armv5te/OP_UNUSED_97FF.S */
9723/* File: armv5te/unused.S */
9724    bl      common_abort
9725
9726
9727/* ------------------------------ */
9728    .balign 64
9729.L_OP_UNUSED_98FF: /* 0x198 */
9730/* File: armv5te/OP_UNUSED_98FF.S */
9731/* File: armv5te/unused.S */
9732    bl      common_abort
9733
9734
9735/* ------------------------------ */
9736    .balign 64
9737.L_OP_UNUSED_99FF: /* 0x199 */
9738/* File: armv5te/OP_UNUSED_99FF.S */
9739/* File: armv5te/unused.S */
9740    bl      common_abort
9741
9742
9743/* ------------------------------ */
9744    .balign 64
9745.L_OP_UNUSED_9AFF: /* 0x19a */
9746/* File: armv5te/OP_UNUSED_9AFF.S */
9747/* File: armv5te/unused.S */
9748    bl      common_abort
9749
9750
9751/* ------------------------------ */
9752    .balign 64
9753.L_OP_UNUSED_9BFF: /* 0x19b */
9754/* File: armv5te/OP_UNUSED_9BFF.S */
9755/* File: armv5te/unused.S */
9756    bl      common_abort
9757
9758
9759/* ------------------------------ */
9760    .balign 64
9761.L_OP_UNUSED_9CFF: /* 0x19c */
9762/* File: armv5te/OP_UNUSED_9CFF.S */
9763/* File: armv5te/unused.S */
9764    bl      common_abort
9765
9766
9767/* ------------------------------ */
9768    .balign 64
9769.L_OP_UNUSED_9DFF: /* 0x19d */
9770/* File: armv5te/OP_UNUSED_9DFF.S */
9771/* File: armv5te/unused.S */
9772    bl      common_abort
9773
9774
9775/* ------------------------------ */
9776    .balign 64
9777.L_OP_UNUSED_9EFF: /* 0x19e */
9778/* File: armv5te/OP_UNUSED_9EFF.S */
9779/* File: armv5te/unused.S */
9780    bl      common_abort
9781
9782
9783/* ------------------------------ */
9784    .balign 64
9785.L_OP_UNUSED_9FFF: /* 0x19f */
9786/* File: armv5te/OP_UNUSED_9FFF.S */
9787/* File: armv5te/unused.S */
9788    bl      common_abort
9789
9790
9791/* ------------------------------ */
9792    .balign 64
9793.L_OP_UNUSED_A0FF: /* 0x1a0 */
9794/* File: armv5te/OP_UNUSED_A0FF.S */
9795/* File: armv5te/unused.S */
9796    bl      common_abort
9797
9798
9799/* ------------------------------ */
9800    .balign 64
9801.L_OP_UNUSED_A1FF: /* 0x1a1 */
9802/* File: armv5te/OP_UNUSED_A1FF.S */
9803/* File: armv5te/unused.S */
9804    bl      common_abort
9805
9806
9807/* ------------------------------ */
9808    .balign 64
9809.L_OP_UNUSED_A2FF: /* 0x1a2 */
9810/* File: armv5te/OP_UNUSED_A2FF.S */
9811/* File: armv5te/unused.S */
9812    bl      common_abort
9813
9814
9815/* ------------------------------ */
9816    .balign 64
9817.L_OP_UNUSED_A3FF: /* 0x1a3 */
9818/* File: armv5te/OP_UNUSED_A3FF.S */
9819/* File: armv5te/unused.S */
9820    bl      common_abort
9821
9822
9823/* ------------------------------ */
9824    .balign 64
9825.L_OP_UNUSED_A4FF: /* 0x1a4 */
9826/* File: armv5te/OP_UNUSED_A4FF.S */
9827/* File: armv5te/unused.S */
9828    bl      common_abort
9829
9830
9831/* ------------------------------ */
9832    .balign 64
9833.L_OP_UNUSED_A5FF: /* 0x1a5 */
9834/* File: armv5te/OP_UNUSED_A5FF.S */
9835/* File: armv5te/unused.S */
9836    bl      common_abort
9837
9838
9839/* ------------------------------ */
9840    .balign 64
9841.L_OP_UNUSED_A6FF: /* 0x1a6 */
9842/* File: armv5te/OP_UNUSED_A6FF.S */
9843/* File: armv5te/unused.S */
9844    bl      common_abort
9845
9846
9847/* ------------------------------ */
9848    .balign 64
9849.L_OP_UNUSED_A7FF: /* 0x1a7 */
9850/* File: armv5te/OP_UNUSED_A7FF.S */
9851/* File: armv5te/unused.S */
9852    bl      common_abort
9853
9854
9855/* ------------------------------ */
9856    .balign 64
9857.L_OP_UNUSED_A8FF: /* 0x1a8 */
9858/* File: armv5te/OP_UNUSED_A8FF.S */
9859/* File: armv5te/unused.S */
9860    bl      common_abort
9861
9862
9863/* ------------------------------ */
9864    .balign 64
9865.L_OP_UNUSED_A9FF: /* 0x1a9 */
9866/* File: armv5te/OP_UNUSED_A9FF.S */
9867/* File: armv5te/unused.S */
9868    bl      common_abort
9869
9870
9871/* ------------------------------ */
9872    .balign 64
9873.L_OP_UNUSED_AAFF: /* 0x1aa */
9874/* File: armv5te/OP_UNUSED_AAFF.S */
9875/* File: armv5te/unused.S */
9876    bl      common_abort
9877
9878
9879/* ------------------------------ */
9880    .balign 64
9881.L_OP_UNUSED_ABFF: /* 0x1ab */
9882/* File: armv5te/OP_UNUSED_ABFF.S */
9883/* File: armv5te/unused.S */
9884    bl      common_abort
9885
9886
9887/* ------------------------------ */
9888    .balign 64
9889.L_OP_UNUSED_ACFF: /* 0x1ac */
9890/* File: armv5te/OP_UNUSED_ACFF.S */
9891/* File: armv5te/unused.S */
9892    bl      common_abort
9893
9894
9895/* ------------------------------ */
9896    .balign 64
9897.L_OP_UNUSED_ADFF: /* 0x1ad */
9898/* File: armv5te/OP_UNUSED_ADFF.S */
9899/* File: armv5te/unused.S */
9900    bl      common_abort
9901
9902
9903/* ------------------------------ */
9904    .balign 64
9905.L_OP_UNUSED_AEFF: /* 0x1ae */
9906/* File: armv5te/OP_UNUSED_AEFF.S */
9907/* File: armv5te/unused.S */
9908    bl      common_abort
9909
9910
9911/* ------------------------------ */
9912    .balign 64
9913.L_OP_UNUSED_AFFF: /* 0x1af */
9914/* File: armv5te/OP_UNUSED_AFFF.S */
9915/* File: armv5te/unused.S */
9916    bl      common_abort
9917
9918
9919/* ------------------------------ */
9920    .balign 64
9921.L_OP_UNUSED_B0FF: /* 0x1b0 */
9922/* File: armv5te/OP_UNUSED_B0FF.S */
9923/* File: armv5te/unused.S */
9924    bl      common_abort
9925
9926
9927/* ------------------------------ */
9928    .balign 64
9929.L_OP_UNUSED_B1FF: /* 0x1b1 */
9930/* File: armv5te/OP_UNUSED_B1FF.S */
9931/* File: armv5te/unused.S */
9932    bl      common_abort
9933
9934
9935/* ------------------------------ */
9936    .balign 64
9937.L_OP_UNUSED_B2FF: /* 0x1b2 */
9938/* File: armv5te/OP_UNUSED_B2FF.S */
9939/* File: armv5te/unused.S */
9940    bl      common_abort
9941
9942
9943/* ------------------------------ */
9944    .balign 64
9945.L_OP_UNUSED_B3FF: /* 0x1b3 */
9946/* File: armv5te/OP_UNUSED_B3FF.S */
9947/* File: armv5te/unused.S */
9948    bl      common_abort
9949
9950
9951/* ------------------------------ */
9952    .balign 64
9953.L_OP_UNUSED_B4FF: /* 0x1b4 */
9954/* File: armv5te/OP_UNUSED_B4FF.S */
9955/* File: armv5te/unused.S */
9956    bl      common_abort
9957
9958
9959/* ------------------------------ */
9960    .balign 64
9961.L_OP_UNUSED_B5FF: /* 0x1b5 */
9962/* File: armv5te/OP_UNUSED_B5FF.S */
9963/* File: armv5te/unused.S */
9964    bl      common_abort
9965
9966
9967/* ------------------------------ */
9968    .balign 64
9969.L_OP_UNUSED_B6FF: /* 0x1b6 */
9970/* File: armv5te/OP_UNUSED_B6FF.S */
9971/* File: armv5te/unused.S */
9972    bl      common_abort
9973
9974
9975/* ------------------------------ */
9976    .balign 64
9977.L_OP_UNUSED_B7FF: /* 0x1b7 */
9978/* File: armv5te/OP_UNUSED_B7FF.S */
9979/* File: armv5te/unused.S */
9980    bl      common_abort
9981
9982
9983/* ------------------------------ */
9984    .balign 64
9985.L_OP_UNUSED_B8FF: /* 0x1b8 */
9986/* File: armv5te/OP_UNUSED_B8FF.S */
9987/* File: armv5te/unused.S */
9988    bl      common_abort
9989
9990
9991/* ------------------------------ */
9992    .balign 64
9993.L_OP_UNUSED_B9FF: /* 0x1b9 */
9994/* File: armv5te/OP_UNUSED_B9FF.S */
9995/* File: armv5te/unused.S */
9996    bl      common_abort
9997
9998
9999/* ------------------------------ */
10000    .balign 64
10001.L_OP_UNUSED_BAFF: /* 0x1ba */
10002/* File: armv5te/OP_UNUSED_BAFF.S */
10003/* File: armv5te/unused.S */
10004    bl      common_abort
10005
10006
10007/* ------------------------------ */
10008    .balign 64
10009.L_OP_UNUSED_BBFF: /* 0x1bb */
10010/* File: armv5te/OP_UNUSED_BBFF.S */
10011/* File: armv5te/unused.S */
10012    bl      common_abort
10013
10014
10015/* ------------------------------ */
10016    .balign 64
10017.L_OP_UNUSED_BCFF: /* 0x1bc */
10018/* File: armv5te/OP_UNUSED_BCFF.S */
10019/* File: armv5te/unused.S */
10020    bl      common_abort
10021
10022
10023/* ------------------------------ */
10024    .balign 64
10025.L_OP_UNUSED_BDFF: /* 0x1bd */
10026/* File: armv5te/OP_UNUSED_BDFF.S */
10027/* File: armv5te/unused.S */
10028    bl      common_abort
10029
10030
10031/* ------------------------------ */
10032    .balign 64
10033.L_OP_UNUSED_BEFF: /* 0x1be */
10034/* File: armv5te/OP_UNUSED_BEFF.S */
10035/* File: armv5te/unused.S */
10036    bl      common_abort
10037
10038
10039/* ------------------------------ */
10040    .balign 64
10041.L_OP_UNUSED_BFFF: /* 0x1bf */
10042/* File: armv5te/OP_UNUSED_BFFF.S */
10043/* File: armv5te/unused.S */
10044    bl      common_abort
10045
10046
10047/* ------------------------------ */
10048    .balign 64
10049.L_OP_UNUSED_C0FF: /* 0x1c0 */
10050/* File: armv5te/OP_UNUSED_C0FF.S */
10051/* File: armv5te/unused.S */
10052    bl      common_abort
10053
10054
10055/* ------------------------------ */
10056    .balign 64
10057.L_OP_UNUSED_C1FF: /* 0x1c1 */
10058/* File: armv5te/OP_UNUSED_C1FF.S */
10059/* File: armv5te/unused.S */
10060    bl      common_abort
10061
10062
10063/* ------------------------------ */
10064    .balign 64
10065.L_OP_UNUSED_C2FF: /* 0x1c2 */
10066/* File: armv5te/OP_UNUSED_C2FF.S */
10067/* File: armv5te/unused.S */
10068    bl      common_abort
10069
10070
10071/* ------------------------------ */
10072    .balign 64
10073.L_OP_UNUSED_C3FF: /* 0x1c3 */
10074/* File: armv5te/OP_UNUSED_C3FF.S */
10075/* File: armv5te/unused.S */
10076    bl      common_abort
10077
10078
10079/* ------------------------------ */
10080    .balign 64
10081.L_OP_UNUSED_C4FF: /* 0x1c4 */
10082/* File: armv5te/OP_UNUSED_C4FF.S */
10083/* File: armv5te/unused.S */
10084    bl      common_abort
10085
10086
10087/* ------------------------------ */
10088    .balign 64
10089.L_OP_UNUSED_C5FF: /* 0x1c5 */
10090/* File: armv5te/OP_UNUSED_C5FF.S */
10091/* File: armv5te/unused.S */
10092    bl      common_abort
10093
10094
10095/* ------------------------------ */
10096    .balign 64
10097.L_OP_UNUSED_C6FF: /* 0x1c6 */
10098/* File: armv5te/OP_UNUSED_C6FF.S */
10099/* File: armv5te/unused.S */
10100    bl      common_abort
10101
10102
10103/* ------------------------------ */
10104    .balign 64
10105.L_OP_UNUSED_C7FF: /* 0x1c7 */
10106/* File: armv5te/OP_UNUSED_C7FF.S */
10107/* File: armv5te/unused.S */
10108    bl      common_abort
10109
10110
10111/* ------------------------------ */
10112    .balign 64
10113.L_OP_UNUSED_C8FF: /* 0x1c8 */
10114/* File: armv5te/OP_UNUSED_C8FF.S */
10115/* File: armv5te/unused.S */
10116    bl      common_abort
10117
10118
10119/* ------------------------------ */
10120    .balign 64
10121.L_OP_UNUSED_C9FF: /* 0x1c9 */
10122/* File: armv5te/OP_UNUSED_C9FF.S */
10123/* File: armv5te/unused.S */
10124    bl      common_abort
10125
10126
10127/* ------------------------------ */
10128    .balign 64
10129.L_OP_UNUSED_CAFF: /* 0x1ca */
10130/* File: armv5te/OP_UNUSED_CAFF.S */
10131/* File: armv5te/unused.S */
10132    bl      common_abort
10133
10134
10135/* ------------------------------ */
10136    .balign 64
10137.L_OP_UNUSED_CBFF: /* 0x1cb */
10138/* File: armv5te/OP_UNUSED_CBFF.S */
10139/* File: armv5te/unused.S */
10140    bl      common_abort
10141
10142
10143/* ------------------------------ */
10144    .balign 64
10145.L_OP_UNUSED_CCFF: /* 0x1cc */
10146/* File: armv5te/OP_UNUSED_CCFF.S */
10147/* File: armv5te/unused.S */
10148    bl      common_abort
10149
10150
10151/* ------------------------------ */
10152    .balign 64
10153.L_OP_UNUSED_CDFF: /* 0x1cd */
10154/* File: armv5te/OP_UNUSED_CDFF.S */
10155/* File: armv5te/unused.S */
10156    bl      common_abort
10157
10158
10159/* ------------------------------ */
10160    .balign 64
10161.L_OP_UNUSED_CEFF: /* 0x1ce */
10162/* File: armv5te/OP_UNUSED_CEFF.S */
10163/* File: armv5te/unused.S */
10164    bl      common_abort
10165
10166
10167/* ------------------------------ */
10168    .balign 64
10169.L_OP_UNUSED_CFFF: /* 0x1cf */
10170/* File: armv5te/OP_UNUSED_CFFF.S */
10171/* File: armv5te/unused.S */
10172    bl      common_abort
10173
10174
10175/* ------------------------------ */
10176    .balign 64
10177.L_OP_UNUSED_D0FF: /* 0x1d0 */
10178/* File: armv5te/OP_UNUSED_D0FF.S */
10179/* File: armv5te/unused.S */
10180    bl      common_abort
10181
10182
10183/* ------------------------------ */
10184    .balign 64
10185.L_OP_UNUSED_D1FF: /* 0x1d1 */
10186/* File: armv5te/OP_UNUSED_D1FF.S */
10187/* File: armv5te/unused.S */
10188    bl      common_abort
10189
10190
10191/* ------------------------------ */
10192    .balign 64
10193.L_OP_UNUSED_D2FF: /* 0x1d2 */
10194/* File: armv5te/OP_UNUSED_D2FF.S */
10195/* File: armv5te/unused.S */
10196    bl      common_abort
10197
10198
10199/* ------------------------------ */
10200    .balign 64
10201.L_OP_UNUSED_D3FF: /* 0x1d3 */
10202/* File: armv5te/OP_UNUSED_D3FF.S */
10203/* File: armv5te/unused.S */
10204    bl      common_abort
10205
10206
10207/* ------------------------------ */
10208    .balign 64
10209.L_OP_UNUSED_D4FF: /* 0x1d4 */
10210/* File: armv5te/OP_UNUSED_D4FF.S */
10211/* File: armv5te/unused.S */
10212    bl      common_abort
10213
10214
10215/* ------------------------------ */
10216    .balign 64
10217.L_OP_UNUSED_D5FF: /* 0x1d5 */
10218/* File: armv5te/OP_UNUSED_D5FF.S */
10219/* File: armv5te/unused.S */
10220    bl      common_abort
10221
10222
10223/* ------------------------------ */
10224    .balign 64
10225.L_OP_UNUSED_D6FF: /* 0x1d6 */
10226/* File: armv5te/OP_UNUSED_D6FF.S */
10227/* File: armv5te/unused.S */
10228    bl      common_abort
10229
10230
10231/* ------------------------------ */
10232    .balign 64
10233.L_OP_UNUSED_D7FF: /* 0x1d7 */
10234/* File: armv5te/OP_UNUSED_D7FF.S */
10235/* File: armv5te/unused.S */
10236    bl      common_abort
10237
10238
10239/* ------------------------------ */
10240    .balign 64
10241.L_OP_UNUSED_D8FF: /* 0x1d8 */
10242/* File: armv5te/OP_UNUSED_D8FF.S */
10243/* File: armv5te/unused.S */
10244    bl      common_abort
10245
10246
10247/* ------------------------------ */
10248    .balign 64
10249.L_OP_UNUSED_D9FF: /* 0x1d9 */
10250/* File: armv5te/OP_UNUSED_D9FF.S */
10251/* File: armv5te/unused.S */
10252    bl      common_abort
10253
10254
10255/* ------------------------------ */
10256    .balign 64
10257.L_OP_UNUSED_DAFF: /* 0x1da */
10258/* File: armv5te/OP_UNUSED_DAFF.S */
10259/* File: armv5te/unused.S */
10260    bl      common_abort
10261
10262
10263/* ------------------------------ */
10264    .balign 64
10265.L_OP_UNUSED_DBFF: /* 0x1db */
10266/* File: armv5te/OP_UNUSED_DBFF.S */
10267/* File: armv5te/unused.S */
10268    bl      common_abort
10269
10270
10271/* ------------------------------ */
10272    .balign 64
10273.L_OP_UNUSED_DCFF: /* 0x1dc */
10274/* File: armv5te/OP_UNUSED_DCFF.S */
10275/* File: armv5te/unused.S */
10276    bl      common_abort
10277
10278
10279/* ------------------------------ */
10280    .balign 64
10281.L_OP_UNUSED_DDFF: /* 0x1dd */
10282/* File: armv5te/OP_UNUSED_DDFF.S */
10283/* File: armv5te/unused.S */
10284    bl      common_abort
10285
10286
10287/* ------------------------------ */
10288    .balign 64
10289.L_OP_UNUSED_DEFF: /* 0x1de */
10290/* File: armv5te/OP_UNUSED_DEFF.S */
10291/* File: armv5te/unused.S */
10292    bl      common_abort
10293
10294
10295/* ------------------------------ */
10296    .balign 64
10297.L_OP_UNUSED_DFFF: /* 0x1df */
10298/* File: armv5te/OP_UNUSED_DFFF.S */
10299/* File: armv5te/unused.S */
10300    bl      common_abort
10301
10302
10303/* ------------------------------ */
10304    .balign 64
10305.L_OP_UNUSED_E0FF: /* 0x1e0 */
10306/* File: armv5te/OP_UNUSED_E0FF.S */
10307/* File: armv5te/unused.S */
10308    bl      common_abort
10309
10310
10311/* ------------------------------ */
10312    .balign 64
10313.L_OP_UNUSED_E1FF: /* 0x1e1 */
10314/* File: armv5te/OP_UNUSED_E1FF.S */
10315/* File: armv5te/unused.S */
10316    bl      common_abort
10317
10318
10319/* ------------------------------ */
10320    .balign 64
10321.L_OP_UNUSED_E2FF: /* 0x1e2 */
10322/* File: armv5te/OP_UNUSED_E2FF.S */
10323/* File: armv5te/unused.S */
10324    bl      common_abort
10325
10326
10327/* ------------------------------ */
10328    .balign 64
10329.L_OP_UNUSED_E3FF: /* 0x1e3 */
10330/* File: armv5te/OP_UNUSED_E3FF.S */
10331/* File: armv5te/unused.S */
10332    bl      common_abort
10333
10334
10335/* ------------------------------ */
10336    .balign 64
10337.L_OP_UNUSED_E4FF: /* 0x1e4 */
10338/* File: armv5te/OP_UNUSED_E4FF.S */
10339/* File: armv5te/unused.S */
10340    bl      common_abort
10341
10342
10343/* ------------------------------ */
10344    .balign 64
10345.L_OP_UNUSED_E5FF: /* 0x1e5 */
10346/* File: armv5te/OP_UNUSED_E5FF.S */
10347/* File: armv5te/unused.S */
10348    bl      common_abort
10349
10350
10351/* ------------------------------ */
10352    .balign 64
10353.L_OP_UNUSED_E6FF: /* 0x1e6 */
10354/* File: armv5te/OP_UNUSED_E6FF.S */
10355/* File: armv5te/unused.S */
10356    bl      common_abort
10357
10358
10359/* ------------------------------ */
10360    .balign 64
10361.L_OP_UNUSED_E7FF: /* 0x1e7 */
10362/* File: armv5te/OP_UNUSED_E7FF.S */
10363/* File: armv5te/unused.S */
10364    bl      common_abort
10365
10366
10367/* ------------------------------ */
10368    .balign 64
10369.L_OP_UNUSED_E8FF: /* 0x1e8 */
10370/* File: armv5te/OP_UNUSED_E8FF.S */
10371/* File: armv5te/unused.S */
10372    bl      common_abort
10373
10374
10375/* ------------------------------ */
10376    .balign 64
10377.L_OP_UNUSED_E9FF: /* 0x1e9 */
10378/* File: armv5te/OP_UNUSED_E9FF.S */
10379/* File: armv5te/unused.S */
10380    bl      common_abort
10381
10382
10383/* ------------------------------ */
10384    .balign 64
10385.L_OP_UNUSED_EAFF: /* 0x1ea */
10386/* File: armv5te/OP_UNUSED_EAFF.S */
10387/* File: armv5te/unused.S */
10388    bl      common_abort
10389
10390
10391/* ------------------------------ */
10392    .balign 64
10393.L_OP_UNUSED_EBFF: /* 0x1eb */
10394/* File: armv5te/OP_UNUSED_EBFF.S */
10395/* File: armv5te/unused.S */
10396    bl      common_abort
10397
10398
10399/* ------------------------------ */
10400    .balign 64
10401.L_OP_UNUSED_ECFF: /* 0x1ec */
10402/* File: armv5te/OP_UNUSED_ECFF.S */
10403/* File: armv5te/unused.S */
10404    bl      common_abort
10405
10406
10407/* ------------------------------ */
10408    .balign 64
10409.L_OP_UNUSED_EDFF: /* 0x1ed */
10410/* File: armv5te/OP_UNUSED_EDFF.S */
10411/* File: armv5te/unused.S */
10412    bl      common_abort
10413
10414
10415/* ------------------------------ */
10416    .balign 64
10417.L_OP_UNUSED_EEFF: /* 0x1ee */
10418/* File: armv5te/OP_UNUSED_EEFF.S */
10419/* File: armv5te/unused.S */
10420    bl      common_abort
10421
10422
10423/* ------------------------------ */
10424    .balign 64
10425.L_OP_UNUSED_EFFF: /* 0x1ef */
10426/* File: armv5te/OP_UNUSED_EFFF.S */
10427/* File: armv5te/unused.S */
10428    bl      common_abort
10429
10430
10431/* ------------------------------ */
10432    .balign 64
10433.L_OP_UNUSED_F0FF: /* 0x1f0 */
10434/* File: armv5te/OP_UNUSED_F0FF.S */
10435/* File: armv5te/unused.S */
10436    bl      common_abort
10437
10438
10439/* ------------------------------ */
10440    .balign 64
10441.L_OP_UNUSED_F1FF: /* 0x1f1 */
10442/* File: armv5te/OP_UNUSED_F1FF.S */
10443/* File: armv5te/unused.S */
10444    bl      common_abort
10445
10446
10447/* ------------------------------ */
10448    .balign 64
10449.L_OP_UNUSED_F2FF: /* 0x1f2 */
10450/* File: armv5te/OP_UNUSED_F2FF.S */
10451/* File: armv5te/unused.S */
10452    bl      common_abort
10453
10454
10455/* ------------------------------ */
10456    .balign 64
10457.L_OP_UNUSED_F3FF: /* 0x1f3 */
10458/* File: armv5te/OP_UNUSED_F3FF.S */
10459/* File: armv5te/unused.S */
10460    bl      common_abort
10461
10462
10463/* ------------------------------ */
10464    .balign 64
10465.L_OP_UNUSED_F4FF: /* 0x1f4 */
10466/* File: armv5te/OP_UNUSED_F4FF.S */
10467/* File: armv5te/unused.S */
10468    bl      common_abort
10469
10470
10471/* ------------------------------ */
10472    .balign 64
10473.L_OP_UNUSED_F5FF: /* 0x1f5 */
10474/* File: armv5te/OP_UNUSED_F5FF.S */
10475/* File: armv5te/unused.S */
10476    bl      common_abort
10477
10478
10479/* ------------------------------ */
10480    .balign 64
10481.L_OP_UNUSED_F6FF: /* 0x1f6 */
10482/* File: armv5te/OP_UNUSED_F6FF.S */
10483/* File: armv5te/unused.S */
10484    bl      common_abort
10485
10486
10487/* ------------------------------ */
10488    .balign 64
10489.L_OP_UNUSED_F7FF: /* 0x1f7 */
10490/* File: armv5te/OP_UNUSED_F7FF.S */
10491/* File: armv5te/unused.S */
10492    bl      common_abort
10493
10494
10495/* ------------------------------ */
10496    .balign 64
10497.L_OP_UNUSED_F8FF: /* 0x1f8 */
10498/* File: armv5te/OP_UNUSED_F8FF.S */
10499/* File: armv5te/unused.S */
10500    bl      common_abort
10501
10502
10503/* ------------------------------ */
10504    .balign 64
10505.L_OP_UNUSED_F9FF: /* 0x1f9 */
10506/* File: armv5te/OP_UNUSED_F9FF.S */
10507/* File: armv5te/unused.S */
10508    bl      common_abort
10509
10510
10511/* ------------------------------ */
10512    .balign 64
10513.L_OP_UNUSED_FAFF: /* 0x1fa */
10514/* File: armv5te/OP_UNUSED_FAFF.S */
10515/* File: armv5te/unused.S */
10516    bl      common_abort
10517
10518
10519/* ------------------------------ */
10520    .balign 64
10521.L_OP_UNUSED_FBFF: /* 0x1fb */
10522/* File: armv5te/OP_UNUSED_FBFF.S */
10523/* File: armv5te/unused.S */
10524    bl      common_abort
10525
10526
10527/* ------------------------------ */
10528    .balign 64
10529.L_OP_UNUSED_FCFF: /* 0x1fc */
10530/* File: armv5te/OP_UNUSED_FCFF.S */
10531/* File: armv5te/unused.S */
10532    bl      common_abort
10533
10534
10535/* ------------------------------ */
10536    .balign 64
10537.L_OP_UNUSED_FDFF: /* 0x1fd */
10538/* File: armv5te/OP_UNUSED_FDFF.S */
10539/* File: armv5te/unused.S */
10540    bl      common_abort
10541
10542
10543/* ------------------------------ */
10544    .balign 64
10545.L_OP_UNUSED_FEFF: /* 0x1fe */
10546/* File: armv5te/OP_UNUSED_FEFF.S */
10547/* File: armv5te/unused.S */
10548    bl      common_abort
10549
10550
10551/* ------------------------------ */
10552    .balign 64
10553.L_OP_THROW_VERIFICATION_ERROR_JUMBO: /* 0x1ff */
10554/* File: armv5te/OP_THROW_VERIFICATION_ERROR_JUMBO.S */
10555    /*
10556     * Handle a jumbo throw-verification-error instruction.  This throws an
10557     * exception for an error discovered during verification.  The
10558     * exception is indicated by BBBB, with some detail provided by AAAAAAAA.
10559     */
10560    /* exop BBBB, Class@AAAAAAAA */
10561    FETCH(r1, 1)                        @ r1<- aaaa (lo)
10562    FETCH(r2, 2)                        @ r2<- AAAA (hi)
10563    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
10564    orr     r2, r1, r2, lsl #16         @ r2<- AAAAaaaa
10565    EXPORT_PC()                         @ export the PC
10566    FETCH(r1, 3)                        @ r1<- BBBB
10567    bl      dvmThrowVerificationError   @ always throws
10568    b       common_exceptionThrown      @ handle exception
10569
10570
10571    .balign 64
10572    .size   .L_OP_NOP, .-.L_OP_NOP
10573    .global dvmAsmInstructionEnd
10574dvmAsmInstructionEnd:
10575
10576/*
10577 * ===========================================================================
10578 *  Sister implementations
10579 * ===========================================================================
10580 */
10581    .global dvmAsmSisterStart
10582    .type   dvmAsmSisterStart, %function
10583    .text
10584    .balign 4
10585dvmAsmSisterStart:
10586
10587/* continuation for OP_CONST_STRING */
10588
10589    /*
10590     * Continuation if the String has not yet been resolved.
10591     *  r1: BBBB (String ref)
10592     *  r9: target register
10593     */
10594.LOP_CONST_STRING_resolve:
10595    EXPORT_PC()
10596    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
10597    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10598    bl      dvmResolveString            @ r0<- String reference
10599    cmp     r0, #0                      @ failed?
10600    beq     common_exceptionThrown      @ yup, handle the exception
10601    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10602    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10603    SET_VREG(r0, r9)                    @ vAA<- r0
10604    GOTO_OPCODE(ip)                     @ jump to next instruction
10605
10606/* continuation for OP_CONST_STRING_JUMBO */
10607
10608    /*
10609     * Continuation if the String has not yet been resolved.
10610     *  r1: BBBBBBBB (String ref)
10611     *  r9: target register
10612     */
10613.LOP_CONST_STRING_JUMBO_resolve:
10614    EXPORT_PC()
10615    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
10616    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10617    bl      dvmResolveString            @ r0<- String reference
10618    cmp     r0, #0                      @ failed?
10619    beq     common_exceptionThrown      @ yup, handle the exception
10620    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
10621    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10622    SET_VREG(r0, r9)                    @ vAA<- r0
10623    GOTO_OPCODE(ip)                     @ jump to next instruction
10624
10625/* continuation for OP_CONST_CLASS */
10626
10627    /*
10628     * Continuation if the Class has not yet been resolved.
10629     *  r1: BBBB (Class ref)
10630     *  r9: target register
10631     */
10632.LOP_CONST_CLASS_resolve:
10633    EXPORT_PC()
10634    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
10635    mov     r2, #1                      @ r2<- true
10636    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10637    bl      dvmResolveClass             @ r0<- Class reference
10638    cmp     r0, #0                      @ failed?
10639    beq     common_exceptionThrown      @ yup, handle the exception
10640    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10641    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10642    SET_VREG(r0, r9)                    @ vAA<- r0
10643    GOTO_OPCODE(ip)                     @ jump to next instruction
10644
10645/* continuation for OP_CHECK_CAST */
10646
10647    /*
10648     * Trivial test failed, need to perform full check.  This is common.
10649     *  r0 holds obj->clazz
10650     *  r1 holds desired class resolved from BBBB
10651     *  r9 holds object
10652     */
10653.LOP_CHECK_CAST_fullcheck:
10654    mov     r10, r1                     @ avoid ClassObject getting clobbered
10655    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
10656    cmp     r0, #0                      @ failed?
10657    bne     .LOP_CHECK_CAST_okay            @ no, success
10658
10659    @ A cast has failed.  We need to throw a ClassCastException.
10660    EXPORT_PC()                         @ about to throw
10661    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
10662    mov     r1, r10                     @ r1<- desired class
10663    bl      dvmThrowClassCastException
10664    b       common_exceptionThrown
10665
10666    /*
10667     * Resolution required.  This is the least-likely path.
10668     *
10669     *  r2 holds BBBB
10670     *  r9 holds object
10671     */
10672.LOP_CHECK_CAST_resolve:
10673    EXPORT_PC()                         @ resolve() could throw
10674    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
10675    mov     r1, r2                      @ r1<- BBBB
10676    mov     r2, #0                      @ r2<- false
10677    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10678    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10679    cmp     r0, #0                      @ got null?
10680    beq     common_exceptionThrown      @ yes, handle exception
10681    mov     r1, r0                      @ r1<- class resolved from BBB
10682    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
10683    b       .LOP_CHECK_CAST_resolved        @ pick up where we left off
10684
10685/* continuation for OP_INSTANCE_OF */
10686
10687    /*
10688     * Trivial test failed, need to perform full check.  This is common.
10689     *  r0 holds obj->clazz
10690     *  r1 holds class resolved from BBBB
10691     *  r9 holds A
10692     */
10693.LOP_INSTANCE_OF_fullcheck:
10694    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
10695    @ fall through to OP_INSTANCE_OF_store
10696
10697    /*
10698     * r0 holds boolean result
10699     * r9 holds A
10700     */
10701.LOP_INSTANCE_OF_store:
10702    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10703    SET_VREG(r0, r9)                    @ vA<- r0
10704    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10705    GOTO_OPCODE(ip)                     @ jump to next instruction
10706
10707    /*
10708     * Trivial test succeeded, save and bail.
10709     *  r9 holds A
10710     */
10711.LOP_INSTANCE_OF_trivial:
10712    mov     r0, #1                      @ indicate success
10713    @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper
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     * Resolution required.  This is the least-likely path.
10721     *
10722     *  r3 holds BBBB
10723     *  r9 holds A
10724     */
10725.LOP_INSTANCE_OF_resolve:
10726    EXPORT_PC()                         @ resolve() could throw
10727    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
10728    mov     r1, r3                      @ r1<- BBBB
10729    mov     r2, #1                      @ r2<- true
10730    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10731    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10732    cmp     r0, #0                      @ got null?
10733    beq     common_exceptionThrown      @ yes, handle exception
10734    mov     r1, r0                      @ r1<- class resolved from BBB
10735    mov     r3, rINST, lsr #12          @ r3<- B
10736    GET_VREG(r0, r3)                    @ r0<- vB (object)
10737    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
10738    b       .LOP_INSTANCE_OF_resolved        @ pick up where we left off
10739
10740/* continuation for OP_NEW_INSTANCE */
10741
10742    .balign 32                          @ minimize cache lines
10743.LOP_NEW_INSTANCE_finish: @ r0=new object
10744    mov     r3, rINST, lsr #8           @ r3<- AA
10745    cmp     r0, #0                      @ failed?
10746    beq     common_exceptionThrown      @ yes, handle the exception
10747    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10748    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10749    SET_VREG(r0, r3)                    @ vAA<- r0
10750    GOTO_OPCODE(ip)                     @ jump to next instruction
10751
10752    /*
10753     * Class initialization required.
10754     *
10755     *  r0 holds class object
10756     */
10757.LOP_NEW_INSTANCE_needinit:
10758    mov     r9, r0                      @ save r0
10759    bl      dvmInitClass                @ initialize class
10760    cmp     r0, #0                      @ check boolean result
10761    mov     r0, r9                      @ restore r0
10762    bne     .LOP_NEW_INSTANCE_initialized     @ success, continue
10763    b       common_exceptionThrown      @ failed, deal with init exception
10764
10765    /*
10766     * Resolution required.  This is the least-likely path.
10767     *
10768     *  r1 holds BBBB
10769     */
10770.LOP_NEW_INSTANCE_resolve:
10771    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
10772    mov     r2, #0                      @ r2<- false
10773    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10774    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10775    cmp     r0, #0                      @ got null?
10776    bne     .LOP_NEW_INSTANCE_resolved        @ no, continue
10777    b       common_exceptionThrown      @ yes, handle exception
10778
10779.LstrInstantiationErrorPtr:
10780    .word   .LstrInstantiationError
10781
10782/* continuation for OP_NEW_ARRAY */
10783
10784
10785    /*
10786     * Resolve class.  (This is an uncommon case.)
10787     *
10788     *  r1 holds array length
10789     *  r2 holds class ref CCCC
10790     */
10791.LOP_NEW_ARRAY_resolve:
10792    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
10793    mov     r9, r1                      @ r9<- length (save)
10794    mov     r1, r2                      @ r1<- CCCC
10795    mov     r2, #0                      @ r2<- false
10796    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10797    bl      dvmResolveClass             @ r0<- call(clazz, ref)
10798    cmp     r0, #0                      @ got null?
10799    mov     r1, r9                      @ r1<- length (restore)
10800    beq     common_exceptionThrown      @ yes, handle exception
10801    @ fall through to OP_NEW_ARRAY_finish
10802
10803    /*
10804     * Finish allocation.
10805     *
10806     *  r0 holds class
10807     *  r1 holds array length
10808     */
10809.LOP_NEW_ARRAY_finish:
10810    mov     r2, #ALLOC_DONT_TRACK       @ don't track in local refs table
10811    bl      dvmAllocArrayByClass        @ r0<- call(clazz, length, flags)
10812    cmp     r0, #0                      @ failed?
10813    mov     r2, rINST, lsr #8           @ r2<- A+
10814    beq     common_exceptionThrown      @ yes, handle the exception
10815    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10816    and     r2, r2, #15                 @ r2<- A
10817    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10818    SET_VREG(r0, r2)                    @ vA<- r0
10819    GOTO_OPCODE(ip)                     @ jump to next instruction
10820
10821/* continuation for OP_FILLED_NEW_ARRAY */
10822
10823    /*
10824     * On entry:
10825     *  r0 holds array class
10826     *  r10 holds AA or BA
10827     */
10828.LOP_FILLED_NEW_ARRAY_continue:
10829    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
10830    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
10831    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
10832    .if     0
10833    mov     r1, r10                     @ r1<- AA (length)
10834    .else
10835    mov     r1, r10, lsr #4             @ r1<- B (length)
10836    .endif
10837    cmp     rINST, #'I'                 @ array of ints?
10838    cmpne   rINST, #'L'                 @ array of objects?
10839    cmpne   rINST, #'['                 @ array of arrays?
10840    mov     r9, r1                      @ save length in r9
10841    bne     .LOP_FILLED_NEW_ARRAY_notimpl         @ no, not handled yet
10842    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
10843    cmp     r0, #0                      @ null return?
10844    beq     common_exceptionThrown      @ alloc failed, handle exception
10845
10846    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
10847    str     r0, [rGLUE, #offGlue_retval]      @ retval.l <- new array
10848    str     rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type
10849    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
10850    subs    r9, r9, #1                  @ length--, check for neg
10851    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
10852    bmi     2f                          @ was zero, bail
10853
10854    @ copy values from registers into the array
10855    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
10856    .if     0
10857    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
108581:  ldr     r3, [r2], #4                @ r3<- *r2++
10859    subs    r9, r9, #1                  @ count--
10860    str     r3, [r0], #4                @ *contents++ = vX
10861    bpl     1b
10862    @ continue at 2
10863    .else
10864    cmp     r9, #4                      @ length was initially 5?
10865    and     r2, r10, #15                @ r2<- A
10866    bne     1f                          @ <= 4 args, branch
10867    GET_VREG(r3, r2)                    @ r3<- vA
10868    sub     r9, r9, #1                  @ count--
10869    str     r3, [r0, #16]               @ contents[4] = vA
108701:  and     r2, r1, #15                 @ r2<- F/E/D/C
10871    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
10872    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
10873    subs    r9, r9, #1                  @ count--
10874    str     r3, [r0], #4                @ *contents++ = vX
10875    bpl     1b
10876    @ continue at 2
10877    .endif
10878
108792:
10880    ldr     r0, [rGLUE, #offGlue_retval]     @ r0<- object
10881    ldr     r1, [rGLUE, #offGlue_retval+4]   @ r1<- type
10882    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
10883    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
10884    cmp     r1, #'I'                         @ Is int array?
10885    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
10886    GOTO_OPCODE(ip)                          @ execute it
10887
10888    /*
10889     * Throw an exception indicating that we have not implemented this
10890     * mode of filled-new-array.
10891     */
10892.LOP_FILLED_NEW_ARRAY_notimpl:
10893    ldr     r0, .L_strInternalError
10894    ldr     r1, .L_strFilledNewArrayNotImpl
10895    bl      dvmThrowException
10896    b       common_exceptionThrown
10897
10898    .if     (!0)                 @ define in one or the other, not both
10899.L_strFilledNewArrayNotImpl:
10900    .word   .LstrFilledNewArrayNotImpl
10901.L_strInternalError:
10902    .word   .LstrInternalError
10903    .endif
10904
10905/* continuation for OP_FILLED_NEW_ARRAY_RANGE */
10906
10907    /*
10908     * On entry:
10909     *  r0 holds array class
10910     *  r10 holds AA or BA
10911     */
10912.LOP_FILLED_NEW_ARRAY_RANGE_continue:
10913    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
10914    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
10915    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
10916    .if     1
10917    mov     r1, r10                     @ r1<- AA (length)
10918    .else
10919    mov     r1, r10, lsr #4             @ r1<- B (length)
10920    .endif
10921    cmp     rINST, #'I'                 @ array of ints?
10922    cmpne   rINST, #'L'                 @ array of objects?
10923    cmpne   rINST, #'['                 @ array of arrays?
10924    mov     r9, r1                      @ save length in r9
10925    bne     .LOP_FILLED_NEW_ARRAY_RANGE_notimpl         @ no, not handled yet
10926    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
10927    cmp     r0, #0                      @ null return?
10928    beq     common_exceptionThrown      @ alloc failed, handle exception
10929
10930    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
10931    str     r0, [rGLUE, #offGlue_retval]      @ retval.l <- new array
10932    str     rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type
10933    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
10934    subs    r9, r9, #1                  @ length--, check for neg
10935    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
10936    bmi     2f                          @ was zero, bail
10937
10938    @ copy values from registers into the array
10939    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
10940    .if     1
10941    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
109421:  ldr     r3, [r2], #4                @ r3<- *r2++
10943    subs    r9, r9, #1                  @ count--
10944    str     r3, [r0], #4                @ *contents++ = vX
10945    bpl     1b
10946    @ continue at 2
10947    .else
10948    cmp     r9, #4                      @ length was initially 5?
10949    and     r2, r10, #15                @ r2<- A
10950    bne     1f                          @ <= 4 args, branch
10951    GET_VREG(r3, r2)                    @ r3<- vA
10952    sub     r9, r9, #1                  @ count--
10953    str     r3, [r0, #16]               @ contents[4] = vA
109541:  and     r2, r1, #15                 @ r2<- F/E/D/C
10955    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
10956    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
10957    subs    r9, r9, #1                  @ count--
10958    str     r3, [r0], #4                @ *contents++ = vX
10959    bpl     1b
10960    @ continue at 2
10961    .endif
10962
109632:
10964    ldr     r0, [rGLUE, #offGlue_retval]     @ r0<- object
10965    ldr     r1, [rGLUE, #offGlue_retval+4]   @ r1<- type
10966    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
10967    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
10968    cmp     r1, #'I'                         @ Is int array?
10969    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
10970    GOTO_OPCODE(ip)                          @ execute it
10971
10972    /*
10973     * Throw an exception indicating that we have not implemented this
10974     * mode of filled-new-array.
10975     */
10976.LOP_FILLED_NEW_ARRAY_RANGE_notimpl:
10977    ldr     r0, .L_strInternalError
10978    ldr     r1, .L_strFilledNewArrayNotImpl
10979    bl      dvmThrowException
10980    b       common_exceptionThrown
10981
10982    .if     (!1)                 @ define in one or the other, not both
10983.L_strFilledNewArrayNotImpl:
10984    .word   .LstrFilledNewArrayNotImpl
10985.L_strInternalError:
10986    .word   .LstrInternalError
10987    .endif
10988
10989/* continuation for OP_CMPL_FLOAT */
10990.LOP_CMPL_FLOAT_finish:
10991    SET_VREG(r0, r9)                    @ vAA<- r0
10992    GOTO_OPCODE(ip)                     @ jump to next instruction
10993
10994/* continuation for OP_CMPG_FLOAT */
10995.LOP_CMPG_FLOAT_finish:
10996    SET_VREG(r0, r9)                    @ vAA<- r0
10997    GOTO_OPCODE(ip)                     @ jump to next instruction
10998
10999/* continuation for OP_CMPL_DOUBLE */
11000.LOP_CMPL_DOUBLE_finish:
11001    SET_VREG(r0, r9)                    @ vAA<- r0
11002    GOTO_OPCODE(ip)                     @ jump to next instruction
11003
11004/* continuation for OP_CMPG_DOUBLE */
11005.LOP_CMPG_DOUBLE_finish:
11006    SET_VREG(r0, r9)                    @ vAA<- r0
11007    GOTO_OPCODE(ip)                     @ jump to next instruction
11008
11009/* continuation for OP_CMP_LONG */
11010
11011.LOP_CMP_LONG_less:
11012    mvn     r1, #0                      @ r1<- -1
11013    @ Want to cond code the next mov so we can avoid branch, but don't see it;
11014    @ instead, we just replicate the tail end.
11015    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11016    SET_VREG(r1, r9)                    @ vAA<- r1
11017    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11018    GOTO_OPCODE(ip)                     @ jump to next instruction
11019
11020.LOP_CMP_LONG_greater:
11021    mov     r1, #1                      @ r1<- 1
11022    @ fall through to _finish
11023
11024.LOP_CMP_LONG_finish:
11025    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11026    SET_VREG(r1, r9)                    @ vAA<- r1
11027    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11028    GOTO_OPCODE(ip)                     @ jump to next instruction
11029
11030/* continuation for OP_AGET_WIDE */
11031
11032.LOP_AGET_WIDE_finish:
11033    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11034    ldrd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
11035    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
11036    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11037    stmia   r9, {r2-r3}                 @ vAA/vAA+1<- r2/r3
11038    GOTO_OPCODE(ip)                     @ jump to next instruction
11039
11040/* continuation for OP_APUT_WIDE */
11041
11042.LOP_APUT_WIDE_finish:
11043    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11044    ldmia   r9, {r2-r3}                 @ r2/r3<- vAA/vAA+1
11045    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11046    strd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
11047    GOTO_OPCODE(ip)                     @ jump to next instruction
11048
11049/* continuation for OP_APUT_OBJECT */
11050    /*
11051     * On entry:
11052     *  rINST = vBB (arrayObj)
11053     *  r9 = vAA (obj)
11054     *  r10 = offset into array (vBB + vCC * width)
11055     */
11056.LOP_APUT_OBJECT_finish:
11057    cmp     r9, #0                      @ storing null reference?
11058    beq     .LOP_APUT_OBJECT_skip_check      @ yes, skip type checks
11059    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
11060    ldr     r1, [rINST, #offObject_clazz]  @ r1<- arrayObj->clazz
11061    bl      dvmCanPutArrayElement       @ test object type vs. array type
11062    cmp     r0, #0                      @ okay?
11063    beq     .LOP_APUT_OBJECT_throw           @ no
11064    mov     r1, rINST                   @ r1<- arrayObj
11065    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11066    ldr     r2, [rGLUE, #offGlue_cardTable]     @ get biased CT base
11067    add     r10, #offArrayObject_contents   @ r0<- pointer to slot
11068    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11069    str     r9, [r10]                   @ vBB[vCC]<- vAA
11070    strb    r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head
11071    GOTO_OPCODE(ip)                     @ jump to next instruction
11072.LOP_APUT_OBJECT_skip_check:
11073    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11074    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11075    str     r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA
11076    GOTO_OPCODE(ip)                     @ jump to next instruction
11077.LOP_APUT_OBJECT_throw:
11078    @ The types don't match.  We need to throw an ArrayStoreException.
11079    ldr     r0, [r9, #offObject_clazz]
11080    ldr     r1, [rINST, #offObject_clazz]
11081    EXPORT_PC()
11082    bl      dvmThrowArrayStoreException
11083    b       common_exceptionThrown
11084
11085/* continuation for OP_IGET */
11086
11087    /*
11088     * Currently:
11089     *  r0 holds resolved field
11090     *  r9 holds object
11091     */
11092.LOP_IGET_finish:
11093    @bl      common_squeak0
11094    cmp     r9, #0                      @ check object for null
11095    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11096    beq     common_errNullObject        @ object was null
11097    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11098    @ no-op                             @ acquiring load
11099    mov     r2, rINST, lsr #8           @ r2<- A+
11100    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11101    and     r2, r2, #15                 @ r2<- A
11102    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11103    SET_VREG(r0, r2)                    @ fp[A]<- r0
11104    GOTO_OPCODE(ip)                     @ jump to next instruction
11105
11106/* continuation for OP_IGET_WIDE */
11107
11108    /*
11109     * Currently:
11110     *  r0 holds resolved field
11111     *  r9 holds object
11112     */
11113.LOP_IGET_WIDE_finish:
11114    cmp     r9, #0                      @ check object for null
11115    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11116    beq     common_errNullObject        @ object was null
11117    .if     0
11118    add     r0, r9, r3                  @ r0<- address of field
11119    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
11120    .else
11121    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
11122    .endif
11123    mov     r2, rINST, lsr #8           @ r2<- A+
11124    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11125    and     r2, r2, #15                 @ r2<- A
11126    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
11127    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11128    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
11129    GOTO_OPCODE(ip)                     @ jump to next instruction
11130
11131/* continuation for OP_IGET_OBJECT */
11132
11133    /*
11134     * Currently:
11135     *  r0 holds resolved field
11136     *  r9 holds object
11137     */
11138.LOP_IGET_OBJECT_finish:
11139    @bl      common_squeak0
11140    cmp     r9, #0                      @ check object for null
11141    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11142    beq     common_errNullObject        @ object was null
11143    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11144    @ no-op                             @ acquiring load
11145    mov     r2, rINST, lsr #8           @ r2<- A+
11146    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11147    and     r2, r2, #15                 @ r2<- A
11148    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11149    SET_VREG(r0, r2)                    @ fp[A]<- r0
11150    GOTO_OPCODE(ip)                     @ jump to next instruction
11151
11152/* continuation for OP_IGET_BOOLEAN */
11153
11154    /*
11155     * Currently:
11156     *  r0 holds resolved field
11157     *  r9 holds object
11158     */
11159.LOP_IGET_BOOLEAN_finish:
11160    @bl      common_squeak1
11161    cmp     r9, #0                      @ check object for null
11162    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11163    beq     common_errNullObject        @ object was null
11164    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11165    @ no-op                             @ acquiring load
11166    mov     r2, rINST, lsr #8           @ r2<- A+
11167    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11168    and     r2, r2, #15                 @ r2<- A
11169    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11170    SET_VREG(r0, r2)                    @ fp[A]<- r0
11171    GOTO_OPCODE(ip)                     @ jump to next instruction
11172
11173/* continuation for OP_IGET_BYTE */
11174
11175    /*
11176     * Currently:
11177     *  r0 holds resolved field
11178     *  r9 holds object
11179     */
11180.LOP_IGET_BYTE_finish:
11181    @bl      common_squeak2
11182    cmp     r9, #0                      @ check object for null
11183    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11184    beq     common_errNullObject        @ object was null
11185    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11186    @ no-op                             @ acquiring load
11187    mov     r2, rINST, lsr #8           @ r2<- A+
11188    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11189    and     r2, r2, #15                 @ r2<- A
11190    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11191    SET_VREG(r0, r2)                    @ fp[A]<- r0
11192    GOTO_OPCODE(ip)                     @ jump to next instruction
11193
11194/* continuation for OP_IGET_CHAR */
11195
11196    /*
11197     * Currently:
11198     *  r0 holds resolved field
11199     *  r9 holds object
11200     */
11201.LOP_IGET_CHAR_finish:
11202    @bl      common_squeak3
11203    cmp     r9, #0                      @ check object for null
11204    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11205    beq     common_errNullObject        @ object was null
11206    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11207    @ no-op                             @ acquiring load
11208    mov     r2, rINST, lsr #8           @ r2<- A+
11209    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11210    and     r2, r2, #15                 @ r2<- A
11211    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11212    SET_VREG(r0, r2)                    @ fp[A]<- r0
11213    GOTO_OPCODE(ip)                     @ jump to next instruction
11214
11215/* continuation for OP_IGET_SHORT */
11216
11217    /*
11218     * Currently:
11219     *  r0 holds resolved field
11220     *  r9 holds object
11221     */
11222.LOP_IGET_SHORT_finish:
11223    @bl      common_squeak4
11224    cmp     r9, #0                      @ check object for null
11225    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11226    beq     common_errNullObject        @ object was null
11227    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11228    @ no-op                             @ acquiring load
11229    mov     r2, rINST, lsr #8           @ r2<- A+
11230    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11231    and     r2, r2, #15                 @ r2<- A
11232    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11233    SET_VREG(r0, r2)                    @ fp[A]<- r0
11234    GOTO_OPCODE(ip)                     @ jump to next instruction
11235
11236/* continuation for OP_IPUT */
11237
11238    /*
11239     * Currently:
11240     *  r0 holds resolved field
11241     *  r9 holds object
11242     */
11243.LOP_IPUT_finish:
11244    @bl      common_squeak0
11245    mov     r1, rINST, lsr #8           @ r1<- A+
11246    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11247    and     r1, r1, #15                 @ r1<- A
11248    cmp     r9, #0                      @ check object for null
11249    GET_VREG(r0, r1)                    @ r0<- fp[A]
11250    beq     common_errNullObject        @ object was null
11251    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11252    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11253    @ no-op                             @ releasing store
11254    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11255    GOTO_OPCODE(ip)                     @ jump to next instruction
11256
11257/* continuation for OP_IPUT_WIDE */
11258
11259    /*
11260     * Currently:
11261     *  r0 holds resolved field
11262     *  r9 holds object
11263     */
11264.LOP_IPUT_WIDE_finish:
11265    mov     r2, rINST, lsr #8           @ r2<- A+
11266    cmp     r9, #0                      @ check object for null
11267    and     r2, r2, #15                 @ r2<- A
11268    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11269    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
11270    beq     common_errNullObject        @ object was null
11271    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11272    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
11273    GET_INST_OPCODE(r10)                @ extract opcode from rINST
11274    .if     0
11275    add     r2, r9, r3                  @ r2<- target address
11276    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
11277    .else
11278    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
11279    .endif
11280    GOTO_OPCODE(r10)                    @ jump to next instruction
11281
11282/* continuation for OP_IPUT_OBJECT */
11283
11284    /*
11285     * Currently:
11286     *  r0 holds resolved field
11287     *  r9 holds object
11288     */
11289.LOP_IPUT_OBJECT_finish:
11290    @bl      common_squeak0
11291    mov     r1, rINST, lsr #8           @ r1<- A+
11292    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11293    and     r1, r1, #15                 @ r1<- A
11294    cmp     r9, #0                      @ check object for null
11295    GET_VREG(r0, r1)                    @ r0<- fp[A]
11296    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
11297    beq     common_errNullObject        @ object was null
11298    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11299    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11300    @ no-op                             @ releasing store
11301    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
11302    cmp     r0, #0                      @ stored a null reference?
11303    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
11304    GOTO_OPCODE(ip)                     @ jump to next instruction
11305
11306/* continuation for OP_IPUT_BOOLEAN */
11307
11308    /*
11309     * Currently:
11310     *  r0 holds resolved field
11311     *  r9 holds object
11312     */
11313.LOP_IPUT_BOOLEAN_finish:
11314    @bl      common_squeak1
11315    mov     r1, rINST, lsr #8           @ r1<- A+
11316    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11317    and     r1, r1, #15                 @ r1<- A
11318    cmp     r9, #0                      @ check object for null
11319    GET_VREG(r0, r1)                    @ r0<- fp[A]
11320    beq     common_errNullObject        @ object was null
11321    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11322    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11323    @ no-op                             @ releasing store
11324    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11325    GOTO_OPCODE(ip)                     @ jump to next instruction
11326
11327/* continuation for OP_IPUT_BYTE */
11328
11329    /*
11330     * Currently:
11331     *  r0 holds resolved field
11332     *  r9 holds object
11333     */
11334.LOP_IPUT_BYTE_finish:
11335    @bl      common_squeak2
11336    mov     r1, rINST, lsr #8           @ r1<- A+
11337    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11338    and     r1, r1, #15                 @ r1<- A
11339    cmp     r9, #0                      @ check object for null
11340    GET_VREG(r0, r1)                    @ r0<- fp[A]
11341    beq     common_errNullObject        @ object was null
11342    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11343    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11344    @ no-op                             @ releasing store
11345    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11346    GOTO_OPCODE(ip)                     @ jump to next instruction
11347
11348/* continuation for OP_IPUT_CHAR */
11349
11350    /*
11351     * Currently:
11352     *  r0 holds resolved field
11353     *  r9 holds object
11354     */
11355.LOP_IPUT_CHAR_finish:
11356    @bl      common_squeak3
11357    mov     r1, rINST, lsr #8           @ r1<- A+
11358    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11359    and     r1, r1, #15                 @ r1<- A
11360    cmp     r9, #0                      @ check object for null
11361    GET_VREG(r0, r1)                    @ r0<- fp[A]
11362    beq     common_errNullObject        @ object was null
11363    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11364    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11365    @ no-op                             @ releasing store
11366    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11367    GOTO_OPCODE(ip)                     @ jump to next instruction
11368
11369/* continuation for OP_IPUT_SHORT */
11370
11371    /*
11372     * Currently:
11373     *  r0 holds resolved field
11374     *  r9 holds object
11375     */
11376.LOP_IPUT_SHORT_finish:
11377    @bl      common_squeak4
11378    mov     r1, rINST, lsr #8           @ r1<- A+
11379    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11380    and     r1, r1, #15                 @ r1<- A
11381    cmp     r9, #0                      @ check object for null
11382    GET_VREG(r0, r1)                    @ r0<- fp[A]
11383    beq     common_errNullObject        @ object was null
11384    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11385    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11386    @ no-op                             @ releasing store
11387    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11388    GOTO_OPCODE(ip)                     @ jump to next instruction
11389
11390/* continuation for OP_SGET */
11391
11392    /*
11393     * Continuation if the field has not yet been resolved.
11394     *  r1: BBBB field ref
11395     */
11396.LOP_SGET_resolve:
11397    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11398    EXPORT_PC()                         @ resolve() could throw, so export now
11399    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11400    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11401    cmp     r0, #0                      @ success?
11402    bne     .LOP_SGET_finish          @ yes, finish
11403    b       common_exceptionThrown      @ no, handle exception
11404
11405/* continuation for OP_SGET_WIDE */
11406
11407    /*
11408     * Continuation if the field has not yet been resolved.
11409     *  r1: BBBB field ref
11410     *
11411     * Returns StaticField pointer in r0.
11412     */
11413.LOP_SGET_WIDE_resolve:
11414    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11415    EXPORT_PC()                         @ resolve() could throw, so export now
11416    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11417    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11418    cmp     r0, #0                      @ success?
11419    bne     .LOP_SGET_WIDE_finish          @ yes, finish
11420    b       common_exceptionThrown      @ no, handle exception
11421
11422/* continuation for OP_SGET_OBJECT */
11423
11424    /*
11425     * Continuation if the field has not yet been resolved.
11426     *  r1: BBBB field ref
11427     */
11428.LOP_SGET_OBJECT_resolve:
11429    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11430    EXPORT_PC()                         @ resolve() could throw, so export now
11431    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11432    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11433    cmp     r0, #0                      @ success?
11434    bne     .LOP_SGET_OBJECT_finish          @ yes, finish
11435    b       common_exceptionThrown      @ no, handle exception
11436
11437/* continuation for OP_SGET_BOOLEAN */
11438
11439    /*
11440     * Continuation if the field has not yet been resolved.
11441     *  r1: BBBB field ref
11442     */
11443.LOP_SGET_BOOLEAN_resolve:
11444    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11445    EXPORT_PC()                         @ resolve() could throw, so export now
11446    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11447    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11448    cmp     r0, #0                      @ success?
11449    bne     .LOP_SGET_BOOLEAN_finish          @ yes, finish
11450    b       common_exceptionThrown      @ no, handle exception
11451
11452/* continuation for OP_SGET_BYTE */
11453
11454    /*
11455     * Continuation if the field has not yet been resolved.
11456     *  r1: BBBB field ref
11457     */
11458.LOP_SGET_BYTE_resolve:
11459    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11460    EXPORT_PC()                         @ resolve() could throw, so export now
11461    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11462    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11463    cmp     r0, #0                      @ success?
11464    bne     .LOP_SGET_BYTE_finish          @ yes, finish
11465    b       common_exceptionThrown      @ no, handle exception
11466
11467/* continuation for OP_SGET_CHAR */
11468
11469    /*
11470     * Continuation if the field has not yet been resolved.
11471     *  r1: BBBB field ref
11472     */
11473.LOP_SGET_CHAR_resolve:
11474    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11475    EXPORT_PC()                         @ resolve() could throw, so export now
11476    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11477    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11478    cmp     r0, #0                      @ success?
11479    bne     .LOP_SGET_CHAR_finish          @ yes, finish
11480    b       common_exceptionThrown      @ no, handle exception
11481
11482/* continuation for OP_SGET_SHORT */
11483
11484    /*
11485     * Continuation if the field has not yet been resolved.
11486     *  r1: BBBB field ref
11487     */
11488.LOP_SGET_SHORT_resolve:
11489    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11490    EXPORT_PC()                         @ resolve() could throw, so export now
11491    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11492    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11493    cmp     r0, #0                      @ success?
11494    bne     .LOP_SGET_SHORT_finish          @ yes, finish
11495    b       common_exceptionThrown      @ no, handle exception
11496
11497/* continuation for OP_SPUT */
11498
11499    /*
11500     * Continuation if the field has not yet been resolved.
11501     *  r1: BBBB field ref
11502     */
11503.LOP_SPUT_resolve:
11504    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11505    EXPORT_PC()                         @ resolve() could throw, so export now
11506    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11507    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11508    cmp     r0, #0                      @ success?
11509    bne     .LOP_SPUT_finish          @ yes, finish
11510    b       common_exceptionThrown      @ no, handle exception
11511
11512/* continuation for OP_SPUT_WIDE */
11513
11514    /*
11515     * Continuation if the field has not yet been resolved.
11516     *  r1: BBBB field ref
11517     *  r9: &fp[AA]
11518     *
11519     * Returns StaticField pointer in r2.
11520     */
11521.LOP_SPUT_WIDE_resolve:
11522    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11523    EXPORT_PC()                         @ resolve() could throw, so export now
11524    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11525    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11526    cmp     r0, #0                      @ success?
11527    mov     r2, r0                      @ copy to r2
11528    bne     .LOP_SPUT_WIDE_finish          @ yes, finish
11529    b       common_exceptionThrown      @ no, handle exception
11530
11531/* continuation for OP_SPUT_OBJECT */
11532.LOP_SPUT_OBJECT_finish:   @ field ptr in r0
11533    mov     r2, rINST, lsr #8           @ r2<- AA
11534    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11535    GET_VREG(r1, r2)                    @ r1<- fp[AA]
11536    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
11537    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
11538    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11539    @ no-op                             @ releasing store
11540    str     r1, [r0, #offStaticField_value]  @ field<- vAA
11541    cmp     r1, #0                      @ stored a null object?
11542    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
11543    GOTO_OPCODE(ip)                     @ jump to next instruction
11544
11545/* continuation for OP_SPUT_BOOLEAN */
11546
11547    /*
11548     * Continuation if the field has not yet been resolved.
11549     *  r1: BBBB field ref
11550     */
11551.LOP_SPUT_BOOLEAN_resolve:
11552    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11553    EXPORT_PC()                         @ resolve() could throw, so export now
11554    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11555    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11556    cmp     r0, #0                      @ success?
11557    bne     .LOP_SPUT_BOOLEAN_finish          @ yes, finish
11558    b       common_exceptionThrown      @ no, handle exception
11559
11560/* continuation for OP_SPUT_BYTE */
11561
11562    /*
11563     * Continuation if the field has not yet been resolved.
11564     *  r1: BBBB field ref
11565     */
11566.LOP_SPUT_BYTE_resolve:
11567    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11568    EXPORT_PC()                         @ resolve() could throw, so export now
11569    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11570    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11571    cmp     r0, #0                      @ success?
11572    bne     .LOP_SPUT_BYTE_finish          @ yes, finish
11573    b       common_exceptionThrown      @ no, handle exception
11574
11575/* continuation for OP_SPUT_CHAR */
11576
11577    /*
11578     * Continuation if the field has not yet been resolved.
11579     *  r1: BBBB field ref
11580     */
11581.LOP_SPUT_CHAR_resolve:
11582    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11583    EXPORT_PC()                         @ resolve() could throw, so export now
11584    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11585    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11586    cmp     r0, #0                      @ success?
11587    bne     .LOP_SPUT_CHAR_finish          @ yes, finish
11588    b       common_exceptionThrown      @ no, handle exception
11589
11590/* continuation for OP_SPUT_SHORT */
11591
11592    /*
11593     * Continuation if the field has not yet been resolved.
11594     *  r1: BBBB field ref
11595     */
11596.LOP_SPUT_SHORT_resolve:
11597    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11598    EXPORT_PC()                         @ resolve() could throw, so export now
11599    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11600    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11601    cmp     r0, #0                      @ success?
11602    bne     .LOP_SPUT_SHORT_finish          @ yes, finish
11603    b       common_exceptionThrown      @ no, handle exception
11604
11605/* continuation for OP_INVOKE_VIRTUAL */
11606
11607    /*
11608     * At this point:
11609     *  r0 = resolved base method
11610     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
11611     */
11612.LOP_INVOKE_VIRTUAL_continue:
11613    GET_VREG(r1, r10)                   @ r1<- "this" ptr
11614    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11615    cmp     r1, #0                      @ is "this" null?
11616    beq     common_errNullObject        @ null "this", throw exception
11617    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
11618    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
11619    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
11620    bl      common_invokeMethodNoRange @ continue on
11621
11622/* continuation for OP_INVOKE_SUPER */
11623
11624    /*
11625     * At this point:
11626     *  r0 = resolved base method
11627     *  r9 = method->clazz
11628     */
11629.LOP_INVOKE_SUPER_continue:
11630    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
11631    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11632    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
11633    EXPORT_PC()                         @ must export for invoke
11634    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
11635    bcs     .LOP_INVOKE_SUPER_nsm             @ method not present in superclass
11636    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
11637    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
11638    bl      common_invokeMethodNoRange @ continue on
11639
11640.LOP_INVOKE_SUPER_resolve:
11641    mov     r0, r9                      @ r0<- method->clazz
11642    mov     r2, #METHOD_VIRTUAL         @ resolver method type
11643    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11644    cmp     r0, #0                      @ got null?
11645    bne     .LOP_INVOKE_SUPER_continue        @ no, continue
11646    b       common_exceptionThrown      @ yes, handle exception
11647
11648    /*
11649     * Throw a NoSuchMethodError with the method name as the message.
11650     *  r0 = resolved base method
11651     */
11652.LOP_INVOKE_SUPER_nsm:
11653    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
11654    b       common_errNoSuchMethod
11655
11656/* continuation for OP_INVOKE_DIRECT */
11657
11658    /*
11659     * On entry:
11660     *  r1 = reference (BBBB or CCCC)
11661     *  r10 = "this" register
11662     */
11663.LOP_INVOKE_DIRECT_resolve:
11664    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
11665    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
11666    mov     r2, #METHOD_DIRECT          @ resolver method type
11667    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11668    cmp     r0, #0                      @ got null?
11669    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
11670    bne     .LOP_INVOKE_DIRECT_finish          @ no, continue
11671    b       common_exceptionThrown      @ yes, handle exception
11672
11673/* continuation for OP_INVOKE_VIRTUAL_RANGE */
11674
11675    /*
11676     * At this point:
11677     *  r0 = resolved base method
11678     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
11679     */
11680.LOP_INVOKE_VIRTUAL_RANGE_continue:
11681    GET_VREG(r1, r10)                   @ r1<- "this" ptr
11682    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11683    cmp     r1, #0                      @ is "this" null?
11684    beq     common_errNullObject        @ null "this", throw exception
11685    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
11686    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
11687    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
11688    bl      common_invokeMethodRange @ continue on
11689
11690/* continuation for OP_INVOKE_SUPER_RANGE */
11691
11692    /*
11693     * At this point:
11694     *  r0 = resolved base method
11695     *  r9 = method->clazz
11696     */
11697.LOP_INVOKE_SUPER_RANGE_continue:
11698    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
11699    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11700    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
11701    EXPORT_PC()                         @ must export for invoke
11702    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
11703    bcs     .LOP_INVOKE_SUPER_RANGE_nsm             @ method not present in superclass
11704    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
11705    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
11706    bl      common_invokeMethodRange @ continue on
11707
11708.LOP_INVOKE_SUPER_RANGE_resolve:
11709    mov     r0, r9                      @ r0<- method->clazz
11710    mov     r2, #METHOD_VIRTUAL         @ resolver method type
11711    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11712    cmp     r0, #0                      @ got null?
11713    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ no, continue
11714    b       common_exceptionThrown      @ yes, handle exception
11715
11716    /*
11717     * Throw a NoSuchMethodError with the method name as the message.
11718     *  r0 = resolved base method
11719     */
11720.LOP_INVOKE_SUPER_RANGE_nsm:
11721    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
11722    b       common_errNoSuchMethod
11723
11724/* continuation for OP_INVOKE_DIRECT_RANGE */
11725
11726    /*
11727     * On entry:
11728     *  r1 = reference (BBBB or CCCC)
11729     *  r10 = "this" register
11730     */
11731.LOP_INVOKE_DIRECT_RANGE_resolve:
11732    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
11733    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
11734    mov     r2, #METHOD_DIRECT          @ resolver method type
11735    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11736    cmp     r0, #0                      @ got null?
11737    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
11738    bne     .LOP_INVOKE_DIRECT_RANGE_finish          @ no, continue
11739    b       common_exceptionThrown      @ yes, handle exception
11740
11741/* continuation for OP_FLOAT_TO_LONG */
11742/*
11743 * Convert the float in r0 to a long in r0/r1.
11744 *
11745 * We have to clip values to long min/max per the specification.  The
11746 * expected common case is a "reasonable" value that converts directly
11747 * to modest integer.  The EABI convert function isn't doing this for us.
11748 */
11749f2l_doconv:
11750    stmfd   sp!, {r4, lr}
11751    mov     r1, #0x5f000000             @ (float)maxlong
11752    mov     r4, r0
11753    bl      __aeabi_fcmpge              @ is arg >= maxlong?
11754    cmp     r0, #0                      @ nonzero == yes
11755    mvnne   r0, #0                      @ return maxlong (7fffffff)
11756    mvnne   r1, #0x80000000
11757    ldmnefd sp!, {r4, pc}
11758
11759    mov     r0, r4                      @ recover arg
11760    mov     r1, #0xdf000000             @ (float)minlong
11761    bl      __aeabi_fcmple              @ is arg <= minlong?
11762    cmp     r0, #0                      @ nonzero == yes
11763    movne   r0, #0                      @ return minlong (80000000)
11764    movne   r1, #0x80000000
11765    ldmnefd sp!, {r4, pc}
11766
11767    mov     r0, r4                      @ recover arg
11768    mov     r1, r4
11769    bl      __aeabi_fcmpeq              @ is arg == self?
11770    cmp     r0, #0                      @ zero == no
11771    moveq   r1, #0                      @ return zero for NaN
11772    ldmeqfd sp!, {r4, pc}
11773
11774    mov     r0, r4                      @ recover arg
11775    bl      __aeabi_f2lz                @ convert float to long
11776    ldmfd   sp!, {r4, pc}
11777
11778/* continuation for OP_DOUBLE_TO_LONG */
11779/*
11780 * Convert the double in r0/r1 to a long in r0/r1.
11781 *
11782 * We have to clip values to long min/max per the specification.  The
11783 * expected common case is a "reasonable" value that converts directly
11784 * to modest integer.  The EABI convert function isn't doing this for us.
11785 */
11786d2l_doconv:
11787    stmfd   sp!, {r4, r5, lr}           @ save regs
11788    mov     r3, #0x43000000             @ maxlong, as a double (high word)
11789    add     r3, #0x00e00000             @  0x43e00000
11790    mov     r2, #0                      @ maxlong, as a double (low word)
11791    sub     sp, sp, #4                  @ align for EABI
11792    mov     r4, r0                      @ save a copy of r0
11793    mov     r5, r1                      @  and r1
11794    bl      __aeabi_dcmpge              @ is arg >= maxlong?
11795    cmp     r0, #0                      @ nonzero == yes
11796    mvnne   r0, #0                      @ return maxlong (7fffffffffffffff)
11797    mvnne   r1, #0x80000000
11798    bne     1f
11799
11800    mov     r0, r4                      @ recover arg
11801    mov     r1, r5
11802    mov     r3, #0xc3000000             @ minlong, as a double (high word)
11803    add     r3, #0x00e00000             @  0xc3e00000
11804    mov     r2, #0                      @ minlong, as a double (low word)
11805    bl      __aeabi_dcmple              @ is arg <= minlong?
11806    cmp     r0, #0                      @ nonzero == yes
11807    movne   r0, #0                      @ return minlong (8000000000000000)
11808    movne   r1, #0x80000000
11809    bne     1f
11810
11811    mov     r0, r4                      @ recover arg
11812    mov     r1, r5
11813    mov     r2, r4                      @ compare against self
11814    mov     r3, r5
11815    bl      __aeabi_dcmpeq              @ is arg == self?
11816    cmp     r0, #0                      @ zero == no
11817    moveq   r1, #0                      @ return zero for NaN
11818    beq     1f
11819
11820    mov     r0, r4                      @ recover arg
11821    mov     r1, r5
11822    bl      __aeabi_d2lz                @ convert double to long
11823
118241:
11825    add     sp, sp, #4
11826    ldmfd   sp!, {r4, r5, pc}
11827
11828/* continuation for OP_MUL_LONG */
11829
11830.LOP_MUL_LONG_finish:
11831    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11832    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
11833    GOTO_OPCODE(ip)                     @ jump to next instruction
11834
11835/* continuation for OP_SHL_LONG */
11836
11837.LOP_SHL_LONG_finish:
11838    mov     r0, r0, asl r2              @  r0<- r0 << r2
11839    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11840    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11841    GOTO_OPCODE(ip)                     @ jump to next instruction
11842
11843/* continuation for OP_SHR_LONG */
11844
11845.LOP_SHR_LONG_finish:
11846    mov     r1, r1, asr r2              @  r1<- r1 >> r2
11847    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11848    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11849    GOTO_OPCODE(ip)                     @ jump to next instruction
11850
11851/* continuation for OP_USHR_LONG */
11852
11853.LOP_USHR_LONG_finish:
11854    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
11855    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11856    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11857    GOTO_OPCODE(ip)                     @ jump to next instruction
11858
11859/* continuation for OP_SHL_LONG_2ADDR */
11860
11861.LOP_SHL_LONG_2ADDR_finish:
11862    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11863    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11864    GOTO_OPCODE(ip)                     @ jump to next instruction
11865
11866/* continuation for OP_SHR_LONG_2ADDR */
11867
11868.LOP_SHR_LONG_2ADDR_finish:
11869    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11870    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11871    GOTO_OPCODE(ip)                     @ jump to next instruction
11872
11873/* continuation for OP_USHR_LONG_2ADDR */
11874
11875.LOP_USHR_LONG_2ADDR_finish:
11876    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11877    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11878    GOTO_OPCODE(ip)                     @ jump to next instruction
11879
11880/* continuation for OP_IGET_VOLATILE */
11881
11882    /*
11883     * Currently:
11884     *  r0 holds resolved field
11885     *  r9 holds object
11886     */
11887.LOP_IGET_VOLATILE_finish:
11888    @bl      common_squeak0
11889    cmp     r9, #0                      @ check object for null
11890    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11891    beq     common_errNullObject        @ object was null
11892    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11893    SMP_DMB                            @ acquiring load
11894    mov     r2, rINST, lsr #8           @ r2<- A+
11895    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11896    and     r2, r2, #15                 @ r2<- A
11897    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11898    SET_VREG(r0, r2)                    @ fp[A]<- r0
11899    GOTO_OPCODE(ip)                     @ jump to next instruction
11900
11901/* continuation for OP_IPUT_VOLATILE */
11902
11903    /*
11904     * Currently:
11905     *  r0 holds resolved field
11906     *  r9 holds object
11907     */
11908.LOP_IPUT_VOLATILE_finish:
11909    @bl      common_squeak0
11910    mov     r1, rINST, lsr #8           @ r1<- A+
11911    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11912    and     r1, r1, #15                 @ r1<- A
11913    cmp     r9, #0                      @ check object for null
11914    GET_VREG(r0, r1)                    @ r0<- fp[A]
11915    beq     common_errNullObject        @ object was null
11916    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11917    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11918    SMP_DMB                            @ releasing store
11919    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11920    GOTO_OPCODE(ip)                     @ jump to next instruction
11921
11922/* continuation for OP_SGET_VOLATILE */
11923
11924    /*
11925     * Continuation if the field has not yet been resolved.
11926     *  r1: BBBB field ref
11927     */
11928.LOP_SGET_VOLATILE_resolve:
11929    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11930    EXPORT_PC()                         @ resolve() could throw, so export now
11931    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11932    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11933    cmp     r0, #0                      @ success?
11934    bne     .LOP_SGET_VOLATILE_finish          @ yes, finish
11935    b       common_exceptionThrown      @ no, handle exception
11936
11937/* continuation for OP_SPUT_VOLATILE */
11938
11939    /*
11940     * Continuation if the field has not yet been resolved.
11941     *  r1: BBBB field ref
11942     */
11943.LOP_SPUT_VOLATILE_resolve:
11944    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
11945    EXPORT_PC()                         @ resolve() could throw, so export now
11946    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11947    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11948    cmp     r0, #0                      @ success?
11949    bne     .LOP_SPUT_VOLATILE_finish          @ yes, finish
11950    b       common_exceptionThrown      @ no, handle exception
11951
11952/* continuation for OP_IGET_OBJECT_VOLATILE */
11953
11954    /*
11955     * Currently:
11956     *  r0 holds resolved field
11957     *  r9 holds object
11958     */
11959.LOP_IGET_OBJECT_VOLATILE_finish:
11960    @bl      common_squeak0
11961    cmp     r9, #0                      @ check object for null
11962    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11963    beq     common_errNullObject        @ object was null
11964    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11965    SMP_DMB                            @ acquiring load
11966    mov     r2, rINST, lsr #8           @ r2<- A+
11967    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11968    and     r2, r2, #15                 @ r2<- A
11969    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11970    SET_VREG(r0, r2)                    @ fp[A]<- r0
11971    GOTO_OPCODE(ip)                     @ jump to next instruction
11972
11973/* continuation for OP_IGET_WIDE_VOLATILE */
11974
11975    /*
11976     * Currently:
11977     *  r0 holds resolved field
11978     *  r9 holds object
11979     */
11980.LOP_IGET_WIDE_VOLATILE_finish:
11981    cmp     r9, #0                      @ check object for null
11982    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11983    beq     common_errNullObject        @ object was null
11984    .if     1
11985    add     r0, r9, r3                  @ r0<- address of field
11986    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
11987    .else
11988    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
11989    .endif
11990    mov     r2, rINST, lsr #8           @ r2<- A+
11991    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11992    and     r2, r2, #15                 @ r2<- A
11993    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
11994    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11995    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
11996    GOTO_OPCODE(ip)                     @ jump to next instruction
11997
11998/* continuation for OP_IPUT_WIDE_VOLATILE */
11999
12000    /*
12001     * Currently:
12002     *  r0 holds resolved field
12003     *  r9 holds object
12004     */
12005.LOP_IPUT_WIDE_VOLATILE_finish:
12006    mov     r2, rINST, lsr #8           @ r2<- A+
12007    cmp     r9, #0                      @ check object for null
12008    and     r2, r2, #15                 @ r2<- A
12009    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12010    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
12011    beq     common_errNullObject        @ object was null
12012    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12013    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
12014    GET_INST_OPCODE(r10)                @ extract opcode from rINST
12015    .if     1
12016    add     r2, r9, r3                  @ r2<- target address
12017    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
12018    .else
12019    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
12020    .endif
12021    GOTO_OPCODE(r10)                    @ jump to next instruction
12022
12023/* continuation for OP_SGET_WIDE_VOLATILE */
12024
12025    /*
12026     * Continuation if the field has not yet been resolved.
12027     *  r1: BBBB field ref
12028     *
12029     * Returns StaticField pointer in r0.
12030     */
12031.LOP_SGET_WIDE_VOLATILE_resolve:
12032    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12033    EXPORT_PC()                         @ resolve() could throw, so export now
12034    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12035    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12036    cmp     r0, #0                      @ success?
12037    bne     .LOP_SGET_WIDE_VOLATILE_finish          @ yes, finish
12038    b       common_exceptionThrown      @ no, handle exception
12039
12040/* continuation for OP_SPUT_WIDE_VOLATILE */
12041
12042    /*
12043     * Continuation if the field has not yet been resolved.
12044     *  r1: BBBB field ref
12045     *  r9: &fp[AA]
12046     *
12047     * Returns StaticField pointer in r2.
12048     */
12049.LOP_SPUT_WIDE_VOLATILE_resolve:
12050    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12051    EXPORT_PC()                         @ resolve() could throw, so export now
12052    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12053    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12054    cmp     r0, #0                      @ success?
12055    mov     r2, r0                      @ copy to r2
12056    bne     .LOP_SPUT_WIDE_VOLATILE_finish          @ yes, finish
12057    b       common_exceptionThrown      @ no, handle exception
12058
12059/* continuation for OP_EXECUTE_INLINE */
12060
12061    /*
12062     * Extract args, call function.
12063     *  r0 = #of args (0-4)
12064     *  r10 = call index
12065     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
12066     *
12067     * Other ideas:
12068     * - Use a jump table from the main piece to jump directly into the
12069     *   AND/LDR pairs.  Costs a data load, saves a branch.
12070     * - Have five separate pieces that do the loading, so we can work the
12071     *   interleave a little better.  Increases code size.
12072     */
12073.LOP_EXECUTE_INLINE_continue:
12074    rsb     r0, r0, #4                  @ r0<- 4-r0
12075    FETCH(r9, 2)                        @ r9<- FEDC
12076    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
12077    bl      common_abort                @ (skipped due to ARM prefetch)
120784:  and     ip, r9, #0xf000             @ isolate F
12079    ldr     r3, [rFP, ip, lsr #10]      @ r3<- vF (shift right 12, left 2)
120803:  and     ip, r9, #0x0f00             @ isolate E
12081    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vE
120822:  and     ip, r9, #0x00f0             @ isolate D
12083    ldr     r1, [rFP, ip, lsr #2]       @ r1<- vD
120841:  and     ip, r9, #0x000f             @ isolate C
12085    ldr     r0, [rFP, ip, lsl #2]       @ r0<- vC
120860:
12087    ldr     r9, .LOP_EXECUTE_INLINE_table       @ table of InlineOperation
12088    ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
12089    @ (not reached)
12090
12091.LOP_EXECUTE_INLINE_table:
12092    .word   gDvmInlineOpsTable
12093
12094/* continuation for OP_EXECUTE_INLINE_RANGE */
12095
12096    /*
12097     * Extract args, call function.
12098     *  r0 = #of args (0-4)
12099     *  r10 = call index
12100     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
12101     */
12102.LOP_EXECUTE_INLINE_RANGE_continue:
12103    rsb     r0, r0, #4                  @ r0<- 4-r0
12104    FETCH(r9, 2)                        @ r9<- CCCC
12105    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
12106    bl      common_abort                @ (skipped due to ARM prefetch)
121074:  add     ip, r9, #3                  @ base+3
12108    GET_VREG(r3, ip)                    @ r3<- vBase[3]
121093:  add     ip, r9, #2                  @ base+2
12110    GET_VREG(r2, ip)                    @ r2<- vBase[2]
121112:  add     ip, r9, #1                  @ base+1
12112    GET_VREG(r1, ip)                    @ r1<- vBase[1]
121131:  add     ip, r9, #0                  @ (nop)
12114    GET_VREG(r0, ip)                    @ r0<- vBase[0]
121150:
12116    ldr     r9, .LOP_EXECUTE_INLINE_RANGE_table       @ table of InlineOperation
12117    ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
12118    @ (not reached)
12119
12120.LOP_EXECUTE_INLINE_RANGE_table:
12121    .word   gDvmInlineOpsTable
12122
12123/* continuation for OP_IPUT_OBJECT_VOLATILE */
12124
12125    /*
12126     * Currently:
12127     *  r0 holds resolved field
12128     *  r9 holds object
12129     */
12130.LOP_IPUT_OBJECT_VOLATILE_finish:
12131    @bl      common_squeak0
12132    mov     r1, rINST, lsr #8           @ r1<- A+
12133    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12134    and     r1, r1, #15                 @ r1<- A
12135    cmp     r9, #0                      @ check object for null
12136    GET_VREG(r0, r1)                    @ r0<- fp[A]
12137    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12138    beq     common_errNullObject        @ object was null
12139    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12140    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12141    SMP_DMB                            @ releasing store
12142    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
12143    cmp     r0, #0                      @ stored a null reference?
12144    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
12145    GOTO_OPCODE(ip)                     @ jump to next instruction
12146
12147/* continuation for OP_SGET_OBJECT_VOLATILE */
12148
12149    /*
12150     * Continuation if the field has not yet been resolved.
12151     *  r1: BBBB field ref
12152     */
12153.LOP_SGET_OBJECT_VOLATILE_resolve:
12154    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12155    EXPORT_PC()                         @ resolve() could throw, so export now
12156    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12157    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12158    cmp     r0, #0                      @ success?
12159    bne     .LOP_SGET_OBJECT_VOLATILE_finish          @ yes, finish
12160    b       common_exceptionThrown      @ no, handle exception
12161
12162/* continuation for OP_SPUT_OBJECT_VOLATILE */
12163.LOP_SPUT_OBJECT_VOLATILE_finish:   @ field ptr in r0
12164    mov     r2, rINST, lsr #8           @ r2<- AA
12165    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12166    GET_VREG(r1, r2)                    @ r1<- fp[AA]
12167    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12168    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
12169    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12170    SMP_DMB                            @ releasing store
12171    str     r1, [r0, #offStaticField_value]  @ field<- vAA
12172    cmp     r1, #0                      @ stored a null object?
12173    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
12174    GOTO_OPCODE(ip)                     @ jump to next instruction
12175
12176/* continuation for OP_CONST_CLASS_JUMBO */
12177
12178    /*
12179     * Continuation if the Class has not yet been resolved.
12180     *  r1: AAAAAAAA (Class ref)
12181     *  r9: target register
12182     */
12183.LOP_CONST_CLASS_JUMBO_resolve:
12184    EXPORT_PC()
12185    ldr     r0, [rGLUE, #offGlue_method] @ r0<- glue->method
12186    mov     r2, #1                      @ r2<- true
12187    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
12188    bl      dvmResolveClass             @ r0<- Class reference
12189    cmp     r0, #0                      @ failed?
12190    beq     common_exceptionThrown      @ yup, handle the exception
12191    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12192    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12193    SET_VREG(r0, r9)                    @ vBBBB<- r0
12194    GOTO_OPCODE(ip)                     @ jump to next instruction
12195
12196/* continuation for OP_CHECK_CAST_JUMBO */
12197
12198    /*
12199     * Trivial test failed, need to perform full check.  This is common.
12200     *  r0 holds obj->clazz
12201     *  r1 holds desired class resolved from AAAAAAAA
12202     *  r9 holds object
12203     */
12204.LOP_CHECK_CAST_JUMBO_fullcheck:
12205    mov     r10, r1                     @ avoid ClassObject getting clobbered
12206    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
12207    cmp     r0, #0                      @ failed?
12208    bne     .LOP_CHECK_CAST_JUMBO_okay            @ no, success
12209
12210    @ A cast has failed.  We need to throw a ClassCastException.
12211    EXPORT_PC()                         @ about to throw
12212    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
12213    mov     r1, r10                     @ r1<- desired class
12214    bl      dvmThrowClassCastException
12215    b       common_exceptionThrown
12216
12217    /*
12218     * Advance PC and get the next opcode.
12219     */
12220.LOP_CHECK_CAST_JUMBO_okay:
12221    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12222    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12223    GOTO_OPCODE(ip)                     @ jump to next instruction
12224
12225    /*
12226     * Resolution required.  This is the least-likely path.
12227     *
12228     *  r2 holds AAAAAAAA
12229     *  r9 holds object
12230     */
12231.LOP_CHECK_CAST_JUMBO_resolve:
12232    EXPORT_PC()                         @ resolve() could throw
12233    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
12234    mov     r1, r2                      @ r1<- AAAAAAAA
12235    mov     r2, #0                      @ r2<- false
12236    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12237    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12238    cmp     r0, #0                      @ got null?
12239    beq     common_exceptionThrown      @ yes, handle exception
12240    mov     r1, r0                      @ r1<- class resolved from AAAAAAAA
12241    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
12242    b       .LOP_CHECK_CAST_JUMBO_resolved        @ pick up where we left off
12243
12244/* continuation for OP_INSTANCE_OF_JUMBO */
12245
12246    /*
12247     * Class resolved, determine type of check necessary.  This is common.
12248     *  r0 holds obj->clazz
12249     *  r1 holds class resolved from AAAAAAAA
12250     *  r9 holds BBBB
12251     */
12252.LOP_INSTANCE_OF_JUMBO_resolved:
12253    cmp     r0, r1                      @ same class (trivial success)?
12254    beq     .LOP_INSTANCE_OF_JUMBO_trivial         @ yes, trivial finish
12255    @ fall through to OP_INSTANCE_OF_JUMBO_fullcheck
12256
12257    /*
12258     * Trivial test failed, need to perform full check.  This is common.
12259     *  r0 holds obj->clazz
12260     *  r1 holds class resolved from AAAAAAAA
12261     *  r9 holds BBBB
12262     */
12263.LOP_INSTANCE_OF_JUMBO_fullcheck:
12264    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
12265    @ fall through to OP_INSTANCE_OF_JUMBO_store
12266
12267    /*
12268     * r0 holds boolean result
12269     * r9 holds BBBB
12270     */
12271.LOP_INSTANCE_OF_JUMBO_store:
12272    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12273    SET_VREG(r0, r9)                    @ vBBBB<- r0
12274    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12275    GOTO_OPCODE(ip)                     @ jump to next instruction
12276
12277    /*
12278     * Trivial test succeeded, save and bail.
12279     *  r9 holds BBBB
12280     */
12281.LOP_INSTANCE_OF_JUMBO_trivial:
12282    mov     r0, #1                      @ indicate success
12283    @ could b OP_INSTANCE_OF_JUMBO_store, but copying is faster and cheaper
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     * Resolution required.  This is the least-likely path.
12291     *
12292     *  r3 holds AAAAAAAA
12293     *  r9 holds BBBB
12294     */
12295
12296.LOP_INSTANCE_OF_JUMBO_resolve:
12297    EXPORT_PC()                         @ resolve() could throw
12298    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
12299    mov     r1, r3                      @ r1<- AAAAAAAA
12300    mov     r2, #1                      @ r2<- true
12301    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
12302    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12303    cmp     r0, #0                      @ got null?
12304    beq     common_exceptionThrown      @ yes, handle exception
12305    FETCH(r3, 4)                        @ r3<- vCCCC
12306    mov     r1, r0                      @ r1<- class resolved from AAAAAAAA
12307    GET_VREG(r0, r3)                    @ r0<- vCCCC (object)
12308    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
12309    b       .LOP_INSTANCE_OF_JUMBO_resolved        @ pick up where we left off
12310
12311/* continuation for OP_NEW_INSTANCE_JUMBO */
12312
12313    .balign 32                          @ minimize cache lines
12314.LOP_NEW_INSTANCE_JUMBO_finish: @ r0=new object
12315    FETCH(r3, 3)                        @ r3<- BBBB
12316    cmp     r0, #0                      @ failed?
12317    beq     common_exceptionThrown      @ yes, handle the exception
12318    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12319    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12320    SET_VREG(r0, r3)                    @ vBBBB<- r0
12321    GOTO_OPCODE(ip)                     @ jump to next instruction
12322
12323    /*
12324     * Class initialization required.
12325     *
12326     *  r0 holds class object
12327     */
12328.LOP_NEW_INSTANCE_JUMBO_needinit:
12329    mov     r9, r0                      @ save r0
12330    bl      dvmInitClass                @ initialize class
12331    cmp     r0, #0                      @ check boolean result
12332    mov     r0, r9                      @ restore r0
12333    bne     .LOP_NEW_INSTANCE_JUMBO_initialized     @ success, continue
12334    b       common_exceptionThrown      @ failed, deal with init exception
12335
12336    /*
12337     * Resolution required.  This is the least-likely path.
12338     *
12339     *  r1 holds AAAAAAAA
12340     */
12341.LOP_NEW_INSTANCE_JUMBO_resolve:
12342    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
12343    mov     r2, #0                      @ r2<- false
12344    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12345    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12346    cmp     r0, #0                      @ got null?
12347    bne     .LOP_NEW_INSTANCE_JUMBO_resolved        @ no, continue
12348    b       common_exceptionThrown      @ yes, handle exception
12349
12350/* continuation for OP_NEW_ARRAY_JUMBO */
12351
12352
12353    /*
12354     * Resolve class.  (This is an uncommon case.)
12355     *
12356     *  r1 holds array length
12357     *  r2 holds class ref AAAAAAAA
12358     */
12359.LOP_NEW_ARRAY_JUMBO_resolve:
12360    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
12361    mov     r9, r1                      @ r9<- length (save)
12362    mov     r1, r2                      @ r1<- AAAAAAAA
12363    mov     r2, #0                      @ r2<- false
12364    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12365    bl      dvmResolveClass             @ r0<- call(clazz, ref)
12366    cmp     r0, #0                      @ got null?
12367    mov     r1, r9                      @ r1<- length (restore)
12368    beq     common_exceptionThrown      @ yes, handle exception
12369    @ fall through to OP_NEW_ARRAY_JUMBO_finish
12370
12371    /*
12372     * Finish allocation.
12373     *
12374     *  r0 holds class
12375     *  r1 holds array length
12376     */
12377.LOP_NEW_ARRAY_JUMBO_finish:
12378    mov     r2, #ALLOC_DONT_TRACK       @ don't track in local refs table
12379    bl      dvmAllocArrayByClass        @ r0<- call(clazz, length, flags)
12380    cmp     r0, #0                      @ failed?
12381    FETCH(r2, 3)                        @ r2<- vBBBB
12382    beq     common_exceptionThrown      @ yes, handle the exception
12383    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12384    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12385    SET_VREG(r0, r2)                    @ vBBBB<- r0
12386    GOTO_OPCODE(ip)                     @ jump to next instruction
12387
12388/* continuation for OP_FILLED_NEW_ARRAY_JUMBO */
12389
12390    /*
12391     * On entry:
12392     *  r0 holds array class
12393     */
12394.LOP_FILLED_NEW_ARRAY_JUMBO_continue:
12395    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
12396    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
12397    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
12398    FETCH(r1, 3)                        @ r1<- BBBB (length)
12399    cmp     rINST, #'I'                 @ array of ints?
12400    cmpne   rINST, #'L'                 @ array of objects?
12401    cmpne   rINST, #'['                 @ array of arrays?
12402    mov     r9, r1                      @ save length in r9
12403    bne     .LOP_FILLED_NEW_ARRAY_JUMBO_notimpl         @ no, not handled yet
12404    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
12405    cmp     r0, #0                      @ null return?
12406    beq     common_exceptionThrown      @ alloc failed, handle exception
12407
12408    FETCH(r1, 4)                        @ r1<- CCCC
12409    str     r0, [rGLUE, #offGlue_retval]      @ retval.l <- new array
12410    str     rINST, [rGLUE, #offGlue_retval+4] @ retval.h <- type
12411    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
12412    subs    r9, r9, #1                  @ length--, check for neg
12413    FETCH_ADVANCE_INST(5)               @ advance to next instr, load rINST
12414    bmi     2f                          @ was zero, bail
12415
12416    @ copy values from registers into the array
12417    @ r0=array, r1=CCCC, r9=BBBB (length)
12418    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
124191:  ldr     r3, [r2], #4                @ r3<- *r2++
12420    subs    r9, r9, #1                  @ count--
12421    str     r3, [r0], #4                @ *contents++ = vX
12422    bpl     1b
12423
124242:  ldr     r0, [rGLUE, #offGlue_retval]     @ r0<- object
12425    ldr     r1, [rGLUE, #offGlue_retval+4]   @ r1<- type
12426    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12427    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
12428    cmp     r1, #'I'                         @ Is int array?
12429    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
12430    GOTO_OPCODE(ip)                          @ execute it
12431
12432    /*
12433     * Throw an exception indicating that we have not implemented this
12434     * mode of filled-new-array.
12435     */
12436.LOP_FILLED_NEW_ARRAY_JUMBO_notimpl:
12437    ldr     r0, .L_strInternalError
12438    ldr     r1, .L_strFilledNewArrayNotImpl
12439    bl      dvmThrowException
12440    b       common_exceptionThrown
12441
12442/* continuation for OP_IGET_JUMBO */
12443
12444    /*
12445     * Currently:
12446     *  r0 holds resolved field
12447     *  r9 holds object
12448     */
12449.LOP_IGET_JUMBO_resolved:
12450    cmp     r0, #0                      @ resolution unsuccessful?
12451    beq     common_exceptionThrown      @ yes, throw exception
12452    @ fall through to OP_IGET_JUMBO_finish
12453
12454    /*
12455     * Currently:
12456     *  r0 holds resolved field
12457     *  r9 holds object
12458     */
12459.LOP_IGET_JUMBO_finish:
12460    @bl      common_squeak0
12461    cmp     r9, #0                      @ check object for null
12462    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12463    beq     common_errNullObject        @ object was null
12464    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12465    @ no-op                             @ acquiring load
12466    FETCH(r2, 3)                        @ r2<- BBBB
12467    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12468    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12469    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12470    GOTO_OPCODE(ip)                     @ jump to next instruction
12471
12472/* continuation for OP_IGET_WIDE_JUMBO */
12473
12474    /*
12475     * Currently:
12476     *  r0 holds resolved field
12477     *  r9 holds object
12478     */
12479.LOP_IGET_WIDE_JUMBO_resolved:
12480    cmp     r0, #0                      @ resolution unsuccessful?
12481    beq     common_exceptionThrown      @ yes, throw exception
12482    @ fall through to OP_IGET_WIDE_JUMBO_finish
12483
12484    /*
12485     * Currently:
12486     *  r0 holds resolved field
12487     *  r9 holds object
12488     */
12489.LOP_IGET_WIDE_JUMBO_finish:
12490    cmp     r9, #0                      @ check object for null
12491    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12492    beq     common_errNullObject        @ object was null
12493    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
12494    FETCH(r2, 3)                        @ r2<- BBBB
12495    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12496    add     r3, rFP, r2, lsl #2         @ r3<- &fp[BBBB]
12497    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12498    stmia   r3, {r0-r1}                 @ fp[BBBB]<- r0/r1
12499    GOTO_OPCODE(ip)                     @ jump to next instruction
12500
12501/* continuation for OP_IGET_OBJECT_JUMBO */
12502
12503    /*
12504     * Currently:
12505     *  r0 holds resolved field
12506     *  r9 holds object
12507     */
12508.LOP_IGET_OBJECT_JUMBO_resolved:
12509    cmp     r0, #0                      @ resolution unsuccessful?
12510    beq     common_exceptionThrown      @ yes, throw exception
12511    @ fall through to OP_IGET_OBJECT_JUMBO_finish
12512
12513    /*
12514     * Currently:
12515     *  r0 holds resolved field
12516     *  r9 holds object
12517     */
12518.LOP_IGET_OBJECT_JUMBO_finish:
12519    @bl      common_squeak0
12520    cmp     r9, #0                      @ check object for null
12521    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12522    beq     common_errNullObject        @ object was null
12523    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12524    @ no-op                             @ acquiring load
12525    FETCH(r2, 3)                        @ r2<- BBBB
12526    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12527    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12528    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12529    GOTO_OPCODE(ip)                     @ jump to next instruction
12530
12531/* continuation for OP_IGET_BOOLEAN_JUMBO */
12532
12533    /*
12534     * Currently:
12535     *  r0 holds resolved field
12536     *  r9 holds object
12537     */
12538.LOP_IGET_BOOLEAN_JUMBO_resolved:
12539    cmp     r0, #0                      @ resolution unsuccessful?
12540    beq     common_exceptionThrown      @ yes, throw exception
12541    @ fall through to OP_IGET_BOOLEAN_JUMBO_finish
12542
12543    /*
12544     * Currently:
12545     *  r0 holds resolved field
12546     *  r9 holds object
12547     */
12548.LOP_IGET_BOOLEAN_JUMBO_finish:
12549    @bl      common_squeak1
12550    cmp     r9, #0                      @ check object for null
12551    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12552    beq     common_errNullObject        @ object was null
12553    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12554    @ no-op                             @ acquiring load
12555    FETCH(r2, 3)                        @ r2<- BBBB
12556    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12557    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12558    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12559    GOTO_OPCODE(ip)                     @ jump to next instruction
12560
12561/* continuation for OP_IGET_BYTE_JUMBO */
12562
12563    /*
12564     * Currently:
12565     *  r0 holds resolved field
12566     *  r9 holds object
12567     */
12568.LOP_IGET_BYTE_JUMBO_resolved:
12569    cmp     r0, #0                      @ resolution unsuccessful?
12570    beq     common_exceptionThrown      @ yes, throw exception
12571    @ fall through to OP_IGET_BYTE_JUMBO_finish
12572
12573    /*
12574     * Currently:
12575     *  r0 holds resolved field
12576     *  r9 holds object
12577     */
12578.LOP_IGET_BYTE_JUMBO_finish:
12579    @bl      common_squeak2
12580    cmp     r9, #0                      @ check object for null
12581    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12582    beq     common_errNullObject        @ object was null
12583    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12584    @ no-op                             @ acquiring load
12585    FETCH(r2, 3)                        @ r2<- BBBB
12586    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12587    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12588    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12589    GOTO_OPCODE(ip)                     @ jump to next instruction
12590
12591/* continuation for OP_IGET_CHAR_JUMBO */
12592
12593    /*
12594     * Currently:
12595     *  r0 holds resolved field
12596     *  r9 holds object
12597     */
12598.LOP_IGET_CHAR_JUMBO_resolved:
12599    cmp     r0, #0                      @ resolution unsuccessful?
12600    beq     common_exceptionThrown      @ yes, throw exception
12601    @ fall through to OP_IGET_CHAR_JUMBO_finish
12602
12603    /*
12604     * Currently:
12605     *  r0 holds resolved field
12606     *  r9 holds object
12607     */
12608.LOP_IGET_CHAR_JUMBO_finish:
12609    @bl      common_squeak3
12610    cmp     r9, #0                      @ check object for null
12611    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12612    beq     common_errNullObject        @ object was null
12613    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12614    @ no-op                             @ acquiring load
12615    FETCH(r2, 3)                        @ r2<- BBBB
12616    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12617    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12618    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12619    GOTO_OPCODE(ip)                     @ jump to next instruction
12620
12621/* continuation for OP_IGET_SHORT_JUMBO */
12622
12623    /*
12624     * Currently:
12625     *  r0 holds resolved field
12626     *  r9 holds object
12627     */
12628.LOP_IGET_SHORT_JUMBO_resolved:
12629    cmp     r0, #0                      @ resolution unsuccessful?
12630    beq     common_exceptionThrown      @ yes, throw exception
12631    @ fall through to OP_IGET_SHORT_JUMBO_finish
12632
12633    /*
12634     * Currently:
12635     *  r0 holds resolved field
12636     *  r9 holds object
12637     */
12638.LOP_IGET_SHORT_JUMBO_finish:
12639    @bl      common_squeak4
12640    cmp     r9, #0                      @ check object for null
12641    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12642    beq     common_errNullObject        @ object was null
12643    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12644    @ no-op                             @ acquiring load
12645    FETCH(r2, 3)                        @ r2<- BBBB
12646    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12647    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12648    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12649    GOTO_OPCODE(ip)                     @ jump to next instruction
12650
12651/* continuation for OP_IPUT_JUMBO */
12652
12653    /*
12654     * Currently:
12655     *  r0 holds resolved field
12656     *  r9 holds object
12657     */
12658.LOP_IPUT_JUMBO_resolved:
12659     cmp     r0, #0                     @ resolution unsuccessful?
12660     beq     common_exceptionThrown     @ yes, throw exception
12661     @ fall through to OP_IPUT_JUMBO_finish
12662
12663    /*
12664     * Currently:
12665     *  r0 holds resolved field
12666     *  r9 holds object
12667     */
12668.LOP_IPUT_JUMBO_finish:
12669    @bl      common_squeak0
12670    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12671    FETCH(r1, 3)                        @ r1<- BBBB
12672    cmp     r9, #0                      @ check object for null
12673    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12674    beq     common_errNullObject        @ object was null
12675    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12676    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12677    @ no-op                             @ releasing store
12678    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12679    GOTO_OPCODE(ip)                     @ jump to next instruction
12680
12681/* continuation for OP_IPUT_WIDE_JUMBO */
12682
12683    /*
12684     * Currently:
12685     *  r0 holds resolved field
12686     *  r9 holds object
12687     */
12688.LOP_IPUT_WIDE_JUMBO_resolved:
12689     cmp     r0, #0                     @ resolution unsuccessful?
12690     beq     common_exceptionThrown     @ yes, throw exception
12691     @ fall through to OP_IPUT_WIDE_JUMBO_finish
12692
12693    /*
12694     * Currently:
12695     *  r0 holds resolved field
12696     *  r9 holds object
12697     */
12698.LOP_IPUT_WIDE_JUMBO_finish:
12699    cmp     r9, #0                      @ check object for null
12700    FETCH(r2, 3)                        @ r1<- BBBB
12701    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12702    add     r2, rFP, r2, lsl #2         @ r3<- &fp[BBBB]
12703    beq     common_errNullObject        @ object was null
12704    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12705    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[BBBB]
12706    GET_INST_OPCODE(r10)                @ extract opcode from rINST
12707    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
12708    GOTO_OPCODE(r10)                    @ jump to next instruction
12709
12710/* continuation for OP_IPUT_OBJECT_JUMBO */
12711
12712    /*
12713     * Currently:
12714     *  r0 holds resolved field
12715     *  r9 holds object
12716     */
12717.LOP_IPUT_OBJECT_JUMBO_resolved:
12718     cmp     r0, #0                     @ resolution unsuccessful?
12719     beq     common_exceptionThrown     @ yes, throw exception
12720     @ fall through to OP_IPUT_OBJECT_JUMBO_finish
12721
12722    /*
12723     * Currently:
12724     *  r0 holds resolved field
12725     *  r9 holds object
12726     */
12727.LOP_IPUT_OBJECT_JUMBO_finish:
12728    @bl      common_squeak0
12729    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12730    FETCH(r1, 3)                        @ r1<- BBBB
12731    cmp     r9, #0                      @ check object for null
12732    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12733    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
12734    beq     common_errNullObject        @ object was null
12735    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12736    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12737    @ no-op                             @ releasing store
12738    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
12739    cmp     r0, #0                      @ stored a null reference?
12740    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
12741    GOTO_OPCODE(ip)                     @ jump to next instruction
12742
12743/* continuation for OP_IPUT_BOOLEAN_JUMBO */
12744
12745    /*
12746     * Currently:
12747     *  r0 holds resolved field
12748     *  r9 holds object
12749     */
12750.LOP_IPUT_BOOLEAN_JUMBO_resolved:
12751     cmp     r0, #0                     @ resolution unsuccessful?
12752     beq     common_exceptionThrown     @ yes, throw exception
12753     @ fall through to OP_IPUT_BOOLEAN_JUMBO_finish
12754
12755    /*
12756     * Currently:
12757     *  r0 holds resolved field
12758     *  r9 holds object
12759     */
12760.LOP_IPUT_BOOLEAN_JUMBO_finish:
12761    @bl      common_squeak1
12762    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12763    FETCH(r1, 3)                        @ r1<- BBBB
12764    cmp     r9, #0                      @ check object for null
12765    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12766    beq     common_errNullObject        @ object was null
12767    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12768    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12769    @ no-op                             @ releasing store
12770    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12771    GOTO_OPCODE(ip)                     @ jump to next instruction
12772
12773/* continuation for OP_IPUT_BYTE_JUMBO */
12774
12775    /*
12776     * Currently:
12777     *  r0 holds resolved field
12778     *  r9 holds object
12779     */
12780.LOP_IPUT_BYTE_JUMBO_resolved:
12781     cmp     r0, #0                     @ resolution unsuccessful?
12782     beq     common_exceptionThrown     @ yes, throw exception
12783     @ fall through to OP_IPUT_BYTE_JUMBO_finish
12784
12785    /*
12786     * Currently:
12787     *  r0 holds resolved field
12788     *  r9 holds object
12789     */
12790.LOP_IPUT_BYTE_JUMBO_finish:
12791    @bl      common_squeak2
12792    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12793    FETCH(r1, 3)                        @ r1<- BBBB
12794    cmp     r9, #0                      @ check object for null
12795    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12796    beq     common_errNullObject        @ object was null
12797    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12798    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12799    @ no-op                             @ releasing store
12800    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12801    GOTO_OPCODE(ip)                     @ jump to next instruction
12802
12803/* continuation for OP_IPUT_CHAR_JUMBO */
12804
12805    /*
12806     * Currently:
12807     *  r0 holds resolved field
12808     *  r9 holds object
12809     */
12810.LOP_IPUT_CHAR_JUMBO_resolved:
12811     cmp     r0, #0                     @ resolution unsuccessful?
12812     beq     common_exceptionThrown     @ yes, throw exception
12813     @ fall through to OP_IPUT_CHAR_JUMBO_finish
12814
12815    /*
12816     * Currently:
12817     *  r0 holds resolved field
12818     *  r9 holds object
12819     */
12820.LOP_IPUT_CHAR_JUMBO_finish:
12821    @bl      common_squeak3
12822    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12823    FETCH(r1, 3)                        @ r1<- BBBB
12824    cmp     r9, #0                      @ check object for null
12825    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12826    beq     common_errNullObject        @ object was null
12827    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12828    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12829    @ no-op                             @ releasing store
12830    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12831    GOTO_OPCODE(ip)                     @ jump to next instruction
12832
12833/* continuation for OP_IPUT_SHORT_JUMBO */
12834
12835    /*
12836     * Currently:
12837     *  r0 holds resolved field
12838     *  r9 holds object
12839     */
12840.LOP_IPUT_SHORT_JUMBO_resolved:
12841     cmp     r0, #0                     @ resolution unsuccessful?
12842     beq     common_exceptionThrown     @ yes, throw exception
12843     @ fall through to OP_IPUT_SHORT_JUMBO_finish
12844
12845    /*
12846     * Currently:
12847     *  r0 holds resolved field
12848     *  r9 holds object
12849     */
12850.LOP_IPUT_SHORT_JUMBO_finish:
12851    @bl      common_squeak4
12852    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12853    FETCH(r1, 3)                        @ r1<- BBBB
12854    cmp     r9, #0                      @ check object for null
12855    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12856    beq     common_errNullObject        @ object was null
12857    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12858    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12859    @ no-op                             @ releasing store
12860    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12861    GOTO_OPCODE(ip)                     @ jump to next instruction
12862
12863/* continuation for OP_SGET_JUMBO */
12864
12865    /*
12866     * Continuation if the field has not yet been resolved.
12867     *  r1: AAAAAAAA field ref
12868     */
12869.LOP_SGET_JUMBO_resolve:
12870    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12871    EXPORT_PC()                         @ resolve() could throw, so export now
12872    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12873    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12874    cmp     r0, #0                      @ success?
12875    bne     .LOP_SGET_JUMBO_finish          @ yes, finish
12876    b       common_exceptionThrown      @ no, handle exception
12877
12878/* continuation for OP_SGET_WIDE_JUMBO */
12879
12880    /*
12881     * Continuation if the field has not yet been resolved.
12882     *  r1: BBBB field ref
12883     *
12884     * Returns StaticField pointer in r0.
12885     */
12886.LOP_SGET_WIDE_JUMBO_resolve:
12887    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12888    EXPORT_PC()                         @ resolve() could throw, so export now
12889    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12890    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12891    cmp     r0, #0                      @ success?
12892    bne     .LOP_SGET_WIDE_JUMBO_finish          @ yes, finish
12893    b       common_exceptionThrown      @ no, handle exception
12894
12895/* continuation for OP_SGET_OBJECT_JUMBO */
12896
12897    /*
12898     * Continuation if the field has not yet been resolved.
12899     *  r1: AAAAAAAA field ref
12900     */
12901.LOP_SGET_OBJECT_JUMBO_resolve:
12902    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12903    EXPORT_PC()                         @ resolve() could throw, so export now
12904    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12905    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12906    cmp     r0, #0                      @ success?
12907    bne     .LOP_SGET_OBJECT_JUMBO_finish          @ yes, finish
12908    b       common_exceptionThrown      @ no, handle exception
12909
12910/* continuation for OP_SGET_BOOLEAN_JUMBO */
12911
12912    /*
12913     * Continuation if the field has not yet been resolved.
12914     *  r1: AAAAAAAA field ref
12915     */
12916.LOP_SGET_BOOLEAN_JUMBO_resolve:
12917    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12918    EXPORT_PC()                         @ resolve() could throw, so export now
12919    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12920    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12921    cmp     r0, #0                      @ success?
12922    bne     .LOP_SGET_BOOLEAN_JUMBO_finish          @ yes, finish
12923    b       common_exceptionThrown      @ no, handle exception
12924
12925/* continuation for OP_SGET_BYTE_JUMBO */
12926
12927    /*
12928     * Continuation if the field has not yet been resolved.
12929     *  r1: AAAAAAAA field ref
12930     */
12931.LOP_SGET_BYTE_JUMBO_resolve:
12932    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12933    EXPORT_PC()                         @ resolve() could throw, so export now
12934    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12935    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12936    cmp     r0, #0                      @ success?
12937    bne     .LOP_SGET_BYTE_JUMBO_finish          @ yes, finish
12938    b       common_exceptionThrown      @ no, handle exception
12939
12940/* continuation for OP_SGET_CHAR_JUMBO */
12941
12942    /*
12943     * Continuation if the field has not yet been resolved.
12944     *  r1: AAAAAAAA field ref
12945     */
12946.LOP_SGET_CHAR_JUMBO_resolve:
12947    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12948    EXPORT_PC()                         @ resolve() could throw, so export now
12949    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12950    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12951    cmp     r0, #0                      @ success?
12952    bne     .LOP_SGET_CHAR_JUMBO_finish          @ yes, finish
12953    b       common_exceptionThrown      @ no, handle exception
12954
12955/* continuation for OP_SGET_SHORT_JUMBO */
12956
12957    /*
12958     * Continuation if the field has not yet been resolved.
12959     *  r1: AAAAAAAA field ref
12960     */
12961.LOP_SGET_SHORT_JUMBO_resolve:
12962    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12963    EXPORT_PC()                         @ resolve() could throw, so export now
12964    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12965    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12966    cmp     r0, #0                      @ success?
12967    bne     .LOP_SGET_SHORT_JUMBO_finish          @ yes, finish
12968    b       common_exceptionThrown      @ no, handle exception
12969
12970/* continuation for OP_SPUT_JUMBO */
12971
12972    /*
12973     * Continuation if the field has not yet been resolved.
12974     *  r1: AAAAAAAA field ref
12975     */
12976.LOP_SPUT_JUMBO_resolve:
12977    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12978    EXPORT_PC()                         @ resolve() could throw, so export now
12979    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12980    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12981    cmp     r0, #0                      @ success?
12982    bne     .LOP_SPUT_JUMBO_finish          @ yes, finish
12983    b       common_exceptionThrown      @ no, handle exception
12984
12985/* continuation for OP_SPUT_WIDE_JUMBO */
12986
12987    /*
12988     * Continuation if the field has not yet been resolved.
12989     *  r1: BBBB field ref
12990     *  r9: &fp[AA]
12991     *
12992     * Returns StaticField pointer in r2.
12993     */
12994.LOP_SPUT_WIDE_JUMBO_resolve:
12995    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
12996    EXPORT_PC()                         @ resolve() could throw, so export now
12997    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12998    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12999    cmp     r0, #0                      @ success?
13000    mov     r2, r0                      @ copy to r2
13001    bne     .LOP_SPUT_WIDE_JUMBO_finish          @ yes, finish
13002    b       common_exceptionThrown      @ no, handle exception
13003
13004/* continuation for OP_SPUT_OBJECT_JUMBO */
13005
13006.LOP_SPUT_OBJECT_JUMBO_finish:   @ field ptr in r0
13007    FETCH(r2, 3)                        @ r2<- BBBB
13008    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
13009    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
13010    ldr     r2, [rGLUE, #offGlue_cardTable]  @ r2<- card table base
13011    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
13012    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13013    @ no-op                             @ releasing store
13014    str     r1, [r0, #offStaticField_value]  @ field<- vBBBB
13015    cmp     r1, #0                      @ stored a null object?
13016    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
13017    GOTO_OPCODE(ip)                     @ jump to next instruction
13018
13019/* continuation for OP_SPUT_BOOLEAN_JUMBO */
13020
13021    /*
13022     * Continuation if the field has not yet been resolved.
13023     *  r1: AAAAAAAA field ref
13024     */
13025.LOP_SPUT_BOOLEAN_JUMBO_resolve:
13026    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13027    EXPORT_PC()                         @ resolve() could throw, so export now
13028    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13029    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13030    cmp     r0, #0                      @ success?
13031    bne     .LOP_SPUT_BOOLEAN_JUMBO_finish          @ yes, finish
13032    b       common_exceptionThrown      @ no, handle exception
13033
13034/* continuation for OP_SPUT_BYTE_JUMBO */
13035
13036    /*
13037     * Continuation if the field has not yet been resolved.
13038     *  r1: AAAAAAAA field ref
13039     */
13040.LOP_SPUT_BYTE_JUMBO_resolve:
13041    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13042    EXPORT_PC()                         @ resolve() could throw, so export now
13043    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13044    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13045    cmp     r0, #0                      @ success?
13046    bne     .LOP_SPUT_BYTE_JUMBO_finish          @ yes, finish
13047    b       common_exceptionThrown      @ no, handle exception
13048
13049/* continuation for OP_SPUT_CHAR_JUMBO */
13050
13051    /*
13052     * Continuation if the field has not yet been resolved.
13053     *  r1: AAAAAAAA field ref
13054     */
13055.LOP_SPUT_CHAR_JUMBO_resolve:
13056    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13057    EXPORT_PC()                         @ resolve() could throw, so export now
13058    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13059    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13060    cmp     r0, #0                      @ success?
13061    bne     .LOP_SPUT_CHAR_JUMBO_finish          @ yes, finish
13062    b       common_exceptionThrown      @ no, handle exception
13063
13064/* continuation for OP_SPUT_SHORT_JUMBO */
13065
13066    /*
13067     * Continuation if the field has not yet been resolved.
13068     *  r1: AAAAAAAA field ref
13069     */
13070.LOP_SPUT_SHORT_JUMBO_resolve:
13071    ldr     r2, [rGLUE, #offGlue_method]    @ r2<- current method
13072    EXPORT_PC()                         @ resolve() could throw, so export now
13073    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13074    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13075    cmp     r0, #0                      @ success?
13076    bne     .LOP_SPUT_SHORT_JUMBO_finish          @ yes, finish
13077    b       common_exceptionThrown      @ no, handle exception
13078
13079/* continuation for OP_INVOKE_VIRTUAL_JUMBO */
13080
13081    /*
13082     * At this point:
13083     *  r0 = resolved base method
13084     */
13085.LOP_INVOKE_VIRTUAL_JUMBO_continue:
13086    FETCH(r10, 4)                       @ r10<- CCCC
13087    GET_VREG(r1, r10)                   @ r1<- "this" ptr
13088    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
13089    cmp     r1, #0                      @ is "this" null?
13090    beq     common_errNullObject        @ null "this", throw exception
13091    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
13092    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
13093    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
13094    bl      common_invokeMethodJumbo    @ continue on
13095
13096/* continuation for OP_INVOKE_SUPER_JUMBO */
13097
13098    /*
13099     * At this point:
13100     *  r0 = resolved base method
13101     *  r9 = method->clazz
13102     */
13103.LOP_INVOKE_SUPER_JUMBO_continue:
13104    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
13105    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
13106    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
13107    EXPORT_PC()                         @ must export for invoke
13108    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
13109    bcs     .LOP_INVOKE_SUPER_JUMBO_nsm             @ method not present in superclass
13110    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
13111    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
13112    bl      common_invokeMethodJumbo    @ continue on
13113
13114.LOP_INVOKE_SUPER_JUMBO_resolve:
13115    mov     r0, r9                      @ r0<- method->clazz
13116    mov     r2, #METHOD_VIRTUAL         @ resolver method type
13117    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
13118    cmp     r0, #0                      @ got null?
13119    bne     .LOP_INVOKE_SUPER_JUMBO_continue        @ no, continue
13120    b       common_exceptionThrown      @ yes, handle exception
13121
13122    /*
13123     * Throw a NoSuchMethodError with the method name as the message.
13124     *  r0 = resolved base method
13125     */
13126.LOP_INVOKE_SUPER_JUMBO_nsm:
13127    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
13128    b       common_errNoSuchMethod
13129
13130/* continuation for OP_INVOKE_DIRECT_JUMBO */
13131
13132    /*
13133     * On entry:
13134     *  r1 = reference (CCCC)
13135     *  r10 = "this" register
13136     */
13137.LOP_INVOKE_DIRECT_JUMBO_resolve:
13138    ldr     r3, [rGLUE, #offGlue_method] @ r3<- glue->method
13139    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
13140    mov     r2, #METHOD_DIRECT          @ resolver method type
13141    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
13142    cmp     r0, #0                      @ got null?
13143    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
13144    bne     .LOP_INVOKE_DIRECT_JUMBO_finish          @ no, continue
13145    b       common_exceptionThrown      @ yes, handle exception
13146
13147    .size   dvmAsmSisterStart, .-dvmAsmSisterStart
13148    .global dvmAsmSisterEnd
13149dvmAsmSisterEnd:
13150
13151/* File: armv5te/footer.S */
13152
13153/*
13154 * ===========================================================================
13155 *  Common subroutines and data
13156 * ===========================================================================
13157 */
13158
13159
13160
13161    .text
13162    .align  2
13163
13164#if defined(WITH_JIT)
13165#if defined(WITH_SELF_VERIFICATION)
13166    .global dvmJitToInterpPunt
13167dvmJitToInterpPunt:
13168    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13169    mov    r2,#kSVSPunt                 @ r2<- interpreter entry point
13170    mov    r3, #0
13171    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13172    b      jitSVShadowRunEnd            @ doesn't return
13173
13174    .global dvmJitToInterpSingleStep
13175dvmJitToInterpSingleStep:
13176    str    lr,[rGLUE,#offGlue_jitResumeNPC]
13177    str    r1,[rGLUE,#offGlue_jitResumeDPC]
13178    mov    r2,#kSVSSingleStep           @ r2<- interpreter entry point
13179    b      jitSVShadowRunEnd            @ doesn't return
13180
13181    .global dvmJitToInterpNoChainNoProfile
13182dvmJitToInterpNoChainNoProfile:
13183    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13184    mov    r0,rPC                       @ pass our target PC
13185    mov    r2,#kSVSNoProfile            @ r2<- interpreter entry point
13186    mov    r3, #0                       @ 0 means !inJitCodeCache
13187    str    r3, [r10, #offThread_inJitCodeCache] @ back to the interp land
13188    b      jitSVShadowRunEnd            @ doesn't return
13189
13190    .global dvmJitToInterpTraceSelectNoChain
13191dvmJitToInterpTraceSelectNoChain:
13192    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13193    mov    r0,rPC                       @ pass our target PC
13194    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
13195    mov    r3, #0                       @ 0 means !inJitCodeCache
13196    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13197    b      jitSVShadowRunEnd            @ doesn't return
13198
13199    .global dvmJitToInterpTraceSelect
13200dvmJitToInterpTraceSelect:
13201    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13202    ldr    r0,[lr, #-1]                 @ pass our target PC
13203    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
13204    mov    r3, #0                       @ 0 means !inJitCodeCache
13205    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13206    b      jitSVShadowRunEnd            @ doesn't return
13207
13208    .global dvmJitToInterpBackwardBranch
13209dvmJitToInterpBackwardBranch:
13210    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13211    ldr    r0,[lr, #-1]                 @ pass our target PC
13212    mov    r2,#kSVSBackwardBranch       @ r2<- interpreter entry point
13213    mov    r3, #0                       @ 0 means !inJitCodeCache
13214    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13215    b      jitSVShadowRunEnd            @ doesn't return
13216
13217    .global dvmJitToInterpNormal
13218dvmJitToInterpNormal:
13219    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13220    ldr    r0,[lr, #-1]                 @ pass our target PC
13221    mov    r2,#kSVSNormal               @ r2<- interpreter entry point
13222    mov    r3, #0                       @ 0 means !inJitCodeCache
13223    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13224    b      jitSVShadowRunEnd            @ doesn't return
13225
13226    .global dvmJitToInterpNoChain
13227dvmJitToInterpNoChain:
13228    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13229    mov    r0,rPC                       @ pass our target PC
13230    mov    r2,#kSVSNoChain              @ r2<- interpreter entry point
13231    mov    r3, #0                       @ 0 means !inJitCodeCache
13232    str    r3, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13233    b      jitSVShadowRunEnd            @ doesn't return
13234#else
13235/*
13236 * Return from the translation cache to the interpreter when the compiler is
13237 * having issues translating/executing a Dalvik instruction. We have to skip
13238 * the code cache lookup otherwise it is possible to indefinitely bouce
13239 * between the interpreter and the code cache if the instruction that fails
13240 * to be compiled happens to be at a trace start.
13241 */
13242    .global dvmJitToInterpPunt
13243dvmJitToInterpPunt:
13244    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13245    mov    rPC, r0
13246#if defined(WITH_JIT_TUNING)
13247    mov    r0,lr
13248    bl     dvmBumpPunt;
13249#endif
13250    EXPORT_PC()
13251    mov    r0, #0
13252    str    r0, [r10, #offThread_inJitCodeCache] @ Back to the interp land
13253    adrl   rIBASE, dvmAsmInstructionStart
13254    FETCH_INST()
13255    GET_INST_OPCODE(ip)
13256    GOTO_OPCODE(ip)
13257
13258/*
13259 * Return to the interpreter to handle a single instruction.
13260 * On entry:
13261 *    r0 <= PC
13262 *    r1 <= PC of resume instruction
13263 *    lr <= resume point in translation
13264 */
13265    .global dvmJitToInterpSingleStep
13266dvmJitToInterpSingleStep:
13267    str    lr,[rGLUE,#offGlue_jitResumeNPC]
13268    str    r1,[rGLUE,#offGlue_jitResumeDPC]
13269    mov    r1,#kInterpEntryInstr
13270    @ enum is 4 byte in aapcs-EABI
13271    str    r1, [rGLUE, #offGlue_entryPoint]
13272    mov    rPC,r0
13273    EXPORT_PC()
13274
13275    adrl   rIBASE, dvmAsmInstructionStart
13276    mov    r2,#kJitSingleStep     @ Ask for single step and then revert
13277    str    r2,[rGLUE,#offGlue_jitState]
13278    mov    r1,#1                  @ set changeInterp to bail to debug interp
13279    b      common_gotoBail
13280
13281/*
13282 * Return from the translation cache and immediately request
13283 * a translation for the exit target.  Commonly used for callees.
13284 */
13285    .global dvmJitToInterpTraceSelectNoChain
13286dvmJitToInterpTraceSelectNoChain:
13287#if defined(WITH_JIT_TUNING)
13288    bl     dvmBumpNoChain
13289#endif
13290    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13291    mov    r0,rPC
13292    bl     dvmJitGetTraceAddr       @ Is there a translation?
13293    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13294    mov    r1, rPC                  @ arg1 of translation may need this
13295    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13296    cmp    r0,#0                    @ !0 means translation exists
13297    bxne   r0                       @ continue native execution if so
13298    b      2f                       @ branch over to use the interpreter
13299
13300/*
13301 * Return from the translation cache and immediately request
13302 * a translation for the exit target.  Commonly used following
13303 * invokes.
13304 */
13305    .global dvmJitToInterpTraceSelect
13306dvmJitToInterpTraceSelect:
13307    ldr    rPC,[lr, #-1]           @ get our target PC
13308    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13309    add    rINST,lr,#-5            @ save start of chain branch
13310    add    rINST, #-4              @  .. which is 9 bytes back
13311    mov    r0,rPC
13312    bl     dvmJitGetTraceAddr      @ Is there a translation?
13313    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13314    cmp    r0,#0
13315    beq    2f
13316    mov    r1,rINST
13317    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
13318    mov    r1, rPC                  @ arg1 of translation may need this
13319    mov    lr, #0                   @ in case target is HANDLER_INTERPRET
13320    cmp    r0,#0                    @ successful chain?
13321    bxne   r0                       @ continue native execution
13322    b      toInterpreter            @ didn't chain - resume with interpreter
13323
13324/* No translation, so request one if profiling isn't disabled*/
133252:
13326    adrl   rIBASE, dvmAsmInstructionStart
13327    GET_JIT_PROF_TABLE(r0)
13328    FETCH_INST()
13329    cmp    r0, #0
13330    movne  r2,#kJitTSelectRequestHot   @ ask for trace selection
13331    bne    common_selectTrace
13332    GET_INST_OPCODE(ip)
13333    GOTO_OPCODE(ip)
13334
13335/*
13336 * Return from the translation cache to the interpreter.
13337 * The return was done with a BLX from thumb mode, and
13338 * the following 32-bit word contains the target rPC value.
13339 * Note that lr (r14) will have its low-order bit set to denote
13340 * its thumb-mode origin.
13341 *
13342 * We'll need to stash our lr origin away, recover the new
13343 * target and then check to see if there is a translation available
13344 * for our new target.  If so, we do a translation chain and
13345 * go back to native execution.  Otherwise, it's back to the
13346 * interpreter (after treating this entry as a potential
13347 * trace start).
13348 */
13349    .global dvmJitToInterpNormal
13350dvmJitToInterpNormal:
13351    ldr    rPC,[lr, #-1]           @ get our target PC
13352    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13353    add    rINST,lr,#-5            @ save start of chain branch
13354    add    rINST,#-4               @ .. which is 9 bytes back
13355#if defined(WITH_JIT_TUNING)
13356    bl     dvmBumpNormal
13357#endif
13358    mov    r0,rPC
13359    bl     dvmJitGetTraceAddr      @ Is there a translation?
13360    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13361    cmp    r0,#0
13362    beq    toInterpreter            @ go if not, otherwise do chain
13363    mov    r1,rINST
13364    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
13365    mov    r1, rPC                  @ arg1 of translation may need this
13366    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13367    cmp    r0,#0                    @ successful chain?
13368    bxne   r0                       @ continue native execution
13369    b      toInterpreter            @ didn't chain - resume with interpreter
13370
13371/*
13372 * Return from the translation cache to the interpreter to do method invocation.
13373 * Check if translation exists for the callee, but don't chain to it.
13374 */
13375    .global dvmJitToInterpNoChainNoProfile
13376dvmJitToInterpNoChainNoProfile:
13377#if defined(WITH_JIT_TUNING)
13378    bl     dvmBumpNoChain
13379#endif
13380    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13381    mov    r0,rPC
13382    bl     dvmJitGetTraceAddr       @ Is there a translation?
13383    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13384    mov    r1, rPC                  @ arg1 of translation may need this
13385    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13386    cmp    r0,#0
13387    bxne   r0                       @ continue native execution if so
13388    EXPORT_PC()
13389    adrl   rIBASE, dvmAsmInstructionStart
13390    FETCH_INST()
13391    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13392    GOTO_OPCODE(ip)                     @ jump to next instruction
13393
13394/*
13395 * Return from the translation cache to the interpreter to do method invocation.
13396 * Check if translation exists for the callee, but don't chain to it.
13397 */
13398    .global dvmJitToInterpNoChain
13399dvmJitToInterpNoChain:
13400#if defined(WITH_JIT_TUNING)
13401    bl     dvmBumpNoChain
13402#endif
13403    ldr    r10, [rGLUE, #offGlue_self]  @ callee saved r10 <- glue->self
13404    mov    r0,rPC
13405    bl     dvmJitGetTraceAddr       @ Is there a translation?
13406    str    r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13407    mov    r1, rPC                  @ arg1 of translation may need this
13408    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13409    cmp    r0,#0
13410    bxne   r0                       @ continue native execution if so
13411#endif
13412
13413/*
13414 * No translation, restore interpreter regs and start interpreting.
13415 * rGLUE & rFP were preserved in the translated code, and rPC has
13416 * already been restored by the time we get here.  We'll need to set
13417 * up rIBASE & rINST, and load the address of the JitTable into r0.
13418 */
13419toInterpreter:
13420    EXPORT_PC()
13421    adrl   rIBASE, dvmAsmInstructionStart
13422    FETCH_INST()
13423    GET_JIT_PROF_TABLE(r0)
13424    @ NOTE: intended fallthrough
13425
13426/*
13427 * Common code to update potential trace start counter, and initiate
13428 * a trace-build if appropriate.  On entry, rPC should point to the
13429 * next instruction to execute, and rINST should be already loaded with
13430 * the next opcode word, and r0 holds a pointer to the jit profile
13431 * table (pJitProfTable).
13432 */
13433common_testUpdateProfile:
13434    cmp     r0,#0
13435    GET_INST_OPCODE(ip)
13436    GOTO_OPCODE_IFEQ(ip)       @ if not profiling, fallthrough otherwise */
13437
13438common_updateProfile:
13439    eor     r3,rPC,rPC,lsr #12 @ cheap, but fast hash function
13440    lsl     r3,r3,#(32 - JIT_PROF_SIZE_LOG_2)          @ shift out excess bits
13441    ldrb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter
13442    GET_INST_OPCODE(ip)
13443    subs    r1,r1,#1           @ decrement counter
13444    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it
13445    GOTO_OPCODE_IFNE(ip)       @ if not threshold, fallthrough otherwise */
13446
13447/*
13448 * Here, we switch to the debug interpreter to request
13449 * trace selection.  First, though, check to see if there
13450 * is already a native translation in place (and, if so,
13451 * jump to it now).
13452 */
13453    GET_JIT_THRESHOLD(r1)
13454    ldr     r10, [rGLUE, #offGlue_self] @ callee saved r10 <- glue->self
13455    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter
13456    EXPORT_PC()
13457    mov     r0,rPC
13458    bl      dvmJitGetTraceAddr          @ r0<- dvmJitGetTraceAddr(rPC)
13459    str     r0, [r10, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13460    mov     r1, rPC                     @ arg1 of translation may need this
13461    mov     lr, #0                      @  in case target is HANDLER_INTERPRET
13462    cmp     r0,#0
13463#if !defined(WITH_SELF_VERIFICATION)
13464    bxne    r0                          @ jump to the translation
13465    mov     r2,#kJitTSelectRequest      @ ask for trace selection
13466    @ fall-through to common_selectTrace
13467#else
13468    moveq   r2,#kJitTSelectRequest      @ ask for trace selection
13469    beq     common_selectTrace
13470    /*
13471     * At this point, we have a target translation.  However, if
13472     * that translation is actually the interpret-only pseudo-translation
13473     * we want to treat it the same as no translation.
13474     */
13475    mov     r10, r0                     @ save target
13476    bl      dvmCompilerGetInterpretTemplate
13477    cmp     r0, r10                     @ special case?
13478    bne     jitSVShadowRunStart         @ set up self verification shadow space
13479    @ Need to clear the inJitCodeCache flag
13480    ldr    r10, [rGLUE, #offGlue_self]  @ r10 <- glue->self
13481    mov    r3, #0                       @ 0 means not in the JIT code cache
13482    str    r3, [r10, #offThread_inJitCodeCache] @ back to the interp land
13483    GET_INST_OPCODE(ip)
13484    GOTO_OPCODE(ip)
13485    /* no return */
13486#endif
13487
13488/*
13489 * On entry:
13490 *  r2 is jit state, e.g. kJitTSelectRequest or kJitTSelectRequestHot
13491 */
13492common_selectTrace:
13493    str     r2,[rGLUE,#offGlue_jitState]
13494    mov     r2,#kInterpEntryInstr       @ normal entry reason
13495    str     r2,[rGLUE,#offGlue_entryPoint]
13496    mov     r1,#1                       @ set changeInterp
13497    b       common_gotoBail
13498
13499#if defined(WITH_SELF_VERIFICATION)
13500/*
13501 * Save PC and registers to shadow memory for self verification mode
13502 * before jumping to native translation.
13503 * On entry:
13504 *    rPC, rFP, rGLUE: the values that they should contain
13505 *    r10: the address of the target translation.
13506 */
13507jitSVShadowRunStart:
13508    mov     r0,rPC                      @ r0<- program counter
13509    mov     r1,rFP                      @ r1<- frame pointer
13510    mov     r2,rGLUE                    @ r2<- InterpState pointer
13511    mov     r3,r10                      @ r3<- target translation
13512    bl      dvmSelfVerificationSaveState @ save registers to shadow space
13513    ldr     rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space
13514    add     rGLUE,r0,#offShadowSpace_interpState @ rGLUE<- rGLUE in shadow space
13515    bx      r10                         @ jump to the translation
13516
13517/*
13518 * Restore PC, registers, and interpState to original values
13519 * before jumping back to the interpreter.
13520 */
13521jitSVShadowRunEnd:
13522    mov    r1,rFP                        @ pass ending fp
13523    bl     dvmSelfVerificationRestoreState @ restore pc and fp values
13524    ldr    rPC,[r0,#offShadowSpace_startPC] @ restore PC
13525    ldr    rFP,[r0,#offShadowSpace_fp]   @ restore FP
13526    ldr    rGLUE,[r0,#offShadowSpace_glue] @ restore InterpState
13527    ldr    r1,[r0,#offShadowSpace_svState] @ get self verification state
13528    cmp    r1,#0                         @ check for punt condition
13529    beq    1f
13530    mov    r2,#kJitSelfVerification      @ ask for self verification
13531    str    r2,[rGLUE,#offGlue_jitState]
13532    mov    r2,#kInterpEntryInstr         @ normal entry reason
13533    str    r2,[rGLUE,#offGlue_entryPoint]
13534    mov    r1,#1                         @ set changeInterp
13535    b      common_gotoBail
13536
135371:                                       @ exit to interpreter without check
13538    EXPORT_PC()
13539    adrl   rIBASE, dvmAsmInstructionStart
13540    FETCH_INST()
13541    GET_INST_OPCODE(ip)
13542    GOTO_OPCODE(ip)
13543#endif
13544
13545#endif
13546
13547/*
13548 * Common code when a backward branch is taken.
13549 *
13550 * TODO: we could avoid a branch by just setting r0 and falling through
13551 * into the common_periodicChecks code, and having a test on r0 at the
13552 * end determine if we should return to the caller or update & branch to
13553 * the next instr.
13554 *
13555 * On entry:
13556 *  r9 is PC adjustment *in bytes*
13557 */
13558common_backwardBranch:
13559    mov     r0, #kInterpEntryInstr
13560    bl      common_periodicChecks
13561#if defined(WITH_JIT)
13562    GET_JIT_PROF_TABLE(r0)
13563    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
13564    cmp     r0,#0
13565    bne     common_updateProfile
13566    GET_INST_OPCODE(ip)
13567    GOTO_OPCODE(ip)
13568#else
13569    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
13570    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13571    GOTO_OPCODE(ip)                     @ jump to next instruction
13572#endif
13573
13574
13575/*
13576 * Need to see if the thread needs to be suspended or debugger/profiler
13577 * activity has begun.  If so, we suspend the thread or side-exit to
13578 * the debug interpreter as appropriate.
13579 *
13580 * The common case is no activity on any of these, so we want to figure
13581 * that out quickly.  If something is up, we can then sort out what.
13582 *
13583 * We want to be fast if the VM was built without debugger or profiler
13584 * support, but we also need to recognize that the system is usually
13585 * shipped with both of these enabled.
13586 *
13587 * TODO: reduce this so we're just checking a single location.
13588 *
13589 * On entry:
13590 *  r0 is reentry type, e.g. kInterpEntryInstr (for debugger/profiling)
13591 *  r9 is trampoline PC adjustment *in bytes*
13592 */
13593common_periodicChecks:
13594    ldr     r1, [rGLUE, #offGlue_pInterpBreak] @ r3<- &interpBreak
13595    /* speculatively load address of thread-specific suspend count */
13596    ldr     r3, [rGLUE, #offGlue_pSelfSuspendCount] @ r3<- &suspendCount
13597    ldr     r1, [r1]                                @ r1<- interpBreak
13598    /* speculatively load thread-specific suspend count */
13599    ldr     ip, [r3]                    @ ip<- suspendCount (int)
13600    cmp     r1, #0                                  @ anything unusual?
13601    bxeq    lr                                      @ return if not
13602    /*
13603     * One or more interesting events have happened.  Figure out what.
13604     *
13605     * r0 still holds the reentry type.
13606     */
13607    cmp     ip, #0                      @ want suspend?
13608    beq     3f                          @ no, must be something else
13609
13610    stmfd   sp!, {r0, lr}               @ preserve r0 and lr
13611#if defined(WITH_JIT)
13612    /*
13613     * Refresh the Jit's cached copy of profile table pointer.  This pointer
13614     * doubles as the Jit's on/off switch.
13615     */
13616    ldr     r3, [rGLUE, #offGlue_ppJitProfTable] @ r3<-&gDvmJit.pJitProfTable
13617    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
13618    ldr     r3, [r3] @ r3 <- pJitProfTable
13619    EXPORT_PC()                         @ need for precise GC
13620    str     r3, [rGLUE, #offGlue_pJitProfTable] @ refresh Jit's on/off switch
13621#else
13622    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- glue->self
13623    EXPORT_PC()                         @ need for precise GC
13624#endif
13625    bl      dvmCheckSuspendPending      @ do full check, suspend if necessary
13626    ldmfd   sp!, {r0, lr}               @ restore r0 and lr
13627
13628    /*
13629     * Reload the interpBreak flags - they may have changed while we
13630     * were suspended.
13631     */
13632    ldr     r1, [rGLUE, #offGlue_pInterpBreak]   @ r1<- &interpBreak
13633    ldr     r1, [r1]                    @ r1<- interpBreak
136343:
13635    /*
13636     * TODO: this code is too fragile.  Need a general mechanism
13637     * to identify what actions to take by submode.  Some profiling modes
13638     * (instruction count) need to single-step, while method tracing
13639     * may not.  Debugging with breakpoints can run unfettered, but
13640     * source-level single-stepping requires Dalvik singlestepping.
13641     * GC may require a one-shot action and then full-speed resumption.
13642     */
13643    ands    r1, #(kSubModeDebuggerActive | kSubModeEmulatorTrace | kSubModeInstCounting)
13644    bxeq    lr                          @ nothing to do, return
13645
13646    @ debugger/profiler enabled, bail out; glue->entryPoint was set above
13647    str     r0, [rGLUE, #offGlue_entryPoint]    @ store r0, need for debug/prof
13648    add     rPC, rPC, r9                @ update rPC
13649    mov     r1, #1                      @ "want switch" = true
13650    b       common_gotoBail             @ side exit
13651
13652
13653/*
13654 * The equivalent of "goto bail", this calls through the "bail handler".
13655 *
13656 * State registers will be saved to the "glue" area before bailing.
13657 *
13658 * On entry:
13659 *  r1 is "bool changeInterp", indicating if we want to switch to the
13660 *     other interpreter or just bail all the way out
13661 */
13662common_gotoBail:
13663    SAVE_PC_FP_TO_GLUE()                @ export state to "glue"
13664    mov     r0, rGLUE                   @ r0<- glue ptr
13665    b       dvmMterpStdBail             @ call(glue, changeInterp)
13666
13667    @add     r1, r1, #1                  @ using (boolean+1)
13668    @add     r0, rGLUE, #offGlue_jmpBuf  @ r0<- &glue->jmpBuf
13669    @bl      _longjmp                    @ does not return
13670    @bl      common_abort
13671
13672
13673/*
13674 * Common code for jumbo method invocation.
13675 * NOTE: this adjusts rPC to account for the difference in instruction width.
13676 * As a result, the savedPc in the stack frame will not be wholly accurate. So
13677 * long as that is only used for source file line number calculations, we're
13678 * okay.
13679 *
13680 * On entry:
13681 *  r0 is "Method* methodToCall", the method we're trying to call
13682 */
13683common_invokeMethodJumbo:
13684.LinvokeNewJumbo:
13685    @ prepare to copy args to "outs" area of current frame
13686    add     rPC, rPC, #4                @ adjust pc to make return consistent
13687    FETCH(r2, 1)                        @ r2<- BBBB (arg count)
13688    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13689    cmp     r2, #0                      @ no args?
13690    beq     .LinvokeArgsDone            @ if no args, skip the rest
13691    FETCH(r1, 2)                        @ r1<- CCCC
13692    b       .LinvokeRangeArgs           @ handle args like invoke range
13693
13694/*
13695 * Common code for method invocation with range.
13696 *
13697 * On entry:
13698 *  r0 is "Method* methodToCall", the method we're trying to call
13699 */
13700common_invokeMethodRange:
13701.LinvokeNewRange:
13702    @ prepare to copy args to "outs" area of current frame
13703    movs    r2, rINST, lsr #8           @ r2<- AA (arg count) -- test for zero
13704    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13705    beq     .LinvokeArgsDone            @ if no args, skip the rest
13706    FETCH(r1, 2)                        @ r1<- CCCC
13707
13708.LinvokeRangeArgs:
13709    @ r0=methodToCall, r1=CCCC, r2=count, r10=outs
13710    @ (very few methods have > 10 args; could unroll for common cases)
13711    add     r3, rFP, r1, lsl #2         @ r3<- &fp[CCCC]
13712    sub     r10, r10, r2, lsl #2        @ r10<- "outs" area, for call args
137131:  ldr     r1, [r3], #4                @ val = *fp++
13714    subs    r2, r2, #1                  @ count--
13715    str     r1, [r10], #4               @ *outs++ = val
13716    bne     1b                          @ ...while count != 0
13717    b       .LinvokeArgsDone
13718
13719/*
13720 * Common code for method invocation without range.
13721 *
13722 * On entry:
13723 *  r0 is "Method* methodToCall", the method we're trying to call
13724 */
13725common_invokeMethodNoRange:
13726.LinvokeNewNoRange:
13727    @ prepare to copy args to "outs" area of current frame
13728    movs    r2, rINST, lsr #12          @ r2<- B (arg count) -- test for zero
13729    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13730    FETCH(r1, 2)                        @ r1<- GFED (load here to hide latency)
13731    beq     .LinvokeArgsDone
13732
13733    @ r0=methodToCall, r1=GFED, r2=count, r10=outs
13734.LinvokeNonRange:
13735    rsb     r2, r2, #5                  @ r2<- 5-r2
13736    add     pc, pc, r2, lsl #4          @ computed goto, 4 instrs each
13737    bl      common_abort                @ (skipped due to ARM prefetch)
137385:  and     ip, rINST, #0x0f00          @ isolate A
13739    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vA (shift right 8, left 2)
13740    mov     r0, r0                      @ nop
13741    str     r2, [r10, #-4]!             @ *--outs = vA
137424:  and     ip, r1, #0xf000             @ isolate G
13743    ldr     r2, [rFP, ip, lsr #10]      @ r2<- vG (shift right 12, left 2)
13744    mov     r0, r0                      @ nop
13745    str     r2, [r10, #-4]!             @ *--outs = vG
137463:  and     ip, r1, #0x0f00             @ isolate F
13747    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vF
13748    mov     r0, r0                      @ nop
13749    str     r2, [r10, #-4]!             @ *--outs = vF
137502:  and     ip, r1, #0x00f0             @ isolate E
13751    ldr     r2, [rFP, ip, lsr #2]       @ r2<- vE
13752    mov     r0, r0                      @ nop
13753    str     r2, [r10, #-4]!             @ *--outs = vE
137541:  and     ip, r1, #0x000f             @ isolate D
13755    ldr     r2, [rFP, ip, lsl #2]       @ r2<- vD
13756    mov     r0, r0                      @ nop
13757    str     r2, [r10, #-4]!             @ *--outs = vD
137580:  @ fall through to .LinvokeArgsDone
13759
13760.LinvokeArgsDone: @ r0=methodToCall
13761    ldrh    r9, [r0, #offMethod_registersSize]  @ r9<- methodToCall->regsSize
13762    ldrh    r3, [r0, #offMethod_outsSize]  @ r3<- methodToCall->outsSize
13763    ldr     r2, [r0, #offMethod_insns]  @ r2<- method->insns
13764    ldr     rINST, [r0, #offMethod_clazz]  @ rINST<- method->clazz
13765    @ find space for the new stack frame, check for overflow
13766    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- stack save area
13767    sub     r1, r1, r9, lsl #2          @ r1<- newFp (old savearea - regsSize)
13768    SAVEAREA_FROM_FP(r10, r1)           @ r10<- newSaveArea
13769@    bl      common_dumpRegs
13770    ldr     r9, [rGLUE, #offGlue_interpStackEnd]    @ r9<- interpStackEnd
13771    sub     r3, r10, r3, lsl #2         @ r3<- bottom (newsave - outsSize)
13772    cmp     r3, r9                      @ bottom < interpStackEnd?
13773    ldr     lr, [rGLUE, #offGlue_pInterpBreak]
13774    ldr     r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags
13775    blo     .LstackOverflow             @ yes, this frame will overflow stack
13776
13777    @ set up newSaveArea
13778    ldr     lr, [lr]                    @ lr<- active submodes
13779#ifdef EASY_GDB
13780    SAVEAREA_FROM_FP(ip, rFP)           @ ip<- stack save area
13781    str     ip, [r10, #offStackSaveArea_prevSave]
13782#endif
13783    str     rFP, [r10, #offStackSaveArea_prevFrame]
13784    str     rPC, [r10, #offStackSaveArea_savedPc]
13785#if defined(WITH_JIT)
13786    mov     r9, #0
13787    str     r9, [r10, #offStackSaveArea_returnAddr]
13788#endif
13789    ands    lr, #kSubModeMethodTrace    @ method tracing?
13790    beq     1f                          @ skip if not
13791    stmfd   sp!, {r0-r3}                @ preserve r0-r3
13792    mov     r1, r6
13793    @ r0=methodToCall, r1=rGlue
13794    bl      dvmFastMethodTraceEnter
13795    ldmfd   sp!, {r0-r3}                @ restore r0-r3
137961:
13797    str     r0, [r10, #offStackSaveArea_method]
13798    tst     r3, #ACC_NATIVE
13799    bne     .LinvokeNative
13800
13801    /*
13802    stmfd   sp!, {r0-r3}
13803    bl      common_printNewline
13804    mov     r0, rFP
13805    mov     r1, #0
13806    bl      dvmDumpFp
13807    ldmfd   sp!, {r0-r3}
13808    stmfd   sp!, {r0-r3}
13809    mov     r0, r1
13810    mov     r1, r10
13811    bl      dvmDumpFp
13812    bl      common_printNewline
13813    ldmfd   sp!, {r0-r3}
13814    */
13815
13816    ldrh    r9, [r2]                        @ r9 <- load INST from new PC
13817    ldr     r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
13818    mov     rPC, r2                         @ publish new rPC
13819    ldr     r2, [rGLUE, #offGlue_self]      @ r2<- glue->self
13820
13821    @ Update "glue" values for the new method
13822    @ r0=methodToCall, r1=newFp, r2=self, r3=newMethodClass, r9=newINST
13823    str     r0, [rGLUE, #offGlue_method]    @ glue->method = methodToCall
13824    str     r3, [rGLUE, #offGlue_methodClassDex] @ glue->methodClassDex = ...
13825#if defined(WITH_JIT)
13826    GET_JIT_PROF_TABLE(r0)
13827    mov     rFP, r1                         @ fp = newFp
13828    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
13829    mov     rINST, r9                       @ publish new rINST
13830    str     r1, [r2, #offThread_curFrame]   @ self->curFrame = newFp
13831    cmp     r0,#0
13832    bne     common_updateProfile
13833    GOTO_OPCODE(ip)                         @ jump to next instruction
13834#else
13835    mov     rFP, r1                         @ fp = newFp
13836    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
13837    mov     rINST, r9                       @ publish new rINST
13838    str     r1, [r2, #offThread_curFrame]   @ self->curFrame = newFp
13839    GOTO_OPCODE(ip)                         @ jump to next instruction
13840#endif
13841
13842.LinvokeNative:
13843    @ Prep for the native call
13844    @ r0=methodToCall, r1=newFp, r10=newSaveArea
13845    ldr     r3, [rGLUE, #offGlue_self]      @ r3<- glue->self
13846    ldr     lr, [rGLUE, #offGlue_pInterpBreak]
13847    ldr     r9, [r3, #offThread_jniLocal_topCookie] @ r9<- thread->localRef->...
13848    str     r1, [r3, #offThread_curFrame]   @ self->curFrame = newFp
13849    str     r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top
13850    ldr     lr, [lr]                    @ lr<- active submodes
13851    mov     r9, r3                      @ r9<- glue->self (preserve)
13852
13853    mov     r2, r0                      @ r2<- methodToCall
13854    mov     r0, r1                      @ r0<- newFp (points to args)
13855    add     r1, rGLUE, #offGlue_retval  @ r1<- &retval
13856
13857#ifdef ASSIST_DEBUGGER
13858    /* insert fake function header to help gdb find the stack frame */
13859    b       .Lskip
13860    .type   dalvik_mterp, %function
13861dalvik_mterp:
13862    .fnstart
13863    MTERP_ENTRY1
13864    MTERP_ENTRY2
13865.Lskip:
13866#endif
13867
13868    ands    lr, #kSubModeMethodTrace    @ method tracing?
13869    beq     110f                        @ hop if not
13870    @ r2=JNIMethod, r6=rGLUE
13871    stmfd   sp!, {r2,r6}
13872
13873    mov     lr, pc                      @ set return addr
13874    ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
13875
13876    @ r0=JNIMethod, r1=rGLUE
13877    ldmfd   sp!, {r0-r1}
13878    bl      dvmFastNativeMethodTraceExit
13879    @ r2=JNIMethod, r6=rGLUE
13880    stmfd   sp!, {r2,r6}
13881    b       220f
13882110:
13883    mov     lr, pc                      @ set return addr
13884    ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
13885220:
13886#if defined(WITH_JIT)
13887    ldr     r3, [rGLUE, #offGlue_ppJitProfTable] @ Refresh Jit's on/off status
13888#endif
13889
13890    @ native return; r9=self, r10=newSaveArea
13891    @ equivalent to dvmPopJniLocals
13892    ldr     r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top
13893    ldr     r1, [r9, #offThread_exception] @ check for exception
13894#if defined(WITH_JIT)
13895    ldr     r3, [r3]                    @ r3 <- gDvmJit.pProfTable
13896#endif
13897    str     rFP, [r9, #offThread_curFrame]  @ self->curFrame = fp
13898    cmp     r1, #0                      @ null?
13899    str     r0, [r9, #offThread_jniLocal_topCookie] @ new top <- old top
13900#if defined(WITH_JIT)
13901    str     r3, [rGLUE, #offGlue_pJitProfTable] @ refresh cached on/off switch
13902#endif
13903    bne     common_exceptionThrown      @ no, handle exception
13904
13905    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
13906    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13907    GOTO_OPCODE(ip)                     @ jump to next instruction
13908
13909.LstackOverflow:    @ r0=methodToCall
13910    mov     r1, r0                      @ r1<- methodToCall
13911    ldr     r0, [rGLUE, #offGlue_self]  @ r0<- self
13912    bl      dvmHandleStackOverflow
13913    b       common_exceptionThrown
13914#ifdef ASSIST_DEBUGGER
13915    .fnend
13916    .size   dalvik_mterp, .-dalvik_mterp
13917#endif
13918
13919
13920    /*
13921     * Common code for method invocation, calling through "glue code".
13922     *
13923     * TODO: now that we have range and non-range invoke handlers, this
13924     *       needs to be split into two.  Maybe just create entry points
13925     *       that set r9 and jump here?
13926     *
13927     * On entry:
13928     *  r0 is "Method* methodToCall", the method we're trying to call
13929     *  r9 is "bool methodCallRange", indicating if this is a /range variant
13930     */
13931     .if    0
13932.LinvokeOld:
13933    sub     sp, sp, #8                  @ space for args + pad
13934    FETCH(ip, 2)                        @ ip<- FEDC or CCCC
13935    mov     r2, r0                      @ A2<- methodToCall
13936    mov     r0, rGLUE                   @ A0<- glue
13937    SAVE_PC_FP_TO_GLUE()                @ export state to "glue"
13938    mov     r1, r9                      @ A1<- methodCallRange
13939    mov     r3, rINST, lsr #8           @ A3<- AA
13940    str     ip, [sp, #0]                @ A4<- ip
13941    bl      dvmMterp_invokeMethod       @ call the C invokeMethod
13942    add     sp, sp, #8                  @ remove arg area
13943    b       common_resumeAfterGlueCall  @ continue to next instruction
13944    .endif
13945
13946
13947
13948/*
13949 * Common code for handling a return instruction.
13950 *
13951 * This does not return.
13952 */
13953common_returnFromMethod:
13954.LreturnNew:
13955    mov     r0, #kInterpEntryReturn
13956    mov     r9, #0
13957    bl      common_periodicChecks
13958
13959    ldr     lr, [rGLUE, #offGlue_pInterpBreak]
13960    SAVEAREA_FROM_FP(r0, rFP)
13961    ldr     lr, [lr]                    @ lr<- active submodes
13962    ldr     r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc
13963    ands    lr, #kSubModeMethodTrace    @ method tracing?
13964    beq     333f
13965    stmfd   sp!, {r0-r3}                @ preserve r0-r3
13966    mov     r0, r6
13967    @ r0=rGlue
13968    bl      dvmFastJavaMethodTraceExit
13969    ldmfd   sp!, {r0-r3}                @ restore r0-r3
13970333:
13971    ldr     rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame
13972    ldr     r3, [rGLUE, #offGlue_self]  @ r3<- glue->self
13973    ldr     r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)]
13974                                        @ r2<- method we're returning to
13975    cmp     r2, #0                      @ is this a break frame?
13976#if defined(WORKAROUND_CORTEX_A9_745320)
13977    /* Don't use conditional loads if the HW defect exists */
13978    beq     101f
13979    ldr     r10, [r2, #offMethod_clazz] @ r10<- method->clazz
13980101:
13981#else
13982    ldrne   r10, [r2, #offMethod_clazz] @ r10<- method->clazz
13983#endif
13984    mov     r1, #0                      @ "want switch" = false
13985    beq     common_gotoBail             @ break frame, bail out completely
13986
13987    PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST
13988    str     r2, [rGLUE, #offGlue_method]@ glue->method = newSave->method
13989    ldr     r1, [r10, #offClassObject_pDvmDex]   @ r1<- method->clazz->pDvmDex
13990    str     rFP, [r3, #offThread_curFrame]  @ self->curFrame = fp
13991#if defined(WITH_JIT)
13992    ldr     r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr
13993    mov     rPC, r9                     @ publish new rPC
13994    str     r1, [rGLUE, #offGlue_methodClassDex]
13995    str     r10, [r3, #offThread_inJitCodeCache]  @ may return to JIT'ed land
13996    cmp     r10, #0                      @ caller is compiled code
13997    blxne   r10
13998    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13999    GOTO_OPCODE(ip)                     @ jump to next instruction
14000#else
14001    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14002    mov     rPC, r9                     @ publish new rPC
14003    str     r1, [rGLUE, #offGlue_methodClassDex]
14004    GOTO_OPCODE(ip)                     @ jump to next instruction
14005#endif
14006
14007    /*
14008     * Return handling, calls through "glue code".
14009     */
14010     .if    0
14011.LreturnOld:
14012    SAVE_PC_FP_TO_GLUE()                @ export state
14013    mov     r0, rGLUE                   @ arg to function
14014    bl      dvmMterp_returnFromMethod
14015    b       common_resumeAfterGlueCall
14016    .endif
14017
14018
14019/*
14020 * Somebody has thrown an exception.  Handle it.
14021 *
14022 * If the exception processing code returns to us (instead of falling
14023 * out of the interpreter), continue with whatever the next instruction
14024 * now happens to be.
14025 *
14026 * This does not return.
14027 */
14028     .global dvmMterpCommonExceptionThrown
14029dvmMterpCommonExceptionThrown:
14030common_exceptionThrown:
14031.LexceptionNew:
14032    mov     r0, #kInterpEntryThrow
14033    mov     r9, #0
14034    bl      common_periodicChecks
14035
14036    ldr     r10, [rGLUE, #offGlue_self] @ r10<- glue->self
14037    ldr     r9, [r10, #offThread_exception] @ r9<- self->exception
14038    mov     r1, r10                     @ r1<- self
14039    mov     r0, r9                      @ r0<- exception
14040    bl      dvmAddTrackedAlloc          @ don't let the exception be GCed
14041    mov     r3, #0                      @ r3<- NULL
14042    str     r3, [r10, #offThread_exception] @ self->exception = NULL
14043
14044    /* set up args and a local for "&fp" */
14045    /* (str sp, [sp, #-4]!  would be perfect here, but is discouraged) */
14046    str     rFP, [sp, #-4]!             @ *--sp = fp
14047    mov     ip, sp                      @ ip<- &fp
14048    mov     r3, #0                      @ r3<- false
14049    str     ip, [sp, #-4]!              @ *--sp = &fp
14050    ldr     r1, [rGLUE, #offGlue_method] @ r1<- glue->method
14051    mov     r0, r10                     @ r0<- self
14052    ldr     r1, [r1, #offMethod_insns]  @ r1<- method->insns
14053    mov     r2, r9                      @ r2<- exception
14054    sub     r1, rPC, r1                 @ r1<- pc - method->insns
14055    mov     r1, r1, asr #1              @ r1<- offset in code units
14056
14057    /* call, r0 gets catchRelPc (a code-unit offset) */
14058    bl      dvmFindCatchBlock           @ call(self, relPc, exc, scan?, &fp)
14059
14060    /* fix earlier stack overflow if necessary; may trash rFP */
14061    ldrb    r1, [r10, #offThread_stackOverflowed]
14062    cmp     r1, #0                      @ did we overflow earlier?
14063    beq     1f                          @ no, skip ahead
14064    mov     rFP, r0                     @ save relPc result in rFP
14065    mov     r0, r10                     @ r0<- self
14066    mov     r1, r9                      @ r1<- exception
14067    bl      dvmCleanupStackOverflow     @ call(self)
14068    mov     r0, rFP                     @ restore result
140691:
14070
14071    /* update frame pointer and check result from dvmFindCatchBlock */
14072    ldr     rFP, [sp, #4]               @ retrieve the updated rFP
14073    cmp     r0, #0                      @ is catchRelPc < 0?
14074    add     sp, sp, #8                  @ restore stack
14075    bmi     .LnotCaughtLocally
14076
14077    /* adjust locals to match self->curFrame and updated PC */
14078    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- new save area
14079    ldr     r1, [r1, #offStackSaveArea_method] @ r1<- new method
14080    str     r1, [rGLUE, #offGlue_method]    @ glue->method = new method
14081    ldr     r2, [r1, #offMethod_clazz]      @ r2<- method->clazz
14082    ldr     r3, [r1, #offMethod_insns]      @ r3<- method->insns
14083    ldr     r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex
14084    add     rPC, r3, r0, asl #1             @ rPC<- method->insns + catchRelPc
14085    str     r2, [rGLUE, #offGlue_methodClassDex] @ glue->pDvmDex = meth...
14086
14087    /* release the tracked alloc on the exception */
14088    mov     r0, r9                      @ r0<- exception
14089    mov     r1, r10                     @ r1<- self
14090    bl      dvmReleaseTrackedAlloc      @ release the exception
14091
14092    /* restore the exception if the handler wants it */
14093    FETCH_INST()                        @ load rINST from rPC
14094    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14095    cmp     ip, #OP_MOVE_EXCEPTION      @ is it "move-exception"?
14096    streq   r9, [r10, #offThread_exception] @ yes, restore the exception
14097    GOTO_OPCODE(ip)                     @ jump to next instruction
14098
14099.LnotCaughtLocally: @ r9=exception, r10=self
14100    /* fix stack overflow if necessary */
14101    ldrb    r1, [r10, #offThread_stackOverflowed]
14102    cmp     r1, #0                      @ did we overflow earlier?
14103    movne   r0, r10                     @ if yes: r0<- self
14104    movne   r1, r9                      @ if yes: r1<- exception
14105    blne    dvmCleanupStackOverflow     @ if yes: call(self)
14106
14107    @ may want to show "not caught locally" debug messages here
14108#if DVM_SHOW_EXCEPTION >= 2
14109    /* call __android_log_print(prio, tag, format, ...) */
14110    /* "Exception %s from %s:%d not caught locally" */
14111    @ dvmLineNumFromPC(method, pc - method->insns)
14112    ldr     r0, [rGLUE, #offGlue_method]
14113    ldr     r1, [r0, #offMethod_insns]
14114    sub     r1, rPC, r1
14115    asr     r1, r1, #1
14116    bl      dvmLineNumFromPC
14117    str     r0, [sp, #-4]!
14118    @ dvmGetMethodSourceFile(method)
14119    ldr     r0, [rGLUE, #offGlue_method]
14120    bl      dvmGetMethodSourceFile
14121    str     r0, [sp, #-4]!
14122    @ exception->clazz->descriptor
14123    ldr     r3, [r9, #offObject_clazz]
14124    ldr     r3, [r3, #offClassObject_descriptor]
14125    @
14126    ldr     r2, strExceptionNotCaughtLocally
14127    ldr     r1, strLogTag
14128    mov     r0, #3                      @ LOG_DEBUG
14129    bl      __android_log_print
14130#endif
14131    str     r9, [r10, #offThread_exception] @ restore exception
14132    mov     r0, r9                      @ r0<- exception
14133    mov     r1, r10                     @ r1<- self
14134    bl      dvmReleaseTrackedAlloc      @ release the exception
14135    mov     r1, #0                      @ "want switch" = false
14136    b       common_gotoBail             @ bail out
14137
14138
14139    /*
14140     * Exception handling, calls through "glue code".
14141     */
14142    .if     0
14143.LexceptionOld:
14144    SAVE_PC_FP_TO_GLUE()                @ export state
14145    mov     r0, rGLUE                   @ arg to function
14146    bl      dvmMterp_exceptionThrown
14147    b       common_resumeAfterGlueCall
14148    .endif
14149
14150
14151/*
14152 * After returning from a "glued" function, pull out the updated
14153 * values and start executing at the next instruction.
14154 */
14155common_resumeAfterGlueCall:
14156    LOAD_PC_FP_FROM_GLUE()              @ pull rPC and rFP out of glue
14157    FETCH_INST()                        @ load rINST from rPC
14158    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14159    GOTO_OPCODE(ip)                     @ jump to next instruction
14160
14161/*
14162 * Invalid array index. Note that our calling convention is strange; we use r1
14163 * and r3 because those just happen to be the registers all our callers are
14164 * using. We shuffle them here before calling the C function.
14165 * r1: index
14166 * r3: size
14167 */
14168common_errArrayIndex:
14169    EXPORT_PC()
14170    mov     r0, r1
14171    mov     r1, r3
14172    bl      dvmThrowAIOOBE
14173    b       common_exceptionThrown
14174
14175/*
14176 * Integer divide or mod by zero.
14177 */
14178common_errDivideByZero:
14179    EXPORT_PC()
14180    ldr     r0, strArithmeticException
14181    ldr     r1, strDivideByZero
14182    bl      dvmThrowException
14183    b       common_exceptionThrown
14184
14185/*
14186 * Attempt to allocate an array with a negative size.
14187 */
14188common_errNegativeArraySize:
14189    EXPORT_PC()
14190    ldr     r0, strNegativeArraySizeException
14191    mov     r1, #0
14192    bl      dvmThrowException
14193    b       common_exceptionThrown
14194
14195/*
14196 * Invocation of a non-existent method.
14197 */
14198common_errNoSuchMethod:
14199    EXPORT_PC()
14200    ldr     r0, strNoSuchMethodError
14201    mov     r1, #0
14202    bl      dvmThrowException
14203    b       common_exceptionThrown
14204
14205/*
14206 * We encountered a null object when we weren't expecting one.  We
14207 * export the PC, throw a NullPointerException, and goto the exception
14208 * processing code.
14209 */
14210common_errNullObject:
14211    EXPORT_PC()
14212    ldr     r0, strNullPointerException
14213    mov     r1, #0
14214    bl      dvmThrowException
14215    b       common_exceptionThrown
14216
14217/*
14218 * For debugging, cause an immediate fault.  The source address will
14219 * be in lr (use a bl instruction to jump here).
14220 */
14221common_abort:
14222    ldr     pc, .LdeadFood
14223.LdeadFood:
14224    .word   0xdeadf00d
14225
14226/*
14227 * Spit out a "we were here", preserving all registers.  (The attempt
14228 * to save ip won't work, but we need to save an even number of
14229 * registers for EABI 64-bit stack alignment.)
14230 */
14231    .macro  SQUEAK num
14232common_squeak\num:
14233    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14234    ldr     r0, strSqueak
14235    mov     r1, #\num
14236    bl      printf
14237    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14238    bx      lr
14239    .endm
14240
14241    SQUEAK  0
14242    SQUEAK  1
14243    SQUEAK  2
14244    SQUEAK  3
14245    SQUEAK  4
14246    SQUEAK  5
14247
14248/*
14249 * Spit out the number in r0, preserving registers.
14250 */
14251common_printNum:
14252    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14253    mov     r1, r0
14254    ldr     r0, strSqueak
14255    bl      printf
14256    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14257    bx      lr
14258
14259/*
14260 * Print a newline, preserving registers.
14261 */
14262common_printNewline:
14263    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14264    ldr     r0, strNewline
14265    bl      printf
14266    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14267    bx      lr
14268
14269    /*
14270     * Print the 32-bit quantity in r0 as a hex value, preserving registers.
14271     */
14272common_printHex:
14273    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14274    mov     r1, r0
14275    ldr     r0, strPrintHex
14276    bl      printf
14277    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14278    bx      lr
14279
14280/*
14281 * Print the 64-bit quantity in r0-r1, preserving registers.
14282 */
14283common_printLong:
14284    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14285    mov     r3, r1
14286    mov     r2, r0
14287    ldr     r0, strPrintLong
14288    bl      printf
14289    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14290    bx      lr
14291
14292/*
14293 * Print full method info.  Pass the Method* in r0.  Preserves regs.
14294 */
14295common_printMethod:
14296    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14297    bl      dvmMterpPrintMethod
14298    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14299    bx      lr
14300
14301/*
14302 * Call a C helper function that dumps regs and possibly some
14303 * additional info.  Requires the C function to be compiled in.
14304 */
14305    .if     0
14306common_dumpRegs:
14307    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14308    bl      dvmMterpDumpArmRegs
14309    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14310    bx      lr
14311    .endif
14312
14313#if 0
14314/*
14315 * Experiment on VFP mode.
14316 *
14317 * uint32_t setFPSCR(uint32_t val, uint32_t mask)
14318 *
14319 * Updates the bits specified by "mask", setting them to the values in "val".
14320 */
14321setFPSCR:
14322    and     r0, r0, r1                  @ make sure no stray bits are set
14323    fmrx    r2, fpscr                   @ get VFP reg
14324    mvn     r1, r1                      @ bit-invert mask
14325    and     r2, r2, r1                  @ clear masked bits
14326    orr     r2, r2, r0                  @ set specified bits
14327    fmxr    fpscr, r2                   @ set VFP reg
14328    mov     r0, r2                      @ return new value
14329    bx      lr
14330
14331    .align  2
14332    .global dvmConfigureFP
14333    .type   dvmConfigureFP, %function
14334dvmConfigureFP:
14335    stmfd   sp!, {ip, lr}
14336    /* 0x03000000 sets DN/FZ */
14337    /* 0x00009f00 clears the six exception enable flags */
14338    bl      common_squeak0
14339    mov     r0, #0x03000000             @ r0<- 0x03000000
14340    add     r1, r0, #0x9f00             @ r1<- 0x03009f00
14341    bl      setFPSCR
14342    ldmfd   sp!, {ip, pc}
14343#endif
14344
14345
14346/*
14347 * String references, must be close to the code that uses them.
14348 */
14349    .align  2
14350strArithmeticException:
14351    .word   .LstrArithmeticException
14352strDivideByZero:
14353    .word   .LstrDivideByZero
14354strNegativeArraySizeException:
14355    .word   .LstrNegativeArraySizeException
14356strNoSuchMethodError:
14357    .word   .LstrNoSuchMethodError
14358strNullPointerException:
14359    .word   .LstrNullPointerException
14360
14361strLogTag:
14362    .word   .LstrLogTag
14363strExceptionNotCaughtLocally:
14364    .word   .LstrExceptionNotCaughtLocally
14365
14366strNewline:
14367    .word   .LstrNewline
14368strSqueak:
14369    .word   .LstrSqueak
14370strPrintHex:
14371    .word   .LstrPrintHex
14372strPrintLong:
14373    .word   .LstrPrintLong
14374
14375/*
14376 * Zero-terminated ASCII string data.
14377 *
14378 * On ARM we have two choices: do like gcc does, and LDR from a .word
14379 * with the address, or use an ADR pseudo-op to get the address
14380 * directly.  ADR saves 4 bytes and an indirection, but it's using a
14381 * PC-relative addressing mode and hence has a limited range, which
14382 * makes it not work well with mergeable string sections.
14383 */
14384    .section .rodata.str1.4,"aMS",%progbits,1
14385
14386.LstrBadEntryPoint:
14387    .asciz  "Bad entry point %d\n"
14388.LstrArithmeticException:
14389    .asciz  "Ljava/lang/ArithmeticException;"
14390.LstrDivideByZero:
14391    .asciz  "divide by zero"
14392.LstrFilledNewArrayNotImpl:
14393    .asciz  "filled-new-array only implemented for objects and 'int'"
14394.LstrInternalError:
14395    .asciz  "Ljava/lang/InternalError;"
14396.LstrInstantiationError:
14397    .asciz  "Ljava/lang/InstantiationError;"
14398.LstrNegativeArraySizeException:
14399    .asciz  "Ljava/lang/NegativeArraySizeException;"
14400.LstrNoSuchMethodError:
14401    .asciz  "Ljava/lang/NoSuchMethodError;"
14402.LstrNullPointerException:
14403    .asciz  "Ljava/lang/NullPointerException;"
14404
14405.LstrLogTag:
14406    .asciz  "mterp"
14407.LstrExceptionNotCaughtLocally:
14408    .asciz  "Exception %s from %s:%d not caught locally\n"
14409
14410.LstrNewline:
14411    .asciz  "\n"
14412.LstrSqueak:
14413    .asciz  "<%d>"
14414.LstrPrintHex:
14415    .asciz  "<0x%x>"
14416.LstrPrintLong:
14417    .asciz  "<%lld>"
14418
14419