InterpAsm-armv5te-vfp.S revision 8cb0d098d79af61546e275f633325794f4587602
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  rSELF     self (Thread) 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 rSELF   r6
79#define rINST   r7
80#define rIBASE  r8
81
82/* save/restore the PC and/or FP from the thread struct */
83#define LOAD_PC_FROM_SELF()     ldr     rPC, [rSELF, #offThread_pc]
84#define SAVE_PC_TO_SELF()       str     rPC, [rSELF, #offThread_pc]
85#define LOAD_FP_FROM_SELF()     ldr     rFP, [rSELF, #offThread_fp]
86#define SAVE_FP_TO_SELF()       str     rFP, [rSELF, #offThread_fp]
87#define LOAD_PC_FP_FROM_SELF()  ldmia   rSELF, {rPC, rFP}
88#define SAVE_PC_FP_TO_SELF()    stmia   rSELF, {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,[rSELF,#offThread_pJitProfTable]
190#define GET_JIT_THRESHOLD(_reg)     ldr _reg,[rSELF,#offThread_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  Thread* self
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, #offThread_bailPtr]  @ save SP for eventual return
288
289    /* set up "named" registers, figure out entry point */
290    mov     rSELF, r0                   @ set rSELF
291    ldr     r1, [r0, #offThread_entryPoint]   @ enum is 4 bytes in aapcs-EABI
292    LOAD_PC_FP_FROM_SELF()              @ load rPC and rFP from "thread"
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    /* Entry is always a possible trace start */
300    GET_JIT_PROF_TABLE(r0)
301    FETCH_INST()
302    mov     r1, #0                      @ prepare the value for the new state
303    str     r1, [rSELF, #offThread_inJitCodeCache] @ back to the interp land
304    cmp     r0,#0                       @ is profiling disabled?
305#if !defined(WITH_SELF_VERIFICATION)
306    bne     common_updateProfile        @ profiling is enabled
307#else
308    ldr     r2, [rSELF, #offThread_shadowSpace] @ to find out the jit exit state
309    beq     1f                          @ profiling is disabled
310    ldr     r3, [r2, #offShadowSpace_jitExitState]  @ jit exit state
311    cmp     r3, #kSVSTraceSelect        @ hot trace following?
312    moveq   r2,#kJitTSelectRequestHot   @ ask for trace selection
313    beq     common_selectTrace          @ go build the trace
314    cmp     r3, #kSVSNoProfile          @ don't profile the next instruction?
315    beq     1f                          @ intrepret the next instruction
316    b       common_updateProfile        @ collect profiles
317#endif
3181:
319    GET_INST_OPCODE(ip)
320    GOTO_OPCODE(ip)
321#else
322    /* start executing the instruction at rPC */
323    FETCH_INST()                        @ load rINST from rPC
324    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
325    GOTO_OPCODE(ip)                     @ jump to next instruction
326#endif
327
328.Lnot_instr:
329    cmp     r1, #kInterpEntryReturn     @ were we returning from a method?
330    beq     common_returnFromMethod
331
332.Lnot_return:
333    cmp     r1, #kInterpEntryThrow      @ were we throwing an exception?
334    beq     common_exceptionThrown
335
336#if defined(WITH_JIT)
337.Lnot_throw:
338    ldr     r10,[rSELF, #offThread_jitResumeNPC]
339    ldr     r2,[rSELF, #offThread_jitResumeDPC]
340    cmp     r1, #kInterpEntryResume     @ resuming after Jit single-step?
341    bne     .Lbad_arg
342    cmp     rPC,r2
343    bne     .LentryInstr                @ must have branched, don't resume
344#if defined(WITH_SELF_VERIFICATION)
345    @ self->entryPoint will be set in dvmSelfVerificationSaveState
346    b       jitSVShadowRunStart         @ re-enter the translation after the
347                                        @ single-stepped instruction
348    @noreturn
349#endif
350    mov     r1, #kInterpEntryInstr
351    str     r1, [rSELF, #offThread_entryPoint]
352    bx      r10                         @ re-enter the translation
353#endif
354
355.Lbad_arg:
356    ldr     r0, strBadEntryPoint
357    @ r1 holds value of entryPoint
358    bl      printf
359    bl      dvmAbort
360    .fnend
361    .size   dvmMterpStdRun, .-dvmMterpStdRun
362
363
364    .global dvmMterpStdBail
365    .type   dvmMterpStdBail, %function
366
367/*
368 * Restore the stack pointer and PC from the save point established on entry.
369 * This is essentially the same as a longjmp, but should be cheaper.  The
370 * last instruction causes us to return to whoever called dvmMterpStdRun.
371 *
372 * We pushed some registers on the stack in dvmMterpStdRun, then saved
373 * SP and LR.  Here we restore SP, restore the registers, and then restore
374 * LR to PC.
375 *
376 * On entry:
377 *  r0  Thread* self
378 *  r1  bool changeInterp
379 */
380dvmMterpStdBail:
381    ldr     sp, [r0, #offThread_bailPtr]      @ sp<- saved SP
382    mov     r0, r1                          @ return the changeInterp value
383    add     sp, sp, #4                      @ un-align 64
384    ldmfd   sp!, {r4-r10,fp,pc}             @ restore 9 regs and return
385
386
387/*
388 * String references.
389 */
390strBadEntryPoint:
391    .word   .LstrBadEntryPoint
392
393
394    .global dvmAsmInstructionStart
395    .type   dvmAsmInstructionStart, %function
396dvmAsmInstructionStart = .L_OP_NOP
397    .text
398
399/* ------------------------------ */
400    .balign 64
401.L_OP_NOP: /* 0x00 */
402/* File: armv5te/OP_NOP.S */
403    FETCH_ADVANCE_INST(1)               @ advance to next instr, load rINST
404    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
405    GOTO_OPCODE(ip)                     @ execute it
406
407#ifdef ASSIST_DEBUGGER
408    /* insert fake function header to help gdb find the stack frame */
409    .type   dalvik_inst, %function
410dalvik_inst:
411    .fnstart
412    MTERP_ENTRY1
413    MTERP_ENTRY2
414    .fnend
415#endif
416
417/* ------------------------------ */
418    .balign 64
419.L_OP_MOVE: /* 0x01 */
420/* File: armv5te/OP_MOVE.S */
421    /* for move, move-object, long-to-int */
422    /* op vA, vB */
423    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
424    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
425    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
426    GET_VREG(r2, r1)                    @ r2<- fp[B]
427    and     r0, r0, #15
428    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
429    SET_VREG(r2, r0)                    @ fp[A]<- r2
430    GOTO_OPCODE(ip)                     @ execute next instruction
431
432/* ------------------------------ */
433    .balign 64
434.L_OP_MOVE_FROM16: /* 0x02 */
435/* File: armv5te/OP_MOVE_FROM16.S */
436    /* for: move/from16, move-object/from16 */
437    /* op vAA, vBBBB */
438    FETCH(r1, 1)                        @ r1<- BBBB
439    mov     r0, rINST, lsr #8           @ r0<- AA
440    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
441    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
442    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
443    SET_VREG(r2, r0)                    @ fp[AA]<- r2
444    GOTO_OPCODE(ip)                     @ jump to next instruction
445
446/* ------------------------------ */
447    .balign 64
448.L_OP_MOVE_16: /* 0x03 */
449/* File: armv5te/OP_MOVE_16.S */
450    /* for: move/16, move-object/16 */
451    /* op vAAAA, vBBBB */
452    FETCH(r1, 2)                        @ r1<- BBBB
453    FETCH(r0, 1)                        @ r0<- AAAA
454    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
455    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
456    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
457    SET_VREG(r2, r0)                    @ fp[AAAA]<- r2
458    GOTO_OPCODE(ip)                     @ jump to next instruction
459
460/* ------------------------------ */
461    .balign 64
462.L_OP_MOVE_WIDE: /* 0x04 */
463/* File: armv5te/OP_MOVE_WIDE.S */
464    /* move-wide vA, vB */
465    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
466    mov     r2, rINST, lsr #8           @ r2<- A(+)
467    mov     r3, rINST, lsr #12          @ r3<- B
468    and     r2, r2, #15
469    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
470    add     r2, rFP, r2, lsl #2         @ r2<- &fp[A]
471    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[B]
472    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
473    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
474    stmia   r2, {r0-r1}                 @ fp[A]<- r0/r1
475    GOTO_OPCODE(ip)                     @ jump to next instruction
476
477/* ------------------------------ */
478    .balign 64
479.L_OP_MOVE_WIDE_FROM16: /* 0x05 */
480/* File: armv5te/OP_MOVE_WIDE_FROM16.S */
481    /* move-wide/from16 vAA, vBBBB */
482    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
483    FETCH(r3, 1)                        @ r3<- BBBB
484    mov     r2, rINST, lsr #8           @ r2<- AA
485    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BBBB]
486    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
487    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[BBBB]
488    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
489    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
490    stmia   r2, {r0-r1}                 @ fp[AA]<- r0/r1
491    GOTO_OPCODE(ip)                     @ jump to next instruction
492
493/* ------------------------------ */
494    .balign 64
495.L_OP_MOVE_WIDE_16: /* 0x06 */
496/* File: armv5te/OP_MOVE_WIDE_16.S */
497    /* move-wide/16 vAAAA, vBBBB */
498    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
499    FETCH(r3, 2)                        @ r3<- BBBB
500    FETCH(r2, 1)                        @ r2<- AAAA
501    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BBBB]
502    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AAAA]
503    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[BBBB]
504    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
505    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
506    stmia   r2, {r0-r1}                 @ fp[AAAA]<- r0/r1
507    GOTO_OPCODE(ip)                     @ jump to next instruction
508
509/* ------------------------------ */
510    .balign 64
511.L_OP_MOVE_OBJECT: /* 0x07 */
512/* File: armv5te/OP_MOVE_OBJECT.S */
513/* File: armv5te/OP_MOVE.S */
514    /* for move, move-object, long-to-int */
515    /* op vA, vB */
516    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
517    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
518    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
519    GET_VREG(r2, r1)                    @ r2<- fp[B]
520    and     r0, r0, #15
521    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
522    SET_VREG(r2, r0)                    @ fp[A]<- r2
523    GOTO_OPCODE(ip)                     @ execute next instruction
524
525
526/* ------------------------------ */
527    .balign 64
528.L_OP_MOVE_OBJECT_FROM16: /* 0x08 */
529/* File: armv5te/OP_MOVE_OBJECT_FROM16.S */
530/* File: armv5te/OP_MOVE_FROM16.S */
531    /* for: move/from16, move-object/from16 */
532    /* op vAA, vBBBB */
533    FETCH(r1, 1)                        @ r1<- BBBB
534    mov     r0, rINST, lsr #8           @ r0<- AA
535    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
536    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
537    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
538    SET_VREG(r2, r0)                    @ fp[AA]<- r2
539    GOTO_OPCODE(ip)                     @ jump to next instruction
540
541
542/* ------------------------------ */
543    .balign 64
544.L_OP_MOVE_OBJECT_16: /* 0x09 */
545/* File: armv5te/OP_MOVE_OBJECT_16.S */
546/* File: armv5te/OP_MOVE_16.S */
547    /* for: move/16, move-object/16 */
548    /* op vAAAA, vBBBB */
549    FETCH(r1, 2)                        @ r1<- BBBB
550    FETCH(r0, 1)                        @ r0<- AAAA
551    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
552    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
553    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
554    SET_VREG(r2, r0)                    @ fp[AAAA]<- r2
555    GOTO_OPCODE(ip)                     @ jump to next instruction
556
557
558/* ------------------------------ */
559    .balign 64
560.L_OP_MOVE_RESULT: /* 0x0a */
561/* File: armv5te/OP_MOVE_RESULT.S */
562    /* for: move-result, move-result-object */
563    /* op vAA */
564    mov     r2, rINST, lsr #8           @ r2<- AA
565    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
566    ldr     r0, [rSELF, #offThread_retval]    @ r0<- self->retval.i
567    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
568    SET_VREG(r0, r2)                    @ fp[AA]<- r0
569    GOTO_OPCODE(ip)                     @ jump to next instruction
570
571/* ------------------------------ */
572    .balign 64
573.L_OP_MOVE_RESULT_WIDE: /* 0x0b */
574/* File: armv5te/OP_MOVE_RESULT_WIDE.S */
575    /* move-result-wide vAA */
576    mov     r2, rINST, lsr #8           @ r2<- AA
577    add     r3, rSELF, #offThread_retval  @ r3<- &self->retval
578    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
579    ldmia   r3, {r0-r1}                 @ r0/r1<- retval.j
580    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
581    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
582    stmia   r2, {r0-r1}                 @ fp[AA]<- r0/r1
583    GOTO_OPCODE(ip)                     @ jump to next instruction
584
585/* ------------------------------ */
586    .balign 64
587.L_OP_MOVE_RESULT_OBJECT: /* 0x0c */
588/* File: armv5te/OP_MOVE_RESULT_OBJECT.S */
589/* File: armv5te/OP_MOVE_RESULT.S */
590    /* for: move-result, move-result-object */
591    /* op vAA */
592    mov     r2, rINST, lsr #8           @ r2<- AA
593    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
594    ldr     r0, [rSELF, #offThread_retval]    @ r0<- self->retval.i
595    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
596    SET_VREG(r0, r2)                    @ fp[AA]<- r0
597    GOTO_OPCODE(ip)                     @ jump to next instruction
598
599
600/* ------------------------------ */
601    .balign 64
602.L_OP_MOVE_EXCEPTION: /* 0x0d */
603/* File: armv5te/OP_MOVE_EXCEPTION.S */
604    /* move-exception vAA */
605    mov     r2, rINST, lsr #8           @ r2<- AA
606    ldr     r3, [rSELF, #offThread_exception]  @ r3<- dvmGetException bypass
607    mov     r1, #0                      @ r1<- 0
608    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
609    SET_VREG(r3, r2)                    @ fp[AA]<- exception obj
610    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
611    str     r1, [rSELF, #offThread_exception]  @ dvmClearException bypass
612    GOTO_OPCODE(ip)                     @ jump to next instruction
613
614/* ------------------------------ */
615    .balign 64
616.L_OP_RETURN_VOID: /* 0x0e */
617/* File: armv5te/OP_RETURN_VOID.S */
618    b       common_returnFromMethod
619
620/* ------------------------------ */
621    .balign 64
622.L_OP_RETURN: /* 0x0f */
623/* File: armv5te/OP_RETURN.S */
624    /*
625     * Return a 32-bit value.  Copies the return value into the "thread"
626     * structure, then jumps to the return handler.
627     *
628     * for: return, return-object
629     */
630    /* op vAA */
631    mov     r2, rINST, lsr #8           @ r2<- AA
632    GET_VREG(r0, r2)                    @ r0<- vAA
633    str     r0, [rSELF, #offThread_retval] @ retval.i <- vAA
634    b       common_returnFromMethod
635
636/* ------------------------------ */
637    .balign 64
638.L_OP_RETURN_WIDE: /* 0x10 */
639/* File: armv5te/OP_RETURN_WIDE.S */
640    /*
641     * Return a 64-bit value.  Copies the return value into the "thread"
642     * structure, then jumps to the return handler.
643     */
644    /* return-wide vAA */
645    mov     r2, rINST, lsr #8           @ r2<- AA
646    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
647    add     r3, rSELF, #offThread_retval  @ r3<- &self->retval
648    ldmia   r2, {r0-r1}                 @ r0/r1 <- vAA/vAA+1
649    stmia   r3, {r0-r1}                 @ retval<- r0/r1
650    b       common_returnFromMethod
651
652/* ------------------------------ */
653    .balign 64
654.L_OP_RETURN_OBJECT: /* 0x11 */
655/* File: armv5te/OP_RETURN_OBJECT.S */
656/* File: armv5te/OP_RETURN.S */
657    /*
658     * Return a 32-bit value.  Copies the return value into the "thread"
659     * structure, then jumps to the return handler.
660     *
661     * for: return, return-object
662     */
663    /* op vAA */
664    mov     r2, rINST, lsr #8           @ r2<- AA
665    GET_VREG(r0, r2)                    @ r0<- vAA
666    str     r0, [rSELF, #offThread_retval] @ retval.i <- vAA
667    b       common_returnFromMethod
668
669
670/* ------------------------------ */
671    .balign 64
672.L_OP_CONST_4: /* 0x12 */
673/* File: armv5te/OP_CONST_4.S */
674    /* const/4 vA, #+B */
675    mov     r1, rINST, lsl #16          @ r1<- Bxxx0000
676    mov     r0, rINST, lsr #8           @ r0<- A+
677    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
678    mov     r1, r1, asr #28             @ r1<- sssssssB (sign-extended)
679    and     r0, r0, #15
680    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
681    SET_VREG(r1, r0)                    @ fp[A]<- r1
682    GOTO_OPCODE(ip)                     @ execute next instruction
683
684/* ------------------------------ */
685    .balign 64
686.L_OP_CONST_16: /* 0x13 */
687/* File: armv5te/OP_CONST_16.S */
688    /* const/16 vAA, #+BBBB */
689    FETCH_S(r0, 1)                      @ r0<- ssssBBBB (sign-extended)
690    mov     r3, rINST, lsr #8           @ r3<- AA
691    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
692    SET_VREG(r0, r3)                    @ vAA<- r0
693    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
694    GOTO_OPCODE(ip)                     @ jump to next instruction
695
696/* ------------------------------ */
697    .balign 64
698.L_OP_CONST: /* 0x14 */
699/* File: armv5te/OP_CONST.S */
700    /* const vAA, #+BBBBbbbb */
701    mov     r3, rINST, lsr #8           @ r3<- AA
702    FETCH(r0, 1)                        @ r0<- bbbb (low)
703    FETCH(r1, 2)                        @ r1<- BBBB (high)
704    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
705    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
706    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
707    SET_VREG(r0, r3)                    @ vAA<- r0
708    GOTO_OPCODE(ip)                     @ jump to next instruction
709
710/* ------------------------------ */
711    .balign 64
712.L_OP_CONST_HIGH16: /* 0x15 */
713/* File: armv5te/OP_CONST_HIGH16.S */
714    /* const/high16 vAA, #+BBBB0000 */
715    FETCH(r0, 1)                        @ r0<- 0000BBBB (zero-extended)
716    mov     r3, rINST, lsr #8           @ r3<- AA
717    mov     r0, r0, lsl #16             @ r0<- BBBB0000
718    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
719    SET_VREG(r0, r3)                    @ vAA<- r0
720    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
721    GOTO_OPCODE(ip)                     @ jump to next instruction
722
723/* ------------------------------ */
724    .balign 64
725.L_OP_CONST_WIDE_16: /* 0x16 */
726/* File: armv5te/OP_CONST_WIDE_16.S */
727    /* const-wide/16 vAA, #+BBBB */
728    FETCH_S(r0, 1)                      @ r0<- ssssBBBB (sign-extended)
729    mov     r3, rINST, lsr #8           @ r3<- AA
730    mov     r1, r0, asr #31             @ r1<- ssssssss
731    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
732    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
733    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
734    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
735    GOTO_OPCODE(ip)                     @ jump to next instruction
736
737/* ------------------------------ */
738    .balign 64
739.L_OP_CONST_WIDE_32: /* 0x17 */
740/* File: armv5te/OP_CONST_WIDE_32.S */
741    /* const-wide/32 vAA, #+BBBBbbbb */
742    FETCH(r0, 1)                        @ r0<- 0000bbbb (low)
743    mov     r3, rINST, lsr #8           @ r3<- AA
744    FETCH_S(r2, 2)                      @ r2<- ssssBBBB (high)
745    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
746    orr     r0, r0, r2, lsl #16         @ r0<- BBBBbbbb
747    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
748    mov     r1, r0, asr #31             @ r1<- ssssssss
749    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
750    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
751    GOTO_OPCODE(ip)                     @ jump to next instruction
752
753/* ------------------------------ */
754    .balign 64
755.L_OP_CONST_WIDE: /* 0x18 */
756/* File: armv5te/OP_CONST_WIDE.S */
757    /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
758    FETCH(r0, 1)                        @ r0<- bbbb (low)
759    FETCH(r1, 2)                        @ r1<- BBBB (low middle)
760    FETCH(r2, 3)                        @ r2<- hhhh (high middle)
761    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb (low word)
762    FETCH(r3, 4)                        @ r3<- HHHH (high)
763    mov     r9, rINST, lsr #8           @ r9<- AA
764    orr     r1, r2, r3, lsl #16         @ r1<- HHHHhhhh (high word)
765    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
766    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
767    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
768    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
769    GOTO_OPCODE(ip)                     @ jump to next instruction
770
771/* ------------------------------ */
772    .balign 64
773.L_OP_CONST_WIDE_HIGH16: /* 0x19 */
774/* File: armv5te/OP_CONST_WIDE_HIGH16.S */
775    /* const-wide/high16 vAA, #+BBBB000000000000 */
776    FETCH(r1, 1)                        @ r1<- 0000BBBB (zero-extended)
777    mov     r3, rINST, lsr #8           @ r3<- AA
778    mov     r0, #0                      @ r0<- 00000000
779    mov     r1, r1, lsl #16             @ r1<- BBBB0000
780    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
781    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
782    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
783    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
784    GOTO_OPCODE(ip)                     @ jump to next instruction
785
786/* ------------------------------ */
787    .balign 64
788.L_OP_CONST_STRING: /* 0x1a */
789/* File: armv5te/OP_CONST_STRING.S */
790    /* const/string vAA, String@BBBB */
791    FETCH(r1, 1)                        @ r1<- BBBB
792    ldr     r2, [rSELF, #offThread_methodClassDex]  @ r2<- self->methodClassDex
793    mov     r9, rINST, lsr #8           @ r9<- AA
794    ldr     r2, [r2, #offDvmDex_pResStrings]   @ r2<- dvmDex->pResStrings
795    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResStrings[BBBB]
796    cmp     r0, #0                      @ not yet resolved?
797    beq     .LOP_CONST_STRING_resolve
798    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
799    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
800    SET_VREG(r0, r9)                    @ vAA<- r0
801    GOTO_OPCODE(ip)                     @ jump to next instruction
802
803/* ------------------------------ */
804    .balign 64
805.L_OP_CONST_STRING_JUMBO: /* 0x1b */
806/* File: armv5te/OP_CONST_STRING_JUMBO.S */
807    /* const/string vAA, String@BBBBBBBB */
808    FETCH(r0, 1)                        @ r0<- bbbb (low)
809    FETCH(r1, 2)                        @ r1<- BBBB (high)
810    ldr     r2, [rSELF, #offThread_methodClassDex]  @ r2<- self->methodClassDex
811    mov     r9, rINST, lsr #8           @ r9<- AA
812    ldr     r2, [r2, #offDvmDex_pResStrings]   @ r2<- dvmDex->pResStrings
813    orr     r1, r0, r1, lsl #16         @ r1<- BBBBbbbb
814    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResStrings[BBBB]
815    cmp     r0, #0
816    beq     .LOP_CONST_STRING_JUMBO_resolve
817    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
818    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
819    SET_VREG(r0, r9)                    @ vAA<- r0
820    GOTO_OPCODE(ip)                     @ jump to next instruction
821
822/* ------------------------------ */
823    .balign 64
824.L_OP_CONST_CLASS: /* 0x1c */
825/* File: armv5te/OP_CONST_CLASS.S */
826    /* const/class vAA, Class@BBBB */
827    FETCH(r1, 1)                        @ r1<- BBBB
828    ldr     r2, [rSELF, #offThread_methodClassDex]  @ r2<- self->methodClassDex
829    mov     r9, rINST, lsr #8           @ r9<- AA
830    ldr     r2, [r2, #offDvmDex_pResClasses]   @ r2<- dvmDex->pResClasses
831    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResClasses[BBBB]
832    cmp     r0, #0                      @ not yet resolved?
833    beq     .LOP_CONST_CLASS_resolve
834    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
835    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
836    SET_VREG(r0, r9)                    @ vAA<- r0
837    GOTO_OPCODE(ip)                     @ jump to next instruction
838
839/* ------------------------------ */
840    .balign 64
841.L_OP_MONITOR_ENTER: /* 0x1d */
842/* File: armv5te/OP_MONITOR_ENTER.S */
843    /*
844     * Synchronize on an object.
845     */
846    /* monitor-enter vAA */
847    mov     r2, rINST, lsr #8           @ r2<- AA
848    GET_VREG(r1, r2)                    @ r1<- vAA (object)
849    mov     r0, rSELF                   @ r0<- self
850    cmp     r1, #0                      @ null object?
851    EXPORT_PC()                         @ need for precise GC
852    beq     common_errNullObject        @ null object, throw an exception
853    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
854    bl      dvmLockObject               @ call(self, obj)
855    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
856    GOTO_OPCODE(ip)                     @ jump to next instruction
857
858/* ------------------------------ */
859    .balign 64
860.L_OP_MONITOR_EXIT: /* 0x1e */
861/* File: armv5te/OP_MONITOR_EXIT.S */
862    /*
863     * Unlock an object.
864     *
865     * Exceptions that occur when unlocking a monitor need to appear as
866     * if they happened at the following instruction.  See the Dalvik
867     * instruction spec.
868     */
869    /* monitor-exit vAA */
870    mov     r2, rINST, lsr #8           @ r2<- AA
871    EXPORT_PC()                         @ before fetch: export the PC
872    GET_VREG(r1, r2)                    @ r1<- vAA (object)
873    cmp     r1, #0                      @ null object?
874    beq     1f                          @ yes
875    mov     r0, rSELF                   @ r0<- self
876    bl      dvmUnlockObject             @ r0<- success for unlock(self, obj)
877    cmp     r0, #0                      @ failed?
878    FETCH_ADVANCE_INST(1)               @ before throw: advance rPC, load rINST
879    beq     common_exceptionThrown      @ yes, exception is pending
880    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
881    GOTO_OPCODE(ip)                     @ jump to next instruction
8821:
883    FETCH_ADVANCE_INST(1)               @ advance before throw
884    b      common_errNullObject
885
886/* ------------------------------ */
887    .balign 64
888.L_OP_CHECK_CAST: /* 0x1f */
889/* File: armv5te/OP_CHECK_CAST.S */
890    /*
891     * Check to see if a cast from one class to another is allowed.
892     */
893    /* check-cast vAA, class@BBBB */
894    mov     r3, rINST, lsr #8           @ r3<- AA
895    FETCH(r2, 1)                        @ r2<- BBBB
896    GET_VREG(r9, r3)                    @ r9<- object
897    ldr     r0, [rSELF, #offThread_methodClassDex]    @ r0<- pDvmDex
898    cmp     r9, #0                      @ is object null?
899    ldr     r0, [r0, #offDvmDex_pResClasses]    @ r0<- pDvmDex->pResClasses
900    beq     .LOP_CHECK_CAST_okay            @ null obj, cast always succeeds
901    ldr     r1, [r0, r2, lsl #2]        @ r1<- resolved class
902    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
903    cmp     r1, #0                      @ have we resolved this before?
904    beq     .LOP_CHECK_CAST_resolve         @ not resolved, do it now
905.LOP_CHECK_CAST_resolved:
906    cmp     r0, r1                      @ same class (trivial success)?
907    bne     .LOP_CHECK_CAST_fullcheck       @ no, do full check
908.LOP_CHECK_CAST_okay:
909    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
910    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
911    GOTO_OPCODE(ip)                     @ jump to next instruction
912
913/* ------------------------------ */
914    .balign 64
915.L_OP_INSTANCE_OF: /* 0x20 */
916/* File: armv5te/OP_INSTANCE_OF.S */
917    /*
918     * Check to see if an object reference is an instance of a class.
919     *
920     * Most common situation is a non-null object, being compared against
921     * an already-resolved class.
922     */
923    /* instance-of vA, vB, class@CCCC */
924    mov     r3, rINST, lsr #12          @ r3<- B
925    mov     r9, rINST, lsr #8           @ r9<- A+
926    GET_VREG(r0, r3)                    @ r0<- vB (object)
927    and     r9, r9, #15                 @ r9<- A
928    cmp     r0, #0                      @ is object null?
929    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- pDvmDex
930    beq     .LOP_INSTANCE_OF_store           @ null obj, not an instance, store r0
931    FETCH(r3, 1)                        @ r3<- CCCC
932    ldr     r2, [r2, #offDvmDex_pResClasses]    @ r2<- pDvmDex->pResClasses
933    ldr     r1, [r2, r3, lsl #2]        @ r1<- resolved class
934    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
935    cmp     r1, #0                      @ have we resolved this before?
936    beq     .LOP_INSTANCE_OF_resolve         @ not resolved, do it now
937.LOP_INSTANCE_OF_resolved: @ r0=obj->clazz, r1=resolved class
938    cmp     r0, r1                      @ same class (trivial success)?
939    beq     .LOP_INSTANCE_OF_trivial         @ yes, trivial finish
940    b       .LOP_INSTANCE_OF_fullcheck       @ no, do full check
941
942/* ------------------------------ */
943    .balign 64
944.L_OP_ARRAY_LENGTH: /* 0x21 */
945/* File: armv5te/OP_ARRAY_LENGTH.S */
946    /*
947     * Return the length of an array.
948     */
949    mov     r1, rINST, lsr #12          @ r1<- B
950    mov     r2, rINST, lsr #8           @ r2<- A+
951    GET_VREG(r0, r1)                    @ r0<- vB (object ref)
952    and     r2, r2, #15                 @ r2<- A
953    cmp     r0, #0                      @ is object null?
954    beq     common_errNullObject        @ yup, fail
955    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
956    ldr     r3, [r0, #offArrayObject_length]    @ r3<- array length
957    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
958    SET_VREG(r3, r2)                    @ vB<- length
959    GOTO_OPCODE(ip)                     @ jump to next instruction
960
961/* ------------------------------ */
962    .balign 64
963.L_OP_NEW_INSTANCE: /* 0x22 */
964/* File: armv5te/OP_NEW_INSTANCE.S */
965    /*
966     * Create a new instance of a class.
967     */
968    /* new-instance vAA, class@BBBB */
969    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
970    FETCH(r1, 1)                        @ r1<- BBBB
971    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
972    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
973    EXPORT_PC()                         @ req'd for init, resolve, alloc
974    cmp     r0, #0                      @ already resolved?
975    beq     .LOP_NEW_INSTANCE_resolve         @ no, resolve it now
976.LOP_NEW_INSTANCE_resolved:   @ r0=class
977    ldrb    r1, [r0, #offClassObject_status]    @ r1<- ClassStatus enum
978    cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
979    bne     .LOP_NEW_INSTANCE_needinit        @ no, init class now
980.LOP_NEW_INSTANCE_initialized: @ r0=class
981    mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
982    bl      dvmAllocObject              @ r0<- new object
983    b       .LOP_NEW_INSTANCE_finish          @ continue
984
985/* ------------------------------ */
986    .balign 64
987.L_OP_NEW_ARRAY: /* 0x23 */
988/* File: armv5te/OP_NEW_ARRAY.S */
989    /*
990     * Allocate an array of objects, specified with the array class
991     * and a count.
992     *
993     * The verifier guarantees that this is an array class, so we don't
994     * check for it here.
995     */
996    /* new-array vA, vB, class@CCCC */
997    mov     r0, rINST, lsr #12          @ r0<- B
998    FETCH(r2, 1)                        @ r2<- CCCC
999    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
1000    GET_VREG(r1, r0)                    @ r1<- vB (array length)
1001    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1002    cmp     r1, #0                      @ check length
1003    ldr     r0, [r3, r2, lsl #2]        @ r0<- resolved class
1004    bmi     common_errNegativeArraySize @ negative length, bail - len in r1
1005    cmp     r0, #0                      @ already resolved?
1006    EXPORT_PC()                         @ req'd for resolve, alloc
1007    bne     .LOP_NEW_ARRAY_finish          @ resolved, continue
1008    b       .LOP_NEW_ARRAY_resolve         @ do resolve now
1009
1010/* ------------------------------ */
1011    .balign 64
1012.L_OP_FILLED_NEW_ARRAY: /* 0x24 */
1013/* File: armv5te/OP_FILLED_NEW_ARRAY.S */
1014    /*
1015     * Create a new array with elements filled from registers.
1016     *
1017     * for: filled-new-array, filled-new-array/range
1018     */
1019    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1020    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1021    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
1022    FETCH(r1, 1)                        @ r1<- BBBB
1023    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1024    EXPORT_PC()                         @ need for resolve and alloc
1025    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
1026    mov     r10, rINST, lsr #8          @ r10<- AA or BA
1027    cmp     r0, #0                      @ already resolved?
1028    bne     .LOP_FILLED_NEW_ARRAY_continue        @ yes, continue on
10298:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
1030    mov     r2, #0                      @ r2<- false
1031    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
1032    bl      dvmResolveClass             @ r0<- call(clazz, ref)
1033    cmp     r0, #0                      @ got null?
1034    beq     common_exceptionThrown      @ yes, handle exception
1035    b       .LOP_FILLED_NEW_ARRAY_continue
1036
1037/* ------------------------------ */
1038    .balign 64
1039.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
1040/* File: armv5te/OP_FILLED_NEW_ARRAY_RANGE.S */
1041/* File: armv5te/OP_FILLED_NEW_ARRAY.S */
1042    /*
1043     * Create a new array with elements filled from registers.
1044     *
1045     * for: filled-new-array, filled-new-array/range
1046     */
1047    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1048    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1049    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
1050    FETCH(r1, 1)                        @ r1<- BBBB
1051    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1052    EXPORT_PC()                         @ need for resolve and alloc
1053    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
1054    mov     r10, rINST, lsr #8          @ r10<- AA or BA
1055    cmp     r0, #0                      @ already resolved?
1056    bne     .LOP_FILLED_NEW_ARRAY_RANGE_continue        @ yes, continue on
10578:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
1058    mov     r2, #0                      @ r2<- false
1059    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
1060    bl      dvmResolveClass             @ r0<- call(clazz, ref)
1061    cmp     r0, #0                      @ got null?
1062    beq     common_exceptionThrown      @ yes, handle exception
1063    b       .LOP_FILLED_NEW_ARRAY_RANGE_continue
1064
1065
1066/* ------------------------------ */
1067    .balign 64
1068.L_OP_FILL_ARRAY_DATA: /* 0x26 */
1069/* File: armv5te/OP_FILL_ARRAY_DATA.S */
1070    /* fill-array-data vAA, +BBBBBBBB */
1071    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1072    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1073    mov     r3, rINST, lsr #8           @ r3<- AA
1074    orr     r1, r0, r1, lsl #16         @ r1<- BBBBbbbb
1075    GET_VREG(r0, r3)                    @ r0<- vAA (array object)
1076    add     r1, rPC, r1, lsl #1         @ r1<- PC + BBBBbbbb*2 (array data off.)
1077    EXPORT_PC();
1078    bl      dvmInterpHandleFillArrayData@ fill the array with predefined data
1079    cmp     r0, #0                      @ 0 means an exception is thrown
1080    beq     common_exceptionThrown      @ has exception
1081    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
1082    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1083    GOTO_OPCODE(ip)                     @ jump to next instruction
1084
1085/* ------------------------------ */
1086    .balign 64
1087.L_OP_THROW: /* 0x27 */
1088/* File: armv5te/OP_THROW.S */
1089    /*
1090     * Throw an exception object in the current thread.
1091     */
1092    /* throw vAA */
1093    mov     r2, rINST, lsr #8           @ r2<- AA
1094    GET_VREG(r1, r2)                    @ r1<- vAA (exception object)
1095    EXPORT_PC()                         @ exception handler can throw
1096    cmp     r1, #0                      @ null object?
1097    beq     common_errNullObject        @ yes, throw an NPE instead
1098    @ bypass dvmSetException, just store it
1099    str     r1, [rSELF, #offThread_exception]  @ thread->exception<- obj
1100    b       common_exceptionThrown
1101
1102/* ------------------------------ */
1103    .balign 64
1104.L_OP_GOTO: /* 0x28 */
1105/* File: armv5te/OP_GOTO.S */
1106    /*
1107     * Unconditional branch, 8-bit offset.
1108     *
1109     * The branch distance is a signed code-unit offset, which we need to
1110     * double to get a byte offset.
1111     */
1112    /* goto +AA */
1113    mov     r0, rINST, lsl #16          @ r0<- AAxx0000
1114    movs    r9, r0, asr #24             @ r9<- ssssssAA (sign-extended)
1115    mov     r9, r9, lsl #1              @ r9<- byte offset
1116    bmi     common_backwardBranch       @ backward branch, do periodic checks
1117#if defined(WITH_JIT)
1118    GET_JIT_PROF_TABLE(r0)
1119    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1120    cmp     r0,#0
1121    bne     common_updateProfile
1122    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1123    GOTO_OPCODE(ip)                     @ jump to next instruction
1124#else
1125    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1126    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1127    GOTO_OPCODE(ip)                     @ jump to next instruction
1128#endif
1129
1130/* ------------------------------ */
1131    .balign 64
1132.L_OP_GOTO_16: /* 0x29 */
1133/* File: armv5te/OP_GOTO_16.S */
1134    /*
1135     * Unconditional branch, 16-bit offset.
1136     *
1137     * The branch distance is a signed code-unit offset, which we need to
1138     * double to get a byte offset.
1139     */
1140    /* goto/16 +AAAA */
1141    FETCH_S(r0, 1)                      @ r0<- ssssAAAA (sign-extended)
1142    movs    r9, r0, asl #1              @ r9<- byte offset, check sign
1143    bmi     common_backwardBranch       @ backward branch, do periodic checks
1144#if defined(WITH_JIT)
1145    GET_JIT_PROF_TABLE(r0)
1146    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1147    cmp     r0,#0
1148    bne     common_updateProfile
1149    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1150    GOTO_OPCODE(ip)                     @ jump to next instruction
1151#else
1152    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1153    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1154    GOTO_OPCODE(ip)                     @ jump to next instruction
1155#endif
1156
1157/* ------------------------------ */
1158    .balign 64
1159.L_OP_GOTO_32: /* 0x2a */
1160/* File: armv5te/OP_GOTO_32.S */
1161    /*
1162     * Unconditional branch, 32-bit offset.
1163     *
1164     * The branch distance is a signed code-unit offset, which we need to
1165     * double to get a byte offset.
1166     *
1167     * Unlike most opcodes, this one is allowed to branch to itself, so
1168     * our "backward branch" test must be "<=0" instead of "<0".  The ORRS
1169     * instruction doesn't affect the V flag, so we need to clear it
1170     * explicitly.
1171     */
1172    /* goto/32 +AAAAAAAA */
1173    FETCH(r0, 1)                        @ r0<- aaaa (lo)
1174    FETCH(r1, 2)                        @ r1<- AAAA (hi)
1175    cmp     ip, ip                      @ (clear V flag during stall)
1176    orrs    r0, r0, r1, lsl #16         @ r0<- AAAAaaaa, check sign
1177    mov     r9, r0, asl #1              @ r9<- byte offset
1178    ble     common_backwardBranch       @ backward branch, do periodic checks
1179#if defined(WITH_JIT)
1180    GET_JIT_PROF_TABLE(r0)
1181    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1182    cmp     r0,#0
1183    bne     common_updateProfile
1184    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1185    GOTO_OPCODE(ip)                     @ jump to next instruction
1186#else
1187    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1188    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1189    GOTO_OPCODE(ip)                     @ jump to next instruction
1190#endif
1191
1192/* ------------------------------ */
1193    .balign 64
1194.L_OP_PACKED_SWITCH: /* 0x2b */
1195/* File: armv5te/OP_PACKED_SWITCH.S */
1196    /*
1197     * Handle a packed-switch or sparse-switch instruction.  In both cases
1198     * we decode it and hand it off to a helper function.
1199     *
1200     * We don't really expect backward branches in a switch statement, but
1201     * they're perfectly legal, so we check for them here.
1202     *
1203     * for: packed-switch, sparse-switch
1204     */
1205    /* op vAA, +BBBB */
1206    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1207    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1208    mov     r3, rINST, lsr #8           @ r3<- AA
1209    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
1210    GET_VREG(r1, r3)                    @ r1<- vAA
1211    add     r0, rPC, r0, lsl #1         @ r0<- PC + BBBBbbbb*2
1212    bl      dvmInterpHandlePackedSwitch                       @ r0<- code-unit branch offset
1213    movs    r9, r0, asl #1              @ r9<- branch byte offset, check sign
1214    bmi     common_backwardBranch       @ backward branch, do periodic checks
1215    beq     common_backwardBranch       @ (want to use BLE but V is unknown)
1216#if defined(WITH_JIT)
1217    GET_JIT_PROF_TABLE(r0)
1218    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1219    cmp     r0,#0
1220    bne     common_updateProfile
1221    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1222    GOTO_OPCODE(ip)                     @ jump to next instruction
1223#else
1224    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1225    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1226    GOTO_OPCODE(ip)                     @ jump to next instruction
1227#endif
1228
1229/* ------------------------------ */
1230    .balign 64
1231.L_OP_SPARSE_SWITCH: /* 0x2c */
1232/* File: armv5te/OP_SPARSE_SWITCH.S */
1233/* File: armv5te/OP_PACKED_SWITCH.S */
1234    /*
1235     * Handle a packed-switch or sparse-switch instruction.  In both cases
1236     * we decode it and hand it off to a helper function.
1237     *
1238     * We don't really expect backward branches in a switch statement, but
1239     * they're perfectly legal, so we check for them here.
1240     *
1241     * for: packed-switch, sparse-switch
1242     */
1243    /* op vAA, +BBBB */
1244    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1245    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1246    mov     r3, rINST, lsr #8           @ r3<- AA
1247    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
1248    GET_VREG(r1, r3)                    @ r1<- vAA
1249    add     r0, rPC, r0, lsl #1         @ r0<- PC + BBBBbbbb*2
1250    bl      dvmInterpHandleSparseSwitch                       @ r0<- code-unit branch offset
1251    movs    r9, r0, asl #1              @ r9<- branch byte offset, check sign
1252    bmi     common_backwardBranch       @ backward branch, do periodic checks
1253    beq     common_backwardBranch       @ (want to use BLE but V is unknown)
1254#if defined(WITH_JIT)
1255    GET_JIT_PROF_TABLE(r0)
1256    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1257    cmp     r0,#0
1258    bne     common_updateProfile
1259    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1260    GOTO_OPCODE(ip)                     @ jump to next instruction
1261#else
1262    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1263    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1264    GOTO_OPCODE(ip)                     @ jump to next instruction
1265#endif
1266
1267
1268/* ------------------------------ */
1269    .balign 64
1270.L_OP_CMPL_FLOAT: /* 0x2d */
1271/* File: arm-vfp/OP_CMPL_FLOAT.S */
1272    /*
1273     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1274     * destination register based on the results of the comparison.
1275     *
1276     * int compare(x, y) {
1277     *     if (x == y) {
1278     *         return 0;
1279     *     } else if (x > y) {
1280     *         return 1;
1281     *     } else if (x < y) {
1282     *         return -1;
1283     *     } else {
1284     *         return -1;
1285     *     }
1286     * }
1287     */
1288    /* op vAA, vBB, vCC */
1289    FETCH(r0, 1)                        @ r0<- CCBB
1290    mov     r9, rINST, lsr #8           @ r9<- AA
1291    and     r2, r0, #255                @ r2<- BB
1292    mov     r3, r0, lsr #8              @ r3<- CC
1293    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1294    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1295    flds    s0, [r2]                    @ s0<- vBB
1296    flds    s1, [r3]                    @ s1<- vCC
1297    fcmpes  s0, s1                      @ compare (vBB, vCC)
1298    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1299    mvn     r0, #0                      @ r0<- -1 (default)
1300    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1301    fmstat                              @ export status flags
1302    movgt   r0, #1                      @ (greater than) r1<- 1
1303    moveq   r0, #0                      @ (equal) r1<- 0
1304    b       .LOP_CMPL_FLOAT_finish          @ argh
1305
1306
1307/* ------------------------------ */
1308    .balign 64
1309.L_OP_CMPG_FLOAT: /* 0x2e */
1310/* File: arm-vfp/OP_CMPG_FLOAT.S */
1311    /*
1312     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1313     * destination register based on the results of the comparison.
1314     *
1315     * int compare(x, y) {
1316     *     if (x == y) {
1317     *         return 0;
1318     *     } else if (x < y) {
1319     *         return -1;
1320     *     } else if (x > y) {
1321     *         return 1;
1322     *     } else {
1323     *         return 1;
1324     *     }
1325     * }
1326     */
1327    /* op vAA, vBB, vCC */
1328    FETCH(r0, 1)                        @ r0<- CCBB
1329    mov     r9, rINST, lsr #8           @ r9<- AA
1330    and     r2, r0, #255                @ r2<- BB
1331    mov     r3, r0, lsr #8              @ r3<- CC
1332    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1333    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1334    flds    s0, [r2]                    @ s0<- vBB
1335    flds    s1, [r3]                    @ s1<- vCC
1336    fcmpes  s0, s1                      @ compare (vBB, vCC)
1337    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1338    mov     r0, #1                      @ r0<- 1 (default)
1339    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1340    fmstat                              @ export status flags
1341    mvnmi   r0, #0                      @ (less than) r1<- -1
1342    moveq   r0, #0                      @ (equal) r1<- 0
1343    b       .LOP_CMPG_FLOAT_finish          @ argh
1344
1345
1346/* ------------------------------ */
1347    .balign 64
1348.L_OP_CMPL_DOUBLE: /* 0x2f */
1349/* File: arm-vfp/OP_CMPL_DOUBLE.S */
1350    /*
1351     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1352     * destination register based on the results of the comparison.
1353     *
1354     * int compare(x, y) {
1355     *     if (x == y) {
1356     *         return 0;
1357     *     } else if (x > y) {
1358     *         return 1;
1359     *     } else if (x < y) {
1360     *         return -1;
1361     *     } else {
1362     *         return -1;
1363     *     }
1364     * }
1365     */
1366    /* op vAA, vBB, vCC */
1367    FETCH(r0, 1)                        @ r0<- CCBB
1368    mov     r9, rINST, lsr #8           @ r9<- AA
1369    and     r2, r0, #255                @ r2<- BB
1370    mov     r3, r0, lsr #8              @ r3<- CC
1371    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1372    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1373    fldd    d0, [r2]                    @ d0<- vBB
1374    fldd    d1, [r3]                    @ d1<- vCC
1375    fcmped  d0, d1                      @ compare (vBB, vCC)
1376    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1377    mvn     r0, #0                      @ r0<- -1 (default)
1378    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1379    fmstat                              @ export status flags
1380    movgt   r0, #1                      @ (greater than) r1<- 1
1381    moveq   r0, #0                      @ (equal) r1<- 0
1382    b       .LOP_CMPL_DOUBLE_finish          @ argh
1383
1384
1385/* ------------------------------ */
1386    .balign 64
1387.L_OP_CMPG_DOUBLE: /* 0x30 */
1388/* File: arm-vfp/OP_CMPG_DOUBLE.S */
1389    /*
1390     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1391     * destination register based on the results of the comparison.
1392     *
1393     * int compare(x, y) {
1394     *     if (x == y) {
1395     *         return 0;
1396     *     } else if (x < y) {
1397     *         return -1;
1398     *     } else if (x > y) {
1399     *         return 1;
1400     *     } else {
1401     *         return 1;
1402     *     }
1403     * }
1404     */
1405    /* op vAA, vBB, vCC */
1406    FETCH(r0, 1)                        @ r0<- CCBB
1407    mov     r9, rINST, lsr #8           @ r9<- AA
1408    and     r2, r0, #255                @ r2<- BB
1409    mov     r3, r0, lsr #8              @ r3<- CC
1410    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1411    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1412    fldd    d0, [r2]                    @ d0<- vBB
1413    fldd    d1, [r3]                    @ d1<- vCC
1414    fcmped  d0, d1                      @ compare (vBB, vCC)
1415    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1416    mov     r0, #1                      @ r0<- 1 (default)
1417    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1418    fmstat                              @ export status flags
1419    mvnmi   r0, #0                      @ (less than) r1<- -1
1420    moveq   r0, #0                      @ (equal) r1<- 0
1421    b       .LOP_CMPG_DOUBLE_finish          @ argh
1422
1423
1424/* ------------------------------ */
1425    .balign 64
1426.L_OP_CMP_LONG: /* 0x31 */
1427/* File: armv5te/OP_CMP_LONG.S */
1428    /*
1429     * Compare two 64-bit values.  Puts 0, 1, or -1 into the destination
1430     * register based on the results of the comparison.
1431     *
1432     * We load the full values with LDM, but in practice many values could
1433     * be resolved by only looking at the high word.  This could be made
1434     * faster or slower by splitting the LDM into a pair of LDRs.
1435     *
1436     * If we just wanted to set condition flags, we could do this:
1437     *  subs    ip, r0, r2
1438     *  sbcs    ip, r1, r3
1439     *  subeqs  ip, r0, r2
1440     * Leaving { <0, 0, >0 } in ip.  However, we have to set it to a specific
1441     * integer value, which we can do with 2 conditional mov/mvn instructions
1442     * (set 1, set -1; if they're equal we already have 0 in ip), giving
1443     * us a constant 5-cycle path plus a branch at the end to the
1444     * instruction epilogue code.  The multi-compare approach below needs
1445     * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch
1446     * in the worst case (the 64-bit values are equal).
1447     */
1448    /* cmp-long vAA, vBB, vCC */
1449    FETCH(r0, 1)                        @ r0<- CCBB
1450    mov     r9, rINST, lsr #8           @ r9<- AA
1451    and     r2, r0, #255                @ r2<- BB
1452    mov     r3, r0, lsr #8              @ r3<- CC
1453    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
1454    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
1455    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
1456    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
1457    cmp     r1, r3                      @ compare (vBB+1, vCC+1)
1458    blt     .LOP_CMP_LONG_less            @ signed compare on high part
1459    bgt     .LOP_CMP_LONG_greater
1460    subs    r1, r0, r2                  @ r1<- r0 - r2
1461    bhi     .LOP_CMP_LONG_greater         @ unsigned compare on low part
1462    bne     .LOP_CMP_LONG_less
1463    b       .LOP_CMP_LONG_finish          @ equal; r1 already holds 0
1464
1465/* ------------------------------ */
1466    .balign 64
1467.L_OP_IF_EQ: /* 0x32 */
1468/* File: armv5te/OP_IF_EQ.S */
1469/* File: armv5te/bincmp.S */
1470    /*
1471     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1472     * fragment that specifies the *reverse* comparison to perform, e.g.
1473     * for "if-le" you would use "gt".
1474     *
1475     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1476     */
1477    /* if-cmp vA, vB, +CCCC */
1478    mov     r0, rINST, lsr #8           @ r0<- A+
1479    mov     r1, rINST, lsr #12          @ r1<- B
1480    and     r0, r0, #15
1481    GET_VREG(r3, r1)                    @ r3<- vB
1482    GET_VREG(r2, r0)                    @ r2<- vA
1483    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1484    cmp     r2, r3                      @ compare (vA, vB)
1485    bne  1f                      @ branch to 1 if comparison failed
1486    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1487    movs    r9, r9, asl #1              @ convert to bytes, check sign
1488    bmi     common_backwardBranch       @ yes, do periodic checks
14891:
1490#if defined(WITH_JIT)
1491    GET_JIT_PROF_TABLE(r0)
1492    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1493    b        common_testUpdateProfile
1494#else
1495    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1496    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1497    GOTO_OPCODE(ip)                     @ jump to next instruction
1498#endif
1499
1500
1501/* ------------------------------ */
1502    .balign 64
1503.L_OP_IF_NE: /* 0x33 */
1504/* File: armv5te/OP_IF_NE.S */
1505/* File: armv5te/bincmp.S */
1506    /*
1507     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1508     * fragment that specifies the *reverse* comparison to perform, e.g.
1509     * for "if-le" you would use "gt".
1510     *
1511     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1512     */
1513    /* if-cmp vA, vB, +CCCC */
1514    mov     r0, rINST, lsr #8           @ r0<- A+
1515    mov     r1, rINST, lsr #12          @ r1<- B
1516    and     r0, r0, #15
1517    GET_VREG(r3, r1)                    @ r3<- vB
1518    GET_VREG(r2, r0)                    @ r2<- vA
1519    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1520    cmp     r2, r3                      @ compare (vA, vB)
1521    beq  1f                      @ branch to 1 if comparison failed
1522    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1523    movs    r9, r9, asl #1              @ convert to bytes, check sign
1524    bmi     common_backwardBranch       @ yes, do periodic checks
15251:
1526#if defined(WITH_JIT)
1527    GET_JIT_PROF_TABLE(r0)
1528    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1529    b        common_testUpdateProfile
1530#else
1531    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1532    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1533    GOTO_OPCODE(ip)                     @ jump to next instruction
1534#endif
1535
1536
1537/* ------------------------------ */
1538    .balign 64
1539.L_OP_IF_LT: /* 0x34 */
1540/* File: armv5te/OP_IF_LT.S */
1541/* File: armv5te/bincmp.S */
1542    /*
1543     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1544     * fragment that specifies the *reverse* comparison to perform, e.g.
1545     * for "if-le" you would use "gt".
1546     *
1547     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1548     */
1549    /* if-cmp vA, vB, +CCCC */
1550    mov     r0, rINST, lsr #8           @ r0<- A+
1551    mov     r1, rINST, lsr #12          @ r1<- B
1552    and     r0, r0, #15
1553    GET_VREG(r3, r1)                    @ r3<- vB
1554    GET_VREG(r2, r0)                    @ r2<- vA
1555    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1556    cmp     r2, r3                      @ compare (vA, vB)
1557    bge  1f                      @ branch to 1 if comparison failed
1558    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1559    movs    r9, r9, asl #1              @ convert to bytes, check sign
1560    bmi     common_backwardBranch       @ yes, do periodic checks
15611:
1562#if defined(WITH_JIT)
1563    GET_JIT_PROF_TABLE(r0)
1564    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1565    b        common_testUpdateProfile
1566#else
1567    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1568    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1569    GOTO_OPCODE(ip)                     @ jump to next instruction
1570#endif
1571
1572
1573/* ------------------------------ */
1574    .balign 64
1575.L_OP_IF_GE: /* 0x35 */
1576/* File: armv5te/OP_IF_GE.S */
1577/* File: armv5te/bincmp.S */
1578    /*
1579     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1580     * fragment that specifies the *reverse* comparison to perform, e.g.
1581     * for "if-le" you would use "gt".
1582     *
1583     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1584     */
1585    /* if-cmp vA, vB, +CCCC */
1586    mov     r0, rINST, lsr #8           @ r0<- A+
1587    mov     r1, rINST, lsr #12          @ r1<- B
1588    and     r0, r0, #15
1589    GET_VREG(r3, r1)                    @ r3<- vB
1590    GET_VREG(r2, r0)                    @ r2<- vA
1591    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1592    cmp     r2, r3                      @ compare (vA, vB)
1593    blt  1f                      @ branch to 1 if comparison failed
1594    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1595    movs    r9, r9, asl #1              @ convert to bytes, check sign
1596    bmi     common_backwardBranch       @ yes, do periodic checks
15971:
1598#if defined(WITH_JIT)
1599    GET_JIT_PROF_TABLE(r0)
1600    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1601    b        common_testUpdateProfile
1602#else
1603    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1604    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1605    GOTO_OPCODE(ip)                     @ jump to next instruction
1606#endif
1607
1608
1609/* ------------------------------ */
1610    .balign 64
1611.L_OP_IF_GT: /* 0x36 */
1612/* File: armv5te/OP_IF_GT.S */
1613/* File: armv5te/bincmp.S */
1614    /*
1615     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1616     * fragment that specifies the *reverse* comparison to perform, e.g.
1617     * for "if-le" you would use "gt".
1618     *
1619     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1620     */
1621    /* if-cmp vA, vB, +CCCC */
1622    mov     r0, rINST, lsr #8           @ r0<- A+
1623    mov     r1, rINST, lsr #12          @ r1<- B
1624    and     r0, r0, #15
1625    GET_VREG(r3, r1)                    @ r3<- vB
1626    GET_VREG(r2, r0)                    @ r2<- vA
1627    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1628    cmp     r2, r3                      @ compare (vA, vB)
1629    ble  1f                      @ branch to 1 if comparison failed
1630    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1631    movs    r9, r9, asl #1              @ convert to bytes, check sign
1632    bmi     common_backwardBranch       @ yes, do periodic checks
16331:
1634#if defined(WITH_JIT)
1635    GET_JIT_PROF_TABLE(r0)
1636    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1637    b        common_testUpdateProfile
1638#else
1639    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1640    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1641    GOTO_OPCODE(ip)                     @ jump to next instruction
1642#endif
1643
1644
1645/* ------------------------------ */
1646    .balign 64
1647.L_OP_IF_LE: /* 0x37 */
1648/* File: armv5te/OP_IF_LE.S */
1649/* File: armv5te/bincmp.S */
1650    /*
1651     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1652     * fragment that specifies the *reverse* comparison to perform, e.g.
1653     * for "if-le" you would use "gt".
1654     *
1655     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1656     */
1657    /* if-cmp vA, vB, +CCCC */
1658    mov     r0, rINST, lsr #8           @ r0<- A+
1659    mov     r1, rINST, lsr #12          @ r1<- B
1660    and     r0, r0, #15
1661    GET_VREG(r3, r1)                    @ r3<- vB
1662    GET_VREG(r2, r0)                    @ r2<- vA
1663    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1664    cmp     r2, r3                      @ compare (vA, vB)
1665    bgt  1f                      @ branch to 1 if comparison failed
1666    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1667    movs    r9, r9, asl #1              @ convert to bytes, check sign
1668    bmi     common_backwardBranch       @ yes, do periodic checks
16691:
1670#if defined(WITH_JIT)
1671    GET_JIT_PROF_TABLE(r0)
1672    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1673    b        common_testUpdateProfile
1674#else
1675    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1676    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1677    GOTO_OPCODE(ip)                     @ jump to next instruction
1678#endif
1679
1680
1681/* ------------------------------ */
1682    .balign 64
1683.L_OP_IF_EQZ: /* 0x38 */
1684/* File: armv5te/OP_IF_EQZ.S */
1685/* File: armv5te/zcmp.S */
1686    /*
1687     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1688     * fragment that specifies the *reverse* comparison to perform, e.g.
1689     * for "if-le" you would use "gt".
1690     *
1691     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1692     */
1693    /* if-cmp vAA, +BBBB */
1694    mov     r0, rINST, lsr #8           @ r0<- AA
1695    GET_VREG(r2, r0)                    @ r2<- vAA
1696    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1697    cmp     r2, #0                      @ compare (vA, 0)
1698    bne  1f                      @ branch to 1 if comparison failed
1699    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1700    movs    r9, r9, asl #1              @ convert to bytes, check sign
1701    bmi     common_backwardBranch       @ backward branch, do periodic checks
17021:
1703#if defined(WITH_JIT)
1704    GET_JIT_PROF_TABLE(r0)
1705    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1706    cmp     r0,#0
1707    bne     common_updateProfile
1708    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1709    GOTO_OPCODE(ip)                     @ jump to next instruction
1710#else
1711    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1712    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1713    GOTO_OPCODE(ip)                     @ jump to next instruction
1714#endif
1715
1716
1717/* ------------------------------ */
1718    .balign 64
1719.L_OP_IF_NEZ: /* 0x39 */
1720/* File: armv5te/OP_IF_NEZ.S */
1721/* File: armv5te/zcmp.S */
1722    /*
1723     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1724     * fragment that specifies the *reverse* comparison to perform, e.g.
1725     * for "if-le" you would use "gt".
1726     *
1727     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1728     */
1729    /* if-cmp vAA, +BBBB */
1730    mov     r0, rINST, lsr #8           @ r0<- AA
1731    GET_VREG(r2, r0)                    @ r2<- vAA
1732    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1733    cmp     r2, #0                      @ compare (vA, 0)
1734    beq  1f                      @ branch to 1 if comparison failed
1735    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1736    movs    r9, r9, asl #1              @ convert to bytes, check sign
1737    bmi     common_backwardBranch       @ backward branch, do periodic checks
17381:
1739#if defined(WITH_JIT)
1740    GET_JIT_PROF_TABLE(r0)
1741    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1742    cmp     r0,#0
1743    bne     common_updateProfile
1744    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1745    GOTO_OPCODE(ip)                     @ jump to next instruction
1746#else
1747    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1748    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1749    GOTO_OPCODE(ip)                     @ jump to next instruction
1750#endif
1751
1752
1753/* ------------------------------ */
1754    .balign 64
1755.L_OP_IF_LTZ: /* 0x3a */
1756/* File: armv5te/OP_IF_LTZ.S */
1757/* File: armv5te/zcmp.S */
1758    /*
1759     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1760     * fragment that specifies the *reverse* comparison to perform, e.g.
1761     * for "if-le" you would use "gt".
1762     *
1763     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1764     */
1765    /* if-cmp vAA, +BBBB */
1766    mov     r0, rINST, lsr #8           @ r0<- AA
1767    GET_VREG(r2, r0)                    @ r2<- vAA
1768    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1769    cmp     r2, #0                      @ compare (vA, 0)
1770    bge  1f                      @ branch to 1 if comparison failed
1771    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1772    movs    r9, r9, asl #1              @ convert to bytes, check sign
1773    bmi     common_backwardBranch       @ backward branch, do periodic checks
17741:
1775#if defined(WITH_JIT)
1776    GET_JIT_PROF_TABLE(r0)
1777    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1778    cmp     r0,#0
1779    bne     common_updateProfile
1780    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1781    GOTO_OPCODE(ip)                     @ jump to next instruction
1782#else
1783    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1784    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1785    GOTO_OPCODE(ip)                     @ jump to next instruction
1786#endif
1787
1788
1789/* ------------------------------ */
1790    .balign 64
1791.L_OP_IF_GEZ: /* 0x3b */
1792/* File: armv5te/OP_IF_GEZ.S */
1793/* File: armv5te/zcmp.S */
1794    /*
1795     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1796     * fragment that specifies the *reverse* comparison to perform, e.g.
1797     * for "if-le" you would use "gt".
1798     *
1799     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1800     */
1801    /* if-cmp vAA, +BBBB */
1802    mov     r0, rINST, lsr #8           @ r0<- AA
1803    GET_VREG(r2, r0)                    @ r2<- vAA
1804    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1805    cmp     r2, #0                      @ compare (vA, 0)
1806    blt  1f                      @ branch to 1 if comparison failed
1807    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1808    movs    r9, r9, asl #1              @ convert to bytes, check sign
1809    bmi     common_backwardBranch       @ backward branch, do periodic checks
18101:
1811#if defined(WITH_JIT)
1812    GET_JIT_PROF_TABLE(r0)
1813    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1814    cmp     r0,#0
1815    bne     common_updateProfile
1816    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1817    GOTO_OPCODE(ip)                     @ jump to next instruction
1818#else
1819    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1820    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1821    GOTO_OPCODE(ip)                     @ jump to next instruction
1822#endif
1823
1824
1825/* ------------------------------ */
1826    .balign 64
1827.L_OP_IF_GTZ: /* 0x3c */
1828/* File: armv5te/OP_IF_GTZ.S */
1829/* File: armv5te/zcmp.S */
1830    /*
1831     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1832     * fragment that specifies the *reverse* comparison to perform, e.g.
1833     * for "if-le" you would use "gt".
1834     *
1835     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1836     */
1837    /* if-cmp vAA, +BBBB */
1838    mov     r0, rINST, lsr #8           @ r0<- AA
1839    GET_VREG(r2, r0)                    @ r2<- vAA
1840    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1841    cmp     r2, #0                      @ compare (vA, 0)
1842    ble  1f                      @ branch to 1 if comparison failed
1843    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1844    movs    r9, r9, asl #1              @ convert to bytes, check sign
1845    bmi     common_backwardBranch       @ backward branch, do periodic checks
18461:
1847#if defined(WITH_JIT)
1848    GET_JIT_PROF_TABLE(r0)
1849    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1850    cmp     r0,#0
1851    bne     common_updateProfile
1852    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1853    GOTO_OPCODE(ip)                     @ jump to next instruction
1854#else
1855    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1856    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1857    GOTO_OPCODE(ip)                     @ jump to next instruction
1858#endif
1859
1860
1861/* ------------------------------ */
1862    .balign 64
1863.L_OP_IF_LEZ: /* 0x3d */
1864/* File: armv5te/OP_IF_LEZ.S */
1865/* File: armv5te/zcmp.S */
1866    /*
1867     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1868     * fragment that specifies the *reverse* comparison to perform, e.g.
1869     * for "if-le" you would use "gt".
1870     *
1871     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1872     */
1873    /* if-cmp vAA, +BBBB */
1874    mov     r0, rINST, lsr #8           @ r0<- AA
1875    GET_VREG(r2, r0)                    @ r2<- vAA
1876    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1877    cmp     r2, #0                      @ compare (vA, 0)
1878    bgt  1f                      @ branch to 1 if comparison failed
1879    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1880    movs    r9, r9, asl #1              @ convert to bytes, check sign
1881    bmi     common_backwardBranch       @ backward branch, do periodic checks
18821:
1883#if defined(WITH_JIT)
1884    GET_JIT_PROF_TABLE(r0)
1885    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1886    cmp     r0,#0
1887    bne     common_updateProfile
1888    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1889    GOTO_OPCODE(ip)                     @ jump to next instruction
1890#else
1891    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1892    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1893    GOTO_OPCODE(ip)                     @ jump to next instruction
1894#endif
1895
1896
1897/* ------------------------------ */
1898    .balign 64
1899.L_OP_UNUSED_3E: /* 0x3e */
1900/* File: armv5te/OP_UNUSED_3E.S */
1901/* File: armv5te/unused.S */
1902    bl      common_abort
1903
1904
1905/* ------------------------------ */
1906    .balign 64
1907.L_OP_UNUSED_3F: /* 0x3f */
1908/* File: armv5te/OP_UNUSED_3F.S */
1909/* File: armv5te/unused.S */
1910    bl      common_abort
1911
1912
1913/* ------------------------------ */
1914    .balign 64
1915.L_OP_UNUSED_40: /* 0x40 */
1916/* File: armv5te/OP_UNUSED_40.S */
1917/* File: armv5te/unused.S */
1918    bl      common_abort
1919
1920
1921/* ------------------------------ */
1922    .balign 64
1923.L_OP_UNUSED_41: /* 0x41 */
1924/* File: armv5te/OP_UNUSED_41.S */
1925/* File: armv5te/unused.S */
1926    bl      common_abort
1927
1928
1929/* ------------------------------ */
1930    .balign 64
1931.L_OP_UNUSED_42: /* 0x42 */
1932/* File: armv5te/OP_UNUSED_42.S */
1933/* File: armv5te/unused.S */
1934    bl      common_abort
1935
1936
1937/* ------------------------------ */
1938    .balign 64
1939.L_OP_UNUSED_43: /* 0x43 */
1940/* File: armv5te/OP_UNUSED_43.S */
1941/* File: armv5te/unused.S */
1942    bl      common_abort
1943
1944
1945/* ------------------------------ */
1946    .balign 64
1947.L_OP_AGET: /* 0x44 */
1948/* File: armv5te/OP_AGET.S */
1949    /*
1950     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1951     *
1952     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
1953     * instructions.  We use a pair of FETCH_Bs instead.
1954     *
1955     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1956     */
1957    /* op vAA, vBB, vCC */
1958    FETCH_B(r2, 1, 0)                   @ r2<- BB
1959    mov     r9, rINST, lsr #8           @ r9<- AA
1960    FETCH_B(r3, 1, 1)                   @ r3<- CC
1961    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1962    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1963    cmp     r0, #0                      @ null array object?
1964    beq     common_errNullObject        @ yes, bail
1965    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1966    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
1967    cmp     r1, r3                      @ compare unsigned index, length
1968    bcs     common_errArrayIndex        @ index >= length, bail
1969    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1970    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
1971    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1972    SET_VREG(r2, r9)                    @ vAA<- r2
1973    GOTO_OPCODE(ip)                     @ jump to next instruction
1974
1975/* ------------------------------ */
1976    .balign 64
1977.L_OP_AGET_WIDE: /* 0x45 */
1978/* File: armv5te/OP_AGET_WIDE.S */
1979    /*
1980     * Array get, 64 bits.  vAA <- vBB[vCC].
1981     *
1982     * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD.
1983     */
1984    /* aget-wide vAA, vBB, vCC */
1985    FETCH(r0, 1)                        @ r0<- CCBB
1986    mov     r9, rINST, lsr #8           @ r9<- AA
1987    and     r2, r0, #255                @ r2<- BB
1988    mov     r3, r0, lsr #8              @ r3<- CC
1989    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1990    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1991    cmp     r0, #0                      @ null array object?
1992    beq     common_errNullObject        @ yes, bail
1993    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1994    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
1995    cmp     r1, r3                      @ compare unsigned index, length
1996    bcc     .LOP_AGET_WIDE_finish          @ okay, continue below
1997    b       common_errArrayIndex        @ index >= length, bail
1998    @ May want to swap the order of these two branches depending on how the
1999    @ branch prediction (if any) handles conditional forward branches vs.
2000    @ unconditional forward branches.
2001
2002/* ------------------------------ */
2003    .balign 64
2004.L_OP_AGET_OBJECT: /* 0x46 */
2005/* File: armv5te/OP_AGET_OBJECT.S */
2006/* File: armv5te/OP_AGET.S */
2007    /*
2008     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2009     *
2010     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2011     * instructions.  We use a pair of FETCH_Bs instead.
2012     *
2013     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2014     */
2015    /* op vAA, vBB, vCC */
2016    FETCH_B(r2, 1, 0)                   @ r2<- BB
2017    mov     r9, rINST, lsr #8           @ r9<- AA
2018    FETCH_B(r3, 1, 1)                   @ r3<- CC
2019    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2020    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2021    cmp     r0, #0                      @ null array object?
2022    beq     common_errNullObject        @ yes, bail
2023    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2024    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
2025    cmp     r1, r3                      @ compare unsigned index, length
2026    bcs     common_errArrayIndex        @ index >= length, bail
2027    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2028    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2029    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2030    SET_VREG(r2, r9)                    @ vAA<- r2
2031    GOTO_OPCODE(ip)                     @ jump to next instruction
2032
2033
2034/* ------------------------------ */
2035    .balign 64
2036.L_OP_AGET_BOOLEAN: /* 0x47 */
2037/* File: armv5te/OP_AGET_BOOLEAN.S */
2038/* File: armv5te/OP_AGET.S */
2039    /*
2040     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2041     *
2042     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2043     * instructions.  We use a pair of FETCH_Bs instead.
2044     *
2045     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2046     */
2047    /* op vAA, vBB, vCC */
2048    FETCH_B(r2, 1, 0)                   @ r2<- BB
2049    mov     r9, rINST, lsr #8           @ r9<- AA
2050    FETCH_B(r3, 1, 1)                   @ r3<- CC
2051    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2052    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2053    cmp     r0, #0                      @ null array object?
2054    beq     common_errNullObject        @ yes, bail
2055    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2056    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2057    cmp     r1, r3                      @ compare unsigned index, length
2058    bcs     common_errArrayIndex        @ index >= length, bail
2059    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2060    ldrb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2061    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2062    SET_VREG(r2, r9)                    @ vAA<- r2
2063    GOTO_OPCODE(ip)                     @ jump to next instruction
2064
2065
2066/* ------------------------------ */
2067    .balign 64
2068.L_OP_AGET_BYTE: /* 0x48 */
2069/* File: armv5te/OP_AGET_BYTE.S */
2070/* File: armv5te/OP_AGET.S */
2071    /*
2072     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2073     *
2074     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2075     * instructions.  We use a pair of FETCH_Bs instead.
2076     *
2077     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2078     */
2079    /* op vAA, vBB, vCC */
2080    FETCH_B(r2, 1, 0)                   @ r2<- BB
2081    mov     r9, rINST, lsr #8           @ r9<- AA
2082    FETCH_B(r3, 1, 1)                   @ r3<- CC
2083    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2084    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2085    cmp     r0, #0                      @ null array object?
2086    beq     common_errNullObject        @ yes, bail
2087    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2088    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2089    cmp     r1, r3                      @ compare unsigned index, length
2090    bcs     common_errArrayIndex        @ index >= length, bail
2091    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2092    ldrsb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2093    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2094    SET_VREG(r2, r9)                    @ vAA<- r2
2095    GOTO_OPCODE(ip)                     @ jump to next instruction
2096
2097
2098/* ------------------------------ */
2099    .balign 64
2100.L_OP_AGET_CHAR: /* 0x49 */
2101/* File: armv5te/OP_AGET_CHAR.S */
2102/* File: armv5te/OP_AGET.S */
2103    /*
2104     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2105     *
2106     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2107     * instructions.  We use a pair of FETCH_Bs instead.
2108     *
2109     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2110     */
2111    /* op vAA, vBB, vCC */
2112    FETCH_B(r2, 1, 0)                   @ r2<- BB
2113    mov     r9, rINST, lsr #8           @ r9<- AA
2114    FETCH_B(r3, 1, 1)                   @ r3<- CC
2115    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2116    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2117    cmp     r0, #0                      @ null array object?
2118    beq     common_errNullObject        @ yes, bail
2119    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2120    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2121    cmp     r1, r3                      @ compare unsigned index, length
2122    bcs     common_errArrayIndex        @ index >= length, bail
2123    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2124    ldrh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2125    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2126    SET_VREG(r2, r9)                    @ vAA<- r2
2127    GOTO_OPCODE(ip)                     @ jump to next instruction
2128
2129
2130/* ------------------------------ */
2131    .balign 64
2132.L_OP_AGET_SHORT: /* 0x4a */
2133/* File: armv5te/OP_AGET_SHORT.S */
2134/* File: armv5te/OP_AGET.S */
2135    /*
2136     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2137     *
2138     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2139     * instructions.  We use a pair of FETCH_Bs instead.
2140     *
2141     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2142     */
2143    /* op vAA, vBB, vCC */
2144    FETCH_B(r2, 1, 0)                   @ r2<- BB
2145    mov     r9, rINST, lsr #8           @ r9<- AA
2146    FETCH_B(r3, 1, 1)                   @ r3<- CC
2147    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2148    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2149    cmp     r0, #0                      @ null array object?
2150    beq     common_errNullObject        @ yes, bail
2151    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2152    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2153    cmp     r1, r3                      @ compare unsigned index, length
2154    bcs     common_errArrayIndex        @ index >= length, bail
2155    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2156    ldrsh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2157    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2158    SET_VREG(r2, r9)                    @ vAA<- r2
2159    GOTO_OPCODE(ip)                     @ jump to next instruction
2160
2161
2162/* ------------------------------ */
2163    .balign 64
2164.L_OP_APUT: /* 0x4b */
2165/* File: armv5te/OP_APUT.S */
2166    /*
2167     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2168     *
2169     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2170     * instructions.  We use a pair of FETCH_Bs instead.
2171     *
2172     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2173     */
2174    /* op vAA, vBB, vCC */
2175    FETCH_B(r2, 1, 0)                   @ r2<- BB
2176    mov     r9, rINST, lsr #8           @ r9<- AA
2177    FETCH_B(r3, 1, 1)                   @ r3<- CC
2178    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2179    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2180    cmp     r0, #0                      @ null array object?
2181    beq     common_errNullObject        @ yes, bail
2182    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2183    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
2184    cmp     r1, r3                      @ compare unsigned index, length
2185    bcs     common_errArrayIndex        @ index >= length, bail
2186    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2187    GET_VREG(r2, r9)                    @ r2<- vAA
2188    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2189    str  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2190    GOTO_OPCODE(ip)                     @ jump to next instruction
2191
2192/* ------------------------------ */
2193    .balign 64
2194.L_OP_APUT_WIDE: /* 0x4c */
2195/* File: armv5te/OP_APUT_WIDE.S */
2196    /*
2197     * Array put, 64 bits.  vBB[vCC] <- vAA.
2198     *
2199     * Arrays of long/double are 64-bit aligned, so it's okay to use STRD.
2200     */
2201    /* aput-wide vAA, vBB, vCC */
2202    FETCH(r0, 1)                        @ r0<- CCBB
2203    mov     r9, rINST, lsr #8           @ r9<- AA
2204    and     r2, r0, #255                @ r2<- BB
2205    mov     r3, r0, lsr #8              @ r3<- CC
2206    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2207    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2208    cmp     r0, #0                      @ null array object?
2209    beq     common_errNullObject        @ yes, bail
2210    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2211    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
2212    cmp     r1, r3                      @ compare unsigned index, length
2213    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2214    bcc     .LOP_APUT_WIDE_finish          @ okay, continue below
2215    b       common_errArrayIndex        @ index >= length, bail
2216    @ May want to swap the order of these two branches depending on how the
2217    @ branch prediction (if any) handles conditional forward branches vs.
2218    @ unconditional forward branches.
2219
2220/* ------------------------------ */
2221    .balign 64
2222.L_OP_APUT_OBJECT: /* 0x4d */
2223/* File: armv5te/OP_APUT_OBJECT.S */
2224    /*
2225     * Store an object into an array.  vBB[vCC] <- vAA.
2226     */
2227    /* op vAA, vBB, vCC */
2228    FETCH(r0, 1)                        @ r0<- CCBB
2229    mov     r9, rINST, lsr #8           @ r9<- AA
2230    and     r2, r0, #255                @ r2<- BB
2231    mov     r3, r0, lsr #8              @ r3<- CC
2232    GET_VREG(rINST, r2)                 @ rINST<- vBB (array object)
2233    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2234    cmp     rINST, #0                   @ null array object?
2235    GET_VREG(r9, r9)                    @ r9<- vAA
2236    beq     common_errNullObject        @ yes, bail
2237    ldr     r3, [rINST, #offArrayObject_length]   @ r3<- arrayObj->length
2238    add     r10, rINST, r1, lsl #2      @ r10<- arrayObj + index*width
2239    cmp     r1, r3                      @ compare unsigned index, length
2240    bcc     .LOP_APUT_OBJECT_finish          @ we're okay, continue on
2241    b       common_errArrayIndex        @ index >= length, bail
2242
2243
2244/* ------------------------------ */
2245    .balign 64
2246.L_OP_APUT_BOOLEAN: /* 0x4e */
2247/* File: armv5te/OP_APUT_BOOLEAN.S */
2248/* File: armv5te/OP_APUT.S */
2249    /*
2250     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2251     *
2252     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2253     * instructions.  We use a pair of FETCH_Bs instead.
2254     *
2255     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2256     */
2257    /* op vAA, vBB, vCC */
2258    FETCH_B(r2, 1, 0)                   @ r2<- BB
2259    mov     r9, rINST, lsr #8           @ r9<- AA
2260    FETCH_B(r3, 1, 1)                   @ r3<- CC
2261    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2262    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2263    cmp     r0, #0                      @ null array object?
2264    beq     common_errNullObject        @ yes, bail
2265    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2266    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2267    cmp     r1, r3                      @ compare unsigned index, length
2268    bcs     common_errArrayIndex        @ index >= length, bail
2269    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2270    GET_VREG(r2, r9)                    @ r2<- vAA
2271    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2272    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2273    GOTO_OPCODE(ip)                     @ jump to next instruction
2274
2275
2276/* ------------------------------ */
2277    .balign 64
2278.L_OP_APUT_BYTE: /* 0x4f */
2279/* File: armv5te/OP_APUT_BYTE.S */
2280/* File: armv5te/OP_APUT.S */
2281    /*
2282     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2283     *
2284     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2285     * instructions.  We use a pair of FETCH_Bs instead.
2286     *
2287     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2288     */
2289    /* op vAA, vBB, vCC */
2290    FETCH_B(r2, 1, 0)                   @ r2<- BB
2291    mov     r9, rINST, lsr #8           @ r9<- AA
2292    FETCH_B(r3, 1, 1)                   @ r3<- CC
2293    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2294    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2295    cmp     r0, #0                      @ null array object?
2296    beq     common_errNullObject        @ yes, bail
2297    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2298    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2299    cmp     r1, r3                      @ compare unsigned index, length
2300    bcs     common_errArrayIndex        @ index >= length, bail
2301    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2302    GET_VREG(r2, r9)                    @ r2<- vAA
2303    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2304    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2305    GOTO_OPCODE(ip)                     @ jump to next instruction
2306
2307
2308/* ------------------------------ */
2309    .balign 64
2310.L_OP_APUT_CHAR: /* 0x50 */
2311/* File: armv5te/OP_APUT_CHAR.S */
2312/* File: armv5te/OP_APUT.S */
2313    /*
2314     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2315     *
2316     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2317     * instructions.  We use a pair of FETCH_Bs instead.
2318     *
2319     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2320     */
2321    /* op vAA, vBB, vCC */
2322    FETCH_B(r2, 1, 0)                   @ r2<- BB
2323    mov     r9, rINST, lsr #8           @ r9<- AA
2324    FETCH_B(r3, 1, 1)                   @ r3<- CC
2325    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2326    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2327    cmp     r0, #0                      @ null array object?
2328    beq     common_errNullObject        @ yes, bail
2329    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2330    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2331    cmp     r1, r3                      @ compare unsigned index, length
2332    bcs     common_errArrayIndex        @ index >= length, bail
2333    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2334    GET_VREG(r2, r9)                    @ r2<- vAA
2335    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2336    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2337    GOTO_OPCODE(ip)                     @ jump to next instruction
2338
2339
2340/* ------------------------------ */
2341    .balign 64
2342.L_OP_APUT_SHORT: /* 0x51 */
2343/* File: armv5te/OP_APUT_SHORT.S */
2344/* File: armv5te/OP_APUT.S */
2345    /*
2346     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2347     *
2348     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2349     * instructions.  We use a pair of FETCH_Bs instead.
2350     *
2351     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2352     */
2353    /* op vAA, vBB, vCC */
2354    FETCH_B(r2, 1, 0)                   @ r2<- BB
2355    mov     r9, rINST, lsr #8           @ r9<- AA
2356    FETCH_B(r3, 1, 1)                   @ r3<- CC
2357    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2358    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2359    cmp     r0, #0                      @ null array object?
2360    beq     common_errNullObject        @ yes, bail
2361    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2362    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2363    cmp     r1, r3                      @ compare unsigned index, length
2364    bcs     common_errArrayIndex        @ index >= length, bail
2365    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2366    GET_VREG(r2, r9)                    @ r2<- vAA
2367    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2368    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2369    GOTO_OPCODE(ip)                     @ jump to next instruction
2370
2371
2372/* ------------------------------ */
2373    .balign 64
2374.L_OP_IGET: /* 0x52 */
2375/* File: armv5te/OP_IGET.S */
2376    /*
2377     * General 32-bit instance field get.
2378     *
2379     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2380     */
2381    /* op vA, vB, field@CCCC */
2382    mov     r0, rINST, lsr #12          @ r0<- B
2383    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2384    FETCH(r1, 1)                        @ r1<- field ref CCCC
2385    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2386    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2387    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2388    cmp     r0, #0                      @ is resolved entry null?
2389    bne     .LOP_IGET_finish          @ no, already resolved
23908:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2391    EXPORT_PC()                         @ resolve() could throw
2392    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2393    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2394    cmp     r0, #0
2395    bne     .LOP_IGET_finish
2396    b       common_exceptionThrown
2397
2398/* ------------------------------ */
2399    .balign 64
2400.L_OP_IGET_WIDE: /* 0x53 */
2401/* File: armv5te/OP_IGET_WIDE.S */
2402    /*
2403     * Wide 32-bit instance field get.
2404     */
2405    /* iget-wide vA, vB, field@CCCC */
2406    mov     r0, rINST, lsr #12          @ r0<- B
2407    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2408    FETCH(r1, 1)                        @ r1<- field ref CCCC
2409    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
2410    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2411    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2412    cmp     r0, #0                      @ is resolved entry null?
2413    bne     .LOP_IGET_WIDE_finish          @ no, already resolved
24148:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
2415    EXPORT_PC()                         @ resolve() could throw
2416    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2417    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2418    cmp     r0, #0
2419    bne     .LOP_IGET_WIDE_finish
2420    b       common_exceptionThrown
2421
2422/* ------------------------------ */
2423    .balign 64
2424.L_OP_IGET_OBJECT: /* 0x54 */
2425/* File: armv5te/OP_IGET_OBJECT.S */
2426/* File: armv5te/OP_IGET.S */
2427    /*
2428     * General 32-bit instance field get.
2429     *
2430     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2431     */
2432    /* op vA, vB, field@CCCC */
2433    mov     r0, rINST, lsr #12          @ r0<- B
2434    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2435    FETCH(r1, 1)                        @ r1<- field ref CCCC
2436    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2437    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2438    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2439    cmp     r0, #0                      @ is resolved entry null?
2440    bne     .LOP_IGET_OBJECT_finish          @ no, already resolved
24418:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2442    EXPORT_PC()                         @ resolve() could throw
2443    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2444    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2445    cmp     r0, #0
2446    bne     .LOP_IGET_OBJECT_finish
2447    b       common_exceptionThrown
2448
2449
2450/* ------------------------------ */
2451    .balign 64
2452.L_OP_IGET_BOOLEAN: /* 0x55 */
2453/* File: armv5te/OP_IGET_BOOLEAN.S */
2454@include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" }
2455/* File: armv5te/OP_IGET.S */
2456    /*
2457     * General 32-bit instance field get.
2458     *
2459     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2460     */
2461    /* op vA, vB, field@CCCC */
2462    mov     r0, rINST, lsr #12          @ r0<- B
2463    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2464    FETCH(r1, 1)                        @ r1<- field ref CCCC
2465    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2466    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2467    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2468    cmp     r0, #0                      @ is resolved entry null?
2469    bne     .LOP_IGET_BOOLEAN_finish          @ no, already resolved
24708:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2471    EXPORT_PC()                         @ resolve() could throw
2472    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2473    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2474    cmp     r0, #0
2475    bne     .LOP_IGET_BOOLEAN_finish
2476    b       common_exceptionThrown
2477
2478
2479/* ------------------------------ */
2480    .balign 64
2481.L_OP_IGET_BYTE: /* 0x56 */
2482/* File: armv5te/OP_IGET_BYTE.S */
2483@include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" }
2484/* File: armv5te/OP_IGET.S */
2485    /*
2486     * General 32-bit instance field get.
2487     *
2488     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2489     */
2490    /* op vA, vB, field@CCCC */
2491    mov     r0, rINST, lsr #12          @ r0<- B
2492    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2493    FETCH(r1, 1)                        @ r1<- field ref CCCC
2494    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2495    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2496    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2497    cmp     r0, #0                      @ is resolved entry null?
2498    bne     .LOP_IGET_BYTE_finish          @ no, already resolved
24998:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2500    EXPORT_PC()                         @ resolve() could throw
2501    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2502    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2503    cmp     r0, #0
2504    bne     .LOP_IGET_BYTE_finish
2505    b       common_exceptionThrown
2506
2507
2508/* ------------------------------ */
2509    .balign 64
2510.L_OP_IGET_CHAR: /* 0x57 */
2511/* File: armv5te/OP_IGET_CHAR.S */
2512@include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" }
2513/* File: armv5te/OP_IGET.S */
2514    /*
2515     * General 32-bit instance field get.
2516     *
2517     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2518     */
2519    /* op vA, vB, field@CCCC */
2520    mov     r0, rINST, lsr #12          @ r0<- B
2521    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2522    FETCH(r1, 1)                        @ r1<- field ref CCCC
2523    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2524    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2525    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2526    cmp     r0, #0                      @ is resolved entry null?
2527    bne     .LOP_IGET_CHAR_finish          @ no, already resolved
25288:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2529    EXPORT_PC()                         @ resolve() could throw
2530    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2531    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2532    cmp     r0, #0
2533    bne     .LOP_IGET_CHAR_finish
2534    b       common_exceptionThrown
2535
2536
2537/* ------------------------------ */
2538    .balign 64
2539.L_OP_IGET_SHORT: /* 0x58 */
2540/* File: armv5te/OP_IGET_SHORT.S */
2541@include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" }
2542/* File: armv5te/OP_IGET.S */
2543    /*
2544     * General 32-bit instance field get.
2545     *
2546     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2547     */
2548    /* op vA, vB, field@CCCC */
2549    mov     r0, rINST, lsr #12          @ r0<- B
2550    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2551    FETCH(r1, 1)                        @ r1<- field ref CCCC
2552    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2553    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2554    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2555    cmp     r0, #0                      @ is resolved entry null?
2556    bne     .LOP_IGET_SHORT_finish          @ no, already resolved
25578:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2558    EXPORT_PC()                         @ resolve() could throw
2559    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2560    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2561    cmp     r0, #0
2562    bne     .LOP_IGET_SHORT_finish
2563    b       common_exceptionThrown
2564
2565
2566/* ------------------------------ */
2567    .balign 64
2568.L_OP_IPUT: /* 0x59 */
2569/* File: armv5te/OP_IPUT.S */
2570    /*
2571     * General 32-bit instance field put.
2572     *
2573     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2574     */
2575    /* op vA, vB, field@CCCC */
2576    mov     r0, rINST, lsr #12          @ r0<- B
2577    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2578    FETCH(r1, 1)                        @ r1<- field ref CCCC
2579    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2580    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2581    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2582    cmp     r0, #0                      @ is resolved entry null?
2583    bne     .LOP_IPUT_finish          @ no, already resolved
25848:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2585    EXPORT_PC()                         @ resolve() could throw
2586    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2587    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2588    cmp     r0, #0                      @ success?
2589    bne     .LOP_IPUT_finish          @ yes, finish up
2590    b       common_exceptionThrown
2591
2592/* ------------------------------ */
2593    .balign 64
2594.L_OP_IPUT_WIDE: /* 0x5a */
2595/* File: armv5te/OP_IPUT_WIDE.S */
2596    /* iput-wide vA, vB, field@CCCC */
2597    mov     r0, rINST, lsr #12          @ r0<- B
2598    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2599    FETCH(r1, 1)                        @ r1<- field ref CCCC
2600    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
2601    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2602    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2603    cmp     r0, #0                      @ is resolved entry null?
2604    bne     .LOP_IPUT_WIDE_finish          @ no, already resolved
26058:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
2606    EXPORT_PC()                         @ resolve() could throw
2607    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2608    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2609    cmp     r0, #0                      @ success?
2610    bne     .LOP_IPUT_WIDE_finish          @ yes, finish up
2611    b       common_exceptionThrown
2612
2613/* ------------------------------ */
2614    .balign 64
2615.L_OP_IPUT_OBJECT: /* 0x5b */
2616/* File: armv5te/OP_IPUT_OBJECT.S */
2617    /*
2618     * 32-bit instance field put.
2619     *
2620     * for: iput-object, iput-object-volatile
2621     */
2622    /* op vA, vB, field@CCCC */
2623    mov     r0, rINST, lsr #12          @ r0<- B
2624    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2625    FETCH(r1, 1)                        @ r1<- field ref CCCC
2626    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2627    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2628    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2629    cmp     r0, #0                      @ is resolved entry null?
2630    bne     .LOP_IPUT_OBJECT_finish          @ no, already resolved
26318:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2632    EXPORT_PC()                         @ resolve() could throw
2633    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2634    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2635    cmp     r0, #0                      @ success?
2636    bne     .LOP_IPUT_OBJECT_finish          @ yes, finish up
2637    b       common_exceptionThrown
2638
2639/* ------------------------------ */
2640    .balign 64
2641.L_OP_IPUT_BOOLEAN: /* 0x5c */
2642/* File: armv5te/OP_IPUT_BOOLEAN.S */
2643@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" }
2644/* File: armv5te/OP_IPUT.S */
2645    /*
2646     * General 32-bit instance field put.
2647     *
2648     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2649     */
2650    /* op vA, vB, field@CCCC */
2651    mov     r0, rINST, lsr #12          @ r0<- B
2652    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2653    FETCH(r1, 1)                        @ r1<- field ref CCCC
2654    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2655    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2656    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2657    cmp     r0, #0                      @ is resolved entry null?
2658    bne     .LOP_IPUT_BOOLEAN_finish          @ no, already resolved
26598:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2660    EXPORT_PC()                         @ resolve() could throw
2661    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2662    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2663    cmp     r0, #0                      @ success?
2664    bne     .LOP_IPUT_BOOLEAN_finish          @ yes, finish up
2665    b       common_exceptionThrown
2666
2667
2668/* ------------------------------ */
2669    .balign 64
2670.L_OP_IPUT_BYTE: /* 0x5d */
2671/* File: armv5te/OP_IPUT_BYTE.S */
2672@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" }
2673/* File: armv5te/OP_IPUT.S */
2674    /*
2675     * General 32-bit instance field put.
2676     *
2677     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2678     */
2679    /* op vA, vB, field@CCCC */
2680    mov     r0, rINST, lsr #12          @ r0<- B
2681    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2682    FETCH(r1, 1)                        @ r1<- field ref CCCC
2683    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2684    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2685    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2686    cmp     r0, #0                      @ is resolved entry null?
2687    bne     .LOP_IPUT_BYTE_finish          @ no, already resolved
26888:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2689    EXPORT_PC()                         @ resolve() could throw
2690    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2691    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2692    cmp     r0, #0                      @ success?
2693    bne     .LOP_IPUT_BYTE_finish          @ yes, finish up
2694    b       common_exceptionThrown
2695
2696
2697/* ------------------------------ */
2698    .balign 64
2699.L_OP_IPUT_CHAR: /* 0x5e */
2700/* File: armv5te/OP_IPUT_CHAR.S */
2701@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" }
2702/* File: armv5te/OP_IPUT.S */
2703    /*
2704     * General 32-bit instance field put.
2705     *
2706     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2707     */
2708    /* op vA, vB, field@CCCC */
2709    mov     r0, rINST, lsr #12          @ r0<- B
2710    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2711    FETCH(r1, 1)                        @ r1<- field ref CCCC
2712    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2713    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2714    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2715    cmp     r0, #0                      @ is resolved entry null?
2716    bne     .LOP_IPUT_CHAR_finish          @ no, already resolved
27178:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2718    EXPORT_PC()                         @ resolve() could throw
2719    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2720    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2721    cmp     r0, #0                      @ success?
2722    bne     .LOP_IPUT_CHAR_finish          @ yes, finish up
2723    b       common_exceptionThrown
2724
2725
2726/* ------------------------------ */
2727    .balign 64
2728.L_OP_IPUT_SHORT: /* 0x5f */
2729/* File: armv5te/OP_IPUT_SHORT.S */
2730@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" }
2731/* File: armv5te/OP_IPUT.S */
2732    /*
2733     * General 32-bit instance field put.
2734     *
2735     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2736     */
2737    /* op vA, vB, field@CCCC */
2738    mov     r0, rINST, lsr #12          @ r0<- B
2739    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2740    FETCH(r1, 1)                        @ r1<- field ref CCCC
2741    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2742    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2743    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2744    cmp     r0, #0                      @ is resolved entry null?
2745    bne     .LOP_IPUT_SHORT_finish          @ no, already resolved
27468:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2747    EXPORT_PC()                         @ resolve() could throw
2748    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2749    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2750    cmp     r0, #0                      @ success?
2751    bne     .LOP_IPUT_SHORT_finish          @ yes, finish up
2752    b       common_exceptionThrown
2753
2754
2755/* ------------------------------ */
2756    .balign 64
2757.L_OP_SGET: /* 0x60 */
2758/* File: armv5te/OP_SGET.S */
2759    /*
2760     * General 32-bit SGET handler.
2761     *
2762     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2763     */
2764    /* op vAA, field@BBBB */
2765    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2766    FETCH(r1, 1)                        @ r1<- field ref BBBB
2767    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2768    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2769    cmp     r0, #0                      @ is resolved entry null?
2770    beq     .LOP_SGET_resolve         @ yes, do resolve
2771.LOP_SGET_finish: @ field ptr in r0
2772    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2773    @ no-op                             @ acquiring load
2774    mov     r2, rINST, lsr #8           @ r2<- AA
2775    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2776    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2777    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2778    GOTO_OPCODE(ip)                     @ jump to next instruction
2779
2780/* ------------------------------ */
2781    .balign 64
2782.L_OP_SGET_WIDE: /* 0x61 */
2783/* File: armv5te/OP_SGET_WIDE.S */
2784    /*
2785     * 64-bit SGET handler.
2786     */
2787    /* sget-wide vAA, field@BBBB */
2788    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2789    FETCH(r1, 1)                        @ r1<- field ref BBBB
2790    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2791    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2792    cmp     r0, #0                      @ is resolved entry null?
2793    beq     .LOP_SGET_WIDE_resolve         @ yes, do resolve
2794.LOP_SGET_WIDE_finish:
2795    mov     r9, rINST, lsr #8           @ r9<- AA
2796    .if 0
2797    add     r0, r0, #offStaticField_value @ r0<- pointer to data
2798    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
2799    .else
2800    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
2801    .endif
2802    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2803    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2804    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
2805    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2806    GOTO_OPCODE(ip)                     @ jump to next instruction
2807
2808/* ------------------------------ */
2809    .balign 64
2810.L_OP_SGET_OBJECT: /* 0x62 */
2811/* File: armv5te/OP_SGET_OBJECT.S */
2812/* File: armv5te/OP_SGET.S */
2813    /*
2814     * General 32-bit SGET handler.
2815     *
2816     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2817     */
2818    /* op vAA, field@BBBB */
2819    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2820    FETCH(r1, 1)                        @ r1<- field ref BBBB
2821    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2822    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2823    cmp     r0, #0                      @ is resolved entry null?
2824    beq     .LOP_SGET_OBJECT_resolve         @ yes, do resolve
2825.LOP_SGET_OBJECT_finish: @ field ptr in r0
2826    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2827    @ no-op                             @ acquiring load
2828    mov     r2, rINST, lsr #8           @ r2<- AA
2829    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2830    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2831    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2832    GOTO_OPCODE(ip)                     @ jump to next instruction
2833
2834
2835/* ------------------------------ */
2836    .balign 64
2837.L_OP_SGET_BOOLEAN: /* 0x63 */
2838/* File: armv5te/OP_SGET_BOOLEAN.S */
2839/* File: armv5te/OP_SGET.S */
2840    /*
2841     * General 32-bit SGET handler.
2842     *
2843     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2844     */
2845    /* op vAA, field@BBBB */
2846    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2847    FETCH(r1, 1)                        @ r1<- field ref BBBB
2848    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2849    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2850    cmp     r0, #0                      @ is resolved entry null?
2851    beq     .LOP_SGET_BOOLEAN_resolve         @ yes, do resolve
2852.LOP_SGET_BOOLEAN_finish: @ field ptr in r0
2853    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2854    @ no-op                             @ acquiring load
2855    mov     r2, rINST, lsr #8           @ r2<- AA
2856    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2857    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2858    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2859    GOTO_OPCODE(ip)                     @ jump to next instruction
2860
2861
2862/* ------------------------------ */
2863    .balign 64
2864.L_OP_SGET_BYTE: /* 0x64 */
2865/* File: armv5te/OP_SGET_BYTE.S */
2866/* File: armv5te/OP_SGET.S */
2867    /*
2868     * General 32-bit SGET handler.
2869     *
2870     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2871     */
2872    /* op vAA, field@BBBB */
2873    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2874    FETCH(r1, 1)                        @ r1<- field ref BBBB
2875    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2876    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2877    cmp     r0, #0                      @ is resolved entry null?
2878    beq     .LOP_SGET_BYTE_resolve         @ yes, do resolve
2879.LOP_SGET_BYTE_finish: @ field ptr in r0
2880    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2881    @ no-op                             @ acquiring load
2882    mov     r2, rINST, lsr #8           @ r2<- AA
2883    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2884    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2885    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2886    GOTO_OPCODE(ip)                     @ jump to next instruction
2887
2888
2889/* ------------------------------ */
2890    .balign 64
2891.L_OP_SGET_CHAR: /* 0x65 */
2892/* File: armv5te/OP_SGET_CHAR.S */
2893/* File: armv5te/OP_SGET.S */
2894    /*
2895     * General 32-bit SGET handler.
2896     *
2897     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2898     */
2899    /* op vAA, field@BBBB */
2900    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2901    FETCH(r1, 1)                        @ r1<- field ref BBBB
2902    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2903    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2904    cmp     r0, #0                      @ is resolved entry null?
2905    beq     .LOP_SGET_CHAR_resolve         @ yes, do resolve
2906.LOP_SGET_CHAR_finish: @ field ptr in r0
2907    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2908    @ no-op                             @ acquiring load
2909    mov     r2, rINST, lsr #8           @ r2<- AA
2910    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2911    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2912    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2913    GOTO_OPCODE(ip)                     @ jump to next instruction
2914
2915
2916/* ------------------------------ */
2917    .balign 64
2918.L_OP_SGET_SHORT: /* 0x66 */
2919/* File: armv5te/OP_SGET_SHORT.S */
2920/* File: armv5te/OP_SGET.S */
2921    /*
2922     * General 32-bit SGET handler.
2923     *
2924     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2925     */
2926    /* op vAA, field@BBBB */
2927    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2928    FETCH(r1, 1)                        @ r1<- field ref BBBB
2929    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2930    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2931    cmp     r0, #0                      @ is resolved entry null?
2932    beq     .LOP_SGET_SHORT_resolve         @ yes, do resolve
2933.LOP_SGET_SHORT_finish: @ field ptr in r0
2934    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2935    @ no-op                             @ acquiring load
2936    mov     r2, rINST, lsr #8           @ r2<- AA
2937    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2938    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2939    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2940    GOTO_OPCODE(ip)                     @ jump to next instruction
2941
2942
2943/* ------------------------------ */
2944    .balign 64
2945.L_OP_SPUT: /* 0x67 */
2946/* File: armv5te/OP_SPUT.S */
2947    /*
2948     * General 32-bit SPUT handler.
2949     *
2950     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2951     */
2952    /* op vAA, field@BBBB */
2953    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2954    FETCH(r1, 1)                        @ r1<- field ref BBBB
2955    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2956    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2957    cmp     r0, #0                      @ is resolved entry null?
2958    beq     .LOP_SPUT_resolve         @ yes, do resolve
2959.LOP_SPUT_finish:   @ field ptr in r0
2960    mov     r2, rINST, lsr #8           @ r2<- AA
2961    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2962    GET_VREG(r1, r2)                    @ r1<- fp[AA]
2963    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2964    @ no-op                             @ releasing store
2965    str     r1, [r0, #offStaticField_value] @ field<- vAA
2966    GOTO_OPCODE(ip)                     @ jump to next instruction
2967
2968/* ------------------------------ */
2969    .balign 64
2970.L_OP_SPUT_WIDE: /* 0x68 */
2971/* File: armv5te/OP_SPUT_WIDE.S */
2972    /*
2973     * 64-bit SPUT handler.
2974     */
2975    /* sput-wide vAA, field@BBBB */
2976    ldr     r0, [rSELF, #offThread_methodClassDex]  @ r0<- DvmDex
2977    FETCH(r1, 1)                        @ r1<- field ref BBBB
2978    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
2979    mov     r9, rINST, lsr #8           @ r9<- AA
2980    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
2981    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2982    cmp     r2, #0                      @ is resolved entry null?
2983    beq     .LOP_SPUT_WIDE_resolve         @ yes, do resolve
2984.LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9
2985    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2986    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
2987    GET_INST_OPCODE(r10)                @ extract opcode from rINST
2988    .if 0
2989    add     r2, r2, #offStaticField_value @ r2<- pointer to data
2990    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
2991    .else
2992    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
2993    .endif
2994    GOTO_OPCODE(r10)                    @ jump to next instruction
2995
2996/* ------------------------------ */
2997    .balign 64
2998.L_OP_SPUT_OBJECT: /* 0x69 */
2999/* File: armv5te/OP_SPUT_OBJECT.S */
3000    /*
3001     * 32-bit SPUT handler for objects
3002     *
3003     * for: sput-object, sput-object-volatile
3004     */
3005    /* op vAA, field@BBBB */
3006    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
3007    FETCH(r1, 1)                        @ r1<- field ref BBBB
3008    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3009    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3010    cmp     r0, #0                      @ is resolved entry null?
3011    bne     .LOP_SPUT_OBJECT_finish          @ no, continue
3012    ldr     r9, [rSELF, #offThread_method]    @ r9<- current method
3013    EXPORT_PC()                         @ resolve() could throw, so export now
3014    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
3015    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
3016    cmp     r0, #0                      @ success?
3017    bne     .LOP_SPUT_OBJECT_finish          @ yes, finish
3018    b       common_exceptionThrown      @ no, handle exception
3019
3020
3021/* ------------------------------ */
3022    .balign 64
3023.L_OP_SPUT_BOOLEAN: /* 0x6a */
3024/* File: armv5te/OP_SPUT_BOOLEAN.S */
3025/* File: armv5te/OP_SPUT.S */
3026    /*
3027     * General 32-bit SPUT handler.
3028     *
3029     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3030     */
3031    /* op vAA, field@BBBB */
3032    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
3033    FETCH(r1, 1)                        @ r1<- field ref BBBB
3034    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3035    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3036    cmp     r0, #0                      @ is resolved entry null?
3037    beq     .LOP_SPUT_BOOLEAN_resolve         @ yes, do resolve
3038.LOP_SPUT_BOOLEAN_finish:   @ field ptr in r0
3039    mov     r2, rINST, lsr #8           @ r2<- AA
3040    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3041    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3042    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3043    @ no-op                             @ releasing store
3044    str     r1, [r0, #offStaticField_value] @ field<- vAA
3045    GOTO_OPCODE(ip)                     @ jump to next instruction
3046
3047
3048/* ------------------------------ */
3049    .balign 64
3050.L_OP_SPUT_BYTE: /* 0x6b */
3051/* File: armv5te/OP_SPUT_BYTE.S */
3052/* File: armv5te/OP_SPUT.S */
3053    /*
3054     * General 32-bit SPUT handler.
3055     *
3056     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3057     */
3058    /* op vAA, field@BBBB */
3059    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
3060    FETCH(r1, 1)                        @ r1<- field ref BBBB
3061    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3062    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3063    cmp     r0, #0                      @ is resolved entry null?
3064    beq     .LOP_SPUT_BYTE_resolve         @ yes, do resolve
3065.LOP_SPUT_BYTE_finish:   @ field ptr in r0
3066    mov     r2, rINST, lsr #8           @ r2<- AA
3067    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3068    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3069    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3070    @ no-op                             @ releasing store
3071    str     r1, [r0, #offStaticField_value] @ field<- vAA
3072    GOTO_OPCODE(ip)                     @ jump to next instruction
3073
3074
3075/* ------------------------------ */
3076    .balign 64
3077.L_OP_SPUT_CHAR: /* 0x6c */
3078/* File: armv5te/OP_SPUT_CHAR.S */
3079/* File: armv5te/OP_SPUT.S */
3080    /*
3081     * General 32-bit SPUT handler.
3082     *
3083     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3084     */
3085    /* op vAA, field@BBBB */
3086    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
3087    FETCH(r1, 1)                        @ r1<- field ref BBBB
3088    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3089    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3090    cmp     r0, #0                      @ is resolved entry null?
3091    beq     .LOP_SPUT_CHAR_resolve         @ yes, do resolve
3092.LOP_SPUT_CHAR_finish:   @ field ptr in r0
3093    mov     r2, rINST, lsr #8           @ r2<- AA
3094    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3095    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3096    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3097    @ no-op                             @ releasing store
3098    str     r1, [r0, #offStaticField_value] @ field<- vAA
3099    GOTO_OPCODE(ip)                     @ jump to next instruction
3100
3101
3102/* ------------------------------ */
3103    .balign 64
3104.L_OP_SPUT_SHORT: /* 0x6d */
3105/* File: armv5te/OP_SPUT_SHORT.S */
3106/* File: armv5te/OP_SPUT.S */
3107    /*
3108     * General 32-bit SPUT handler.
3109     *
3110     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3111     */
3112    /* op vAA, field@BBBB */
3113    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
3114    FETCH(r1, 1)                        @ r1<- field ref BBBB
3115    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3116    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3117    cmp     r0, #0                      @ is resolved entry null?
3118    beq     .LOP_SPUT_SHORT_resolve         @ yes, do resolve
3119.LOP_SPUT_SHORT_finish:   @ field ptr in r0
3120    mov     r2, rINST, lsr #8           @ r2<- AA
3121    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3122    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3123    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3124    @ no-op                             @ releasing store
3125    str     r1, [r0, #offStaticField_value] @ field<- vAA
3126    GOTO_OPCODE(ip)                     @ jump to next instruction
3127
3128
3129/* ------------------------------ */
3130    .balign 64
3131.L_OP_INVOKE_VIRTUAL: /* 0x6e */
3132/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3133    /*
3134     * Handle a virtual method call.
3135     *
3136     * for: invoke-virtual, invoke-virtual/range
3137     */
3138    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3139    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3140    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3141    FETCH(r1, 1)                        @ r1<- BBBB
3142    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3143    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3144    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3145    .if     (!0)
3146    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3147    .endif
3148    cmp     r0, #0                      @ already resolved?
3149    EXPORT_PC()                         @ must export for invoke
3150    bne     .LOP_INVOKE_VIRTUAL_continue        @ yes, continue on
3151    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
3152    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3153    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3154    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3155    cmp     r0, #0                      @ got null?
3156    bne     .LOP_INVOKE_VIRTUAL_continue        @ no, continue
3157    b       common_exceptionThrown      @ yes, handle exception
3158
3159/* ------------------------------ */
3160    .balign 64
3161.L_OP_INVOKE_SUPER: /* 0x6f */
3162/* File: armv5te/OP_INVOKE_SUPER.S */
3163    /*
3164     * Handle a "super" method call.
3165     *
3166     * for: invoke-super, invoke-super/range
3167     */
3168    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3169    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3170    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3171    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3172    .if     (!0)
3173    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3174    .endif
3175    FETCH(r1, 1)                        @ r1<- BBBB
3176    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3177    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3178    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3179    cmp     r2, #0                      @ null "this"?
3180    ldr     r9, [rSELF, #offThread_method] @ r9<- current method
3181    beq     common_errNullObject        @ null "this", throw exception
3182    cmp     r0, #0                      @ already resolved?
3183    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
3184    EXPORT_PC()                         @ must export for invoke
3185    bne     .LOP_INVOKE_SUPER_continue        @ resolved, continue on
3186    b       .LOP_INVOKE_SUPER_resolve         @ do resolve now
3187
3188/* ------------------------------ */
3189    .balign 64
3190.L_OP_INVOKE_DIRECT: /* 0x70 */
3191/* File: armv5te/OP_INVOKE_DIRECT.S */
3192    /*
3193     * Handle a direct method call.
3194     *
3195     * (We could defer the "is 'this' pointer null" test to the common
3196     * method invocation code, and use a flag to indicate that static
3197     * calls don't count.  If we do this as part of copying the arguments
3198     * out we could avoiding loading the first arg twice.)
3199     *
3200     * for: invoke-direct, invoke-direct/range
3201     */
3202    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3203    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3204    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3205    FETCH(r1, 1)                        @ r1<- BBBB
3206    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3207    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3208    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3209    .if     (!0)
3210    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3211    .endif
3212    cmp     r0, #0                      @ already resolved?
3213    EXPORT_PC()                         @ must export for invoke
3214    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3215    beq     .LOP_INVOKE_DIRECT_resolve         @ not resolved, do it now
3216.LOP_INVOKE_DIRECT_finish:
3217    cmp     r2, #0                      @ null "this" ref?
3218    bne     common_invokeMethodNoRange   @ no, continue on
3219    b       common_errNullObject        @ yes, throw exception
3220
3221/* ------------------------------ */
3222    .balign 64
3223.L_OP_INVOKE_STATIC: /* 0x71 */
3224/* File: armv5te/OP_INVOKE_STATIC.S */
3225    /*
3226     * Handle a static method call.
3227     *
3228     * for: invoke-static, invoke-static/range
3229     */
3230    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3231    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3232    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3233    FETCH(r1, 1)                        @ r1<- BBBB
3234    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3235    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3236    cmp     r0, #0                      @ already resolved?
3237    EXPORT_PC()                         @ must export for invoke
3238    bne     common_invokeMethodNoRange @ yes, continue on
32390:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
3240    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3241    mov     r2, #METHOD_STATIC          @ resolver method type
3242    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3243    cmp     r0, #0                      @ got null?
3244    bne     common_invokeMethodNoRange @ no, continue
3245    b       common_exceptionThrown      @ yes, handle exception
3246
3247/* ------------------------------ */
3248    .balign 64
3249.L_OP_INVOKE_INTERFACE: /* 0x72 */
3250/* File: armv5te/OP_INVOKE_INTERFACE.S */
3251    /*
3252     * Handle an interface method call.
3253     *
3254     * for: invoke-interface, invoke-interface/range
3255     */
3256    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3257    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3258    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3259    FETCH(r1, 1)                        @ r1<- BBBB
3260    .if     (!0)
3261    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3262    .endif
3263    EXPORT_PC()                         @ must export for invoke
3264    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
3265    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- methodClassDex
3266    cmp     r0, #0                      @ null obj?
3267    ldr     r2, [rSELF, #offThread_method]  @ r2<- method
3268    beq     common_errNullObject        @ yes, fail
3269    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
3270    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3271    cmp     r0, #0                      @ failed?
3272    beq     common_exceptionThrown      @ yes, handle exception
3273    b       common_invokeMethodNoRange @ jump to common handler
3274
3275/* ------------------------------ */
3276    .balign 64
3277.L_OP_UNUSED_73: /* 0x73 */
3278/* File: armv5te/OP_UNUSED_73.S */
3279/* File: armv5te/unused.S */
3280    bl      common_abort
3281
3282
3283/* ------------------------------ */
3284    .balign 64
3285.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
3286/* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */
3287/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3288    /*
3289     * Handle a virtual method call.
3290     *
3291     * for: invoke-virtual, invoke-virtual/range
3292     */
3293    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3294    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3295    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3296    FETCH(r1, 1)                        @ r1<- BBBB
3297    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3298    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3299    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3300    .if     (!1)
3301    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3302    .endif
3303    cmp     r0, #0                      @ already resolved?
3304    EXPORT_PC()                         @ must export for invoke
3305    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ yes, continue on
3306    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
3307    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3308    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3309    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3310    cmp     r0, #0                      @ got null?
3311    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ no, continue
3312    b       common_exceptionThrown      @ yes, handle exception
3313
3314
3315/* ------------------------------ */
3316    .balign 64
3317.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */
3318/* File: armv5te/OP_INVOKE_SUPER_RANGE.S */
3319/* File: armv5te/OP_INVOKE_SUPER.S */
3320    /*
3321     * Handle a "super" method call.
3322     *
3323     * for: invoke-super, invoke-super/range
3324     */
3325    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3326    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3327    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3328    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3329    .if     (!1)
3330    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3331    .endif
3332    FETCH(r1, 1)                        @ r1<- BBBB
3333    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3334    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3335    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3336    cmp     r2, #0                      @ null "this"?
3337    ldr     r9, [rSELF, #offThread_method] @ r9<- current method
3338    beq     common_errNullObject        @ null "this", throw exception
3339    cmp     r0, #0                      @ already resolved?
3340    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
3341    EXPORT_PC()                         @ must export for invoke
3342    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ resolved, continue on
3343    b       .LOP_INVOKE_SUPER_RANGE_resolve         @ do resolve now
3344
3345
3346/* ------------------------------ */
3347    .balign 64
3348.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
3349/* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */
3350/* File: armv5te/OP_INVOKE_DIRECT.S */
3351    /*
3352     * Handle a direct method call.
3353     *
3354     * (We could defer the "is 'this' pointer null" test to the common
3355     * method invocation code, and use a flag to indicate that static
3356     * calls don't count.  If we do this as part of copying the arguments
3357     * out we could avoiding loading the first arg twice.)
3358     *
3359     * for: invoke-direct, invoke-direct/range
3360     */
3361    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3362    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3363    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3364    FETCH(r1, 1)                        @ r1<- BBBB
3365    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3366    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3367    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3368    .if     (!1)
3369    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3370    .endif
3371    cmp     r0, #0                      @ already resolved?
3372    EXPORT_PC()                         @ must export for invoke
3373    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3374    beq     .LOP_INVOKE_DIRECT_RANGE_resolve         @ not resolved, do it now
3375.LOP_INVOKE_DIRECT_RANGE_finish:
3376    cmp     r2, #0                      @ null "this" ref?
3377    bne     common_invokeMethodRange   @ no, continue on
3378    b       common_errNullObject        @ yes, throw exception
3379
3380
3381/* ------------------------------ */
3382    .balign 64
3383.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */
3384/* File: armv5te/OP_INVOKE_STATIC_RANGE.S */
3385/* File: armv5te/OP_INVOKE_STATIC.S */
3386    /*
3387     * Handle a static method call.
3388     *
3389     * for: invoke-static, invoke-static/range
3390     */
3391    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3392    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3393    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3394    FETCH(r1, 1)                        @ r1<- BBBB
3395    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3396    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3397    cmp     r0, #0                      @ already resolved?
3398    EXPORT_PC()                         @ must export for invoke
3399    bne     common_invokeMethodRange @ yes, continue on
34000:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
3401    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3402    mov     r2, #METHOD_STATIC          @ resolver method type
3403    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3404    cmp     r0, #0                      @ got null?
3405    bne     common_invokeMethodRange @ no, continue
3406    b       common_exceptionThrown      @ yes, handle exception
3407
3408
3409/* ------------------------------ */
3410    .balign 64
3411.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
3412/* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */
3413/* File: armv5te/OP_INVOKE_INTERFACE.S */
3414    /*
3415     * Handle an interface method call.
3416     *
3417     * for: invoke-interface, invoke-interface/range
3418     */
3419    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3420    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3421    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3422    FETCH(r1, 1)                        @ r1<- BBBB
3423    .if     (!1)
3424    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3425    .endif
3426    EXPORT_PC()                         @ must export for invoke
3427    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
3428    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- methodClassDex
3429    cmp     r0, #0                      @ null obj?
3430    ldr     r2, [rSELF, #offThread_method]  @ r2<- method
3431    beq     common_errNullObject        @ yes, fail
3432    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
3433    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3434    cmp     r0, #0                      @ failed?
3435    beq     common_exceptionThrown      @ yes, handle exception
3436    b       common_invokeMethodRange @ jump to common handler
3437
3438
3439/* ------------------------------ */
3440    .balign 64
3441.L_OP_UNUSED_79: /* 0x79 */
3442/* File: armv5te/OP_UNUSED_79.S */
3443/* File: armv5te/unused.S */
3444    bl      common_abort
3445
3446
3447/* ------------------------------ */
3448    .balign 64
3449.L_OP_UNUSED_7A: /* 0x7a */
3450/* File: armv5te/OP_UNUSED_7A.S */
3451/* File: armv5te/unused.S */
3452    bl      common_abort
3453
3454
3455/* ------------------------------ */
3456    .balign 64
3457.L_OP_NEG_INT: /* 0x7b */
3458/* File: armv5te/OP_NEG_INT.S */
3459/* File: armv5te/unop.S */
3460    /*
3461     * Generic 32-bit unary operation.  Provide an "instr" line that
3462     * specifies an instruction that performs "result = op r0".
3463     * This could be an ARM instruction or a function call.
3464     *
3465     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3466     *      int-to-byte, int-to-char, int-to-short
3467     */
3468    /* unop vA, vB */
3469    mov     r3, rINST, lsr #12          @ r3<- B
3470    mov     r9, rINST, lsr #8           @ r9<- A+
3471    GET_VREG(r0, r3)                    @ r0<- vB
3472    and     r9, r9, #15
3473                               @ optional op; may set condition codes
3474    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3475    rsb     r0, r0, #0                              @ r0<- op, r0-r3 changed
3476    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3477    SET_VREG(r0, r9)                    @ vAA<- r0
3478    GOTO_OPCODE(ip)                     @ jump to next instruction
3479    /* 9-10 instructions */
3480
3481
3482/* ------------------------------ */
3483    .balign 64
3484.L_OP_NOT_INT: /* 0x7c */
3485/* File: armv5te/OP_NOT_INT.S */
3486/* File: armv5te/unop.S */
3487    /*
3488     * Generic 32-bit unary operation.  Provide an "instr" line that
3489     * specifies an instruction that performs "result = op r0".
3490     * This could be an ARM instruction or a function call.
3491     *
3492     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3493     *      int-to-byte, int-to-char, int-to-short
3494     */
3495    /* unop vA, vB */
3496    mov     r3, rINST, lsr #12          @ r3<- B
3497    mov     r9, rINST, lsr #8           @ r9<- A+
3498    GET_VREG(r0, r3)                    @ r0<- vB
3499    and     r9, r9, #15
3500                               @ optional op; may set condition codes
3501    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3502    mvn     r0, r0                              @ r0<- op, r0-r3 changed
3503    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3504    SET_VREG(r0, r9)                    @ vAA<- r0
3505    GOTO_OPCODE(ip)                     @ jump to next instruction
3506    /* 9-10 instructions */
3507
3508
3509/* ------------------------------ */
3510    .balign 64
3511.L_OP_NEG_LONG: /* 0x7d */
3512/* File: armv5te/OP_NEG_LONG.S */
3513/* File: armv5te/unopWide.S */
3514    /*
3515     * Generic 64-bit unary operation.  Provide an "instr" line that
3516     * specifies an instruction that performs "result = op r0/r1".
3517     * This could be an ARM instruction or a function call.
3518     *
3519     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3520     */
3521    /* unop vA, vB */
3522    mov     r9, rINST, lsr #8           @ r9<- A+
3523    mov     r3, rINST, lsr #12          @ r3<- B
3524    and     r9, r9, #15
3525    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3526    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3527    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3528    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3529    rsbs    r0, r0, #0                           @ optional op; may set condition codes
3530    rsc     r1, r1, #0                              @ r0/r1<- op, r2-r3 changed
3531    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3532    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3533    GOTO_OPCODE(ip)                     @ jump to next instruction
3534    /* 12-13 instructions */
3535
3536
3537/* ------------------------------ */
3538    .balign 64
3539.L_OP_NOT_LONG: /* 0x7e */
3540/* File: armv5te/OP_NOT_LONG.S */
3541/* File: armv5te/unopWide.S */
3542    /*
3543     * Generic 64-bit unary operation.  Provide an "instr" line that
3544     * specifies an instruction that performs "result = op r0/r1".
3545     * This could be an ARM instruction or a function call.
3546     *
3547     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3548     */
3549    /* unop vA, vB */
3550    mov     r9, rINST, lsr #8           @ r9<- A+
3551    mov     r3, rINST, lsr #12          @ r3<- B
3552    and     r9, r9, #15
3553    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3554    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3555    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3556    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3557    mvn     r0, r0                           @ optional op; may set condition codes
3558    mvn     r1, r1                              @ r0/r1<- op, r2-r3 changed
3559    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3560    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3561    GOTO_OPCODE(ip)                     @ jump to next instruction
3562    /* 12-13 instructions */
3563
3564
3565/* ------------------------------ */
3566    .balign 64
3567.L_OP_NEG_FLOAT: /* 0x7f */
3568/* File: armv5te/OP_NEG_FLOAT.S */
3569/* File: armv5te/unop.S */
3570    /*
3571     * Generic 32-bit unary operation.  Provide an "instr" line that
3572     * specifies an instruction that performs "result = op r0".
3573     * This could be an ARM instruction or a function call.
3574     *
3575     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3576     *      int-to-byte, int-to-char, int-to-short
3577     */
3578    /* unop vA, vB */
3579    mov     r3, rINST, lsr #12          @ r3<- B
3580    mov     r9, rINST, lsr #8           @ r9<- A+
3581    GET_VREG(r0, r3)                    @ r0<- vB
3582    and     r9, r9, #15
3583                               @ optional op; may set condition codes
3584    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3585    add     r0, r0, #0x80000000                              @ r0<- op, r0-r3 changed
3586    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3587    SET_VREG(r0, r9)                    @ vAA<- r0
3588    GOTO_OPCODE(ip)                     @ jump to next instruction
3589    /* 9-10 instructions */
3590
3591
3592/* ------------------------------ */
3593    .balign 64
3594.L_OP_NEG_DOUBLE: /* 0x80 */
3595/* File: armv5te/OP_NEG_DOUBLE.S */
3596/* File: armv5te/unopWide.S */
3597    /*
3598     * Generic 64-bit unary operation.  Provide an "instr" line that
3599     * specifies an instruction that performs "result = op r0/r1".
3600     * This could be an ARM instruction or a function call.
3601     *
3602     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3603     */
3604    /* unop vA, vB */
3605    mov     r9, rINST, lsr #8           @ r9<- A+
3606    mov     r3, rINST, lsr #12          @ r3<- B
3607    and     r9, r9, #15
3608    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3609    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3610    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3611    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3612                               @ optional op; may set condition codes
3613    add     r1, r1, #0x80000000                              @ r0/r1<- op, r2-r3 changed
3614    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3615    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3616    GOTO_OPCODE(ip)                     @ jump to next instruction
3617    /* 12-13 instructions */
3618
3619
3620/* ------------------------------ */
3621    .balign 64
3622.L_OP_INT_TO_LONG: /* 0x81 */
3623/* File: armv5te/OP_INT_TO_LONG.S */
3624/* File: armv5te/unopWider.S */
3625    /*
3626     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3627     * that specifies an instruction that performs "result = op r0", where
3628     * "result" is a 64-bit quantity in r0/r1.
3629     *
3630     * For: int-to-long, int-to-double, float-to-long, float-to-double
3631     */
3632    /* unop vA, vB */
3633    mov     r9, rINST, lsr #8           @ r9<- A+
3634    mov     r3, rINST, lsr #12          @ r3<- B
3635    and     r9, r9, #15
3636    GET_VREG(r0, r3)                    @ r0<- vB
3637    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3638                               @ optional op; may set condition codes
3639    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3640    mov     r1, r0, asr #31                              @ r0<- op, r0-r3 changed
3641    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3642    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3643    GOTO_OPCODE(ip)                     @ jump to next instruction
3644    /* 10-11 instructions */
3645
3646
3647/* ------------------------------ */
3648    .balign 64
3649.L_OP_INT_TO_FLOAT: /* 0x82 */
3650/* File: arm-vfp/OP_INT_TO_FLOAT.S */
3651/* File: arm-vfp/funop.S */
3652    /*
3653     * Generic 32-bit unary floating-point operation.  Provide an "instr"
3654     * line that specifies an instruction that performs "s1 = op s0".
3655     *
3656     * for: int-to-float, float-to-int
3657     */
3658    /* unop vA, vB */
3659    mov     r3, rINST, lsr #12          @ r3<- B
3660    mov     r9, rINST, lsr #8           @ r9<- A+
3661    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3662    flds    s0, [r3]                    @ s0<- vB
3663    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3664    and     r9, r9, #15                 @ r9<- A
3665    fsitos  s1, s0                              @ s1<- op
3666    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3667    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3668    fsts    s1, [r9]                    @ vA<- s1
3669    GOTO_OPCODE(ip)                     @ jump to next instruction
3670
3671
3672/* ------------------------------ */
3673    .balign 64
3674.L_OP_INT_TO_DOUBLE: /* 0x83 */
3675/* File: arm-vfp/OP_INT_TO_DOUBLE.S */
3676/* File: arm-vfp/funopWider.S */
3677    /*
3678     * Generic 32bit-to-64bit floating point unary operation.  Provide an
3679     * "instr" line that specifies an instruction that performs "d0 = op s0".
3680     *
3681     * For: int-to-double, float-to-double
3682     */
3683    /* unop vA, vB */
3684    mov     r3, rINST, lsr #12          @ r3<- B
3685    mov     r9, rINST, lsr #8           @ r9<- A+
3686    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3687    flds    s0, [r3]                    @ s0<- vB
3688    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3689    and     r9, r9, #15                 @ r9<- A
3690    fsitod  d0, s0                              @ d0<- op
3691    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3692    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3693    fstd    d0, [r9]                    @ vA<- d0
3694    GOTO_OPCODE(ip)                     @ jump to next instruction
3695
3696
3697/* ------------------------------ */
3698    .balign 64
3699.L_OP_LONG_TO_INT: /* 0x84 */
3700/* File: armv5te/OP_LONG_TO_INT.S */
3701/* we ignore the high word, making this equivalent to a 32-bit reg move */
3702/* File: armv5te/OP_MOVE.S */
3703    /* for move, move-object, long-to-int */
3704    /* op vA, vB */
3705    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
3706    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
3707    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3708    GET_VREG(r2, r1)                    @ r2<- fp[B]
3709    and     r0, r0, #15
3710    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
3711    SET_VREG(r2, r0)                    @ fp[A]<- r2
3712    GOTO_OPCODE(ip)                     @ execute next instruction
3713
3714
3715/* ------------------------------ */
3716    .balign 64
3717.L_OP_LONG_TO_FLOAT: /* 0x85 */
3718/* File: armv5te/OP_LONG_TO_FLOAT.S */
3719/* File: armv5te/unopNarrower.S */
3720    /*
3721     * Generic 64bit-to-32bit unary operation.  Provide an "instr" line
3722     * that specifies an instruction that performs "result = op r0/r1", where
3723     * "result" is a 32-bit quantity in r0.
3724     *
3725     * For: long-to-float, double-to-int, double-to-float
3726     *
3727     * (This would work for long-to-int, but that instruction is actually
3728     * an exact match for OP_MOVE.)
3729     */
3730    /* unop vA, vB */
3731    mov     r3, rINST, lsr #12          @ r3<- B
3732    mov     r9, rINST, lsr #8           @ r9<- A+
3733    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3734    and     r9, r9, #15
3735    ldmia   r3, {r0-r1}                 @ r0/r1<- vB/vB+1
3736    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3737                               @ optional op; may set condition codes
3738    bl      __aeabi_l2f                              @ r0<- op, r0-r3 changed
3739    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3740    SET_VREG(r0, r9)                    @ vA<- r0
3741    GOTO_OPCODE(ip)                     @ jump to next instruction
3742    /* 10-11 instructions */
3743
3744
3745/* ------------------------------ */
3746    .balign 64
3747.L_OP_LONG_TO_DOUBLE: /* 0x86 */
3748/* File: armv5te/OP_LONG_TO_DOUBLE.S */
3749/* File: armv5te/unopWide.S */
3750    /*
3751     * Generic 64-bit unary operation.  Provide an "instr" line that
3752     * specifies an instruction that performs "result = op r0/r1".
3753     * This could be an ARM instruction or a function call.
3754     *
3755     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3756     */
3757    /* unop vA, vB */
3758    mov     r9, rINST, lsr #8           @ r9<- A+
3759    mov     r3, rINST, lsr #12          @ r3<- B
3760    and     r9, r9, #15
3761    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3762    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3763    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3764    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3765                               @ optional op; may set condition codes
3766    bl      __aeabi_l2d                              @ r0/r1<- op, r2-r3 changed
3767    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3768    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3769    GOTO_OPCODE(ip)                     @ jump to next instruction
3770    /* 12-13 instructions */
3771
3772
3773/* ------------------------------ */
3774    .balign 64
3775.L_OP_FLOAT_TO_INT: /* 0x87 */
3776/* File: arm-vfp/OP_FLOAT_TO_INT.S */
3777/* File: arm-vfp/funop.S */
3778    /*
3779     * Generic 32-bit unary floating-point operation.  Provide an "instr"
3780     * line that specifies an instruction that performs "s1 = op s0".
3781     *
3782     * for: int-to-float, float-to-int
3783     */
3784    /* unop vA, vB */
3785    mov     r3, rINST, lsr #12          @ r3<- B
3786    mov     r9, rINST, lsr #8           @ r9<- A+
3787    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3788    flds    s0, [r3]                    @ s0<- vB
3789    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3790    and     r9, r9, #15                 @ r9<- A
3791    ftosizs s1, s0                              @ s1<- op
3792    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3793    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3794    fsts    s1, [r9]                    @ vA<- s1
3795    GOTO_OPCODE(ip)                     @ jump to next instruction
3796
3797
3798/* ------------------------------ */
3799    .balign 64
3800.L_OP_FLOAT_TO_LONG: /* 0x88 */
3801/* File: armv5te/OP_FLOAT_TO_LONG.S */
3802@include "armv5te/unopWider.S" {"instr":"bl      __aeabi_f2lz"}
3803/* File: armv5te/unopWider.S */
3804    /*
3805     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3806     * that specifies an instruction that performs "result = op r0", where
3807     * "result" is a 64-bit quantity in r0/r1.
3808     *
3809     * For: int-to-long, int-to-double, float-to-long, float-to-double
3810     */
3811    /* unop vA, vB */
3812    mov     r9, rINST, lsr #8           @ r9<- A+
3813    mov     r3, rINST, lsr #12          @ r3<- B
3814    and     r9, r9, #15
3815    GET_VREG(r0, r3)                    @ r0<- vB
3816    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3817                               @ optional op; may set condition codes
3818    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3819    bl      f2l_doconv                              @ r0<- op, r0-r3 changed
3820    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3821    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3822    GOTO_OPCODE(ip)                     @ jump to next instruction
3823    /* 10-11 instructions */
3824
3825
3826
3827/* ------------------------------ */
3828    .balign 64
3829.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */
3830/* File: arm-vfp/OP_FLOAT_TO_DOUBLE.S */
3831/* File: arm-vfp/funopWider.S */
3832    /*
3833     * Generic 32bit-to-64bit floating point unary operation.  Provide an
3834     * "instr" line that specifies an instruction that performs "d0 = op s0".
3835     *
3836     * For: int-to-double, float-to-double
3837     */
3838    /* unop vA, vB */
3839    mov     r3, rINST, lsr #12          @ r3<- B
3840    mov     r9, rINST, lsr #8           @ r9<- A+
3841    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3842    flds    s0, [r3]                    @ s0<- vB
3843    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3844    and     r9, r9, #15                 @ r9<- A
3845    fcvtds  d0, s0                              @ d0<- op
3846    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3847    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3848    fstd    d0, [r9]                    @ vA<- d0
3849    GOTO_OPCODE(ip)                     @ jump to next instruction
3850
3851
3852/* ------------------------------ */
3853    .balign 64
3854.L_OP_DOUBLE_TO_INT: /* 0x8a */
3855/* File: arm-vfp/OP_DOUBLE_TO_INT.S */
3856/* File: arm-vfp/funopNarrower.S */
3857    /*
3858     * Generic 64bit-to-32bit unary floating point operation.  Provide an
3859     * "instr" line that specifies an instruction that performs "s0 = op d0".
3860     *
3861     * For: double-to-int, double-to-float
3862     */
3863    /* unop vA, vB */
3864    mov     r3, rINST, lsr #12          @ r3<- B
3865    mov     r9, rINST, lsr #8           @ r9<- A+
3866    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3867    fldd    d0, [r3]                    @ d0<- vB
3868    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3869    and     r9, r9, #15                 @ r9<- A
3870    ftosizd  s0, d0                              @ s0<- op
3871    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3872    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3873    fsts    s0, [r9]                    @ vA<- s0
3874    GOTO_OPCODE(ip)                     @ jump to next instruction
3875
3876
3877/* ------------------------------ */
3878    .balign 64
3879.L_OP_DOUBLE_TO_LONG: /* 0x8b */
3880/* File: armv5te/OP_DOUBLE_TO_LONG.S */
3881@include "armv5te/unopWide.S" {"instr":"bl      __aeabi_d2lz"}
3882/* File: armv5te/unopWide.S */
3883    /*
3884     * Generic 64-bit unary operation.  Provide an "instr" line that
3885     * specifies an instruction that performs "result = op r0/r1".
3886     * This could be an ARM instruction or a function call.
3887     *
3888     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3889     */
3890    /* unop vA, vB */
3891    mov     r9, rINST, lsr #8           @ r9<- A+
3892    mov     r3, rINST, lsr #12          @ r3<- B
3893    and     r9, r9, #15
3894    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3895    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3896    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3897    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3898                               @ optional op; may set condition codes
3899    bl      d2l_doconv                              @ r0/r1<- op, r2-r3 changed
3900    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3901    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3902    GOTO_OPCODE(ip)                     @ jump to next instruction
3903    /* 12-13 instructions */
3904
3905
3906
3907/* ------------------------------ */
3908    .balign 64
3909.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */
3910/* File: arm-vfp/OP_DOUBLE_TO_FLOAT.S */
3911/* File: arm-vfp/funopNarrower.S */
3912    /*
3913     * Generic 64bit-to-32bit unary floating point operation.  Provide an
3914     * "instr" line that specifies an instruction that performs "s0 = op d0".
3915     *
3916     * For: double-to-int, double-to-float
3917     */
3918    /* unop vA, vB */
3919    mov     r3, rINST, lsr #12          @ r3<- B
3920    mov     r9, rINST, lsr #8           @ r9<- A+
3921    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3922    fldd    d0, [r3]                    @ d0<- vB
3923    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3924    and     r9, r9, #15                 @ r9<- A
3925    fcvtsd  s0, d0                              @ s0<- op
3926    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3927    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3928    fsts    s0, [r9]                    @ vA<- s0
3929    GOTO_OPCODE(ip)                     @ jump to next instruction
3930
3931
3932/* ------------------------------ */
3933    .balign 64
3934.L_OP_INT_TO_BYTE: /* 0x8d */
3935/* File: armv5te/OP_INT_TO_BYTE.S */
3936/* File: armv5te/unop.S */
3937    /*
3938     * Generic 32-bit unary operation.  Provide an "instr" line that
3939     * specifies an instruction that performs "result = op r0".
3940     * This could be an ARM instruction or a function call.
3941     *
3942     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3943     *      int-to-byte, int-to-char, int-to-short
3944     */
3945    /* unop vA, vB */
3946    mov     r3, rINST, lsr #12          @ r3<- B
3947    mov     r9, rINST, lsr #8           @ r9<- A+
3948    GET_VREG(r0, r3)                    @ r0<- vB
3949    and     r9, r9, #15
3950    mov     r0, r0, asl #24                           @ optional op; may set condition codes
3951    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3952    mov     r0, r0, asr #24                              @ r0<- op, r0-r3 changed
3953    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3954    SET_VREG(r0, r9)                    @ vAA<- r0
3955    GOTO_OPCODE(ip)                     @ jump to next instruction
3956    /* 9-10 instructions */
3957
3958
3959/* ------------------------------ */
3960    .balign 64
3961.L_OP_INT_TO_CHAR: /* 0x8e */
3962/* File: armv5te/OP_INT_TO_CHAR.S */
3963/* File: armv5te/unop.S */
3964    /*
3965     * Generic 32-bit unary operation.  Provide an "instr" line that
3966     * specifies an instruction that performs "result = op r0".
3967     * This could be an ARM instruction or a function call.
3968     *
3969     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3970     *      int-to-byte, int-to-char, int-to-short
3971     */
3972    /* unop vA, vB */
3973    mov     r3, rINST, lsr #12          @ r3<- B
3974    mov     r9, rINST, lsr #8           @ r9<- A+
3975    GET_VREG(r0, r3)                    @ r0<- vB
3976    and     r9, r9, #15
3977    mov     r0, r0, asl #16                           @ optional op; may set condition codes
3978    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3979    mov     r0, r0, lsr #16                              @ r0<- op, r0-r3 changed
3980    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3981    SET_VREG(r0, r9)                    @ vAA<- r0
3982    GOTO_OPCODE(ip)                     @ jump to next instruction
3983    /* 9-10 instructions */
3984
3985
3986/* ------------------------------ */
3987    .balign 64
3988.L_OP_INT_TO_SHORT: /* 0x8f */
3989/* File: armv5te/OP_INT_TO_SHORT.S */
3990/* File: armv5te/unop.S */
3991    /*
3992     * Generic 32-bit unary operation.  Provide an "instr" line that
3993     * specifies an instruction that performs "result = op r0".
3994     * This could be an ARM instruction or a function call.
3995     *
3996     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3997     *      int-to-byte, int-to-char, int-to-short
3998     */
3999    /* unop vA, vB */
4000    mov     r3, rINST, lsr #12          @ r3<- B
4001    mov     r9, rINST, lsr #8           @ r9<- A+
4002    GET_VREG(r0, r3)                    @ r0<- vB
4003    and     r9, r9, #15
4004    mov     r0, r0, asl #16                           @ optional op; may set condition codes
4005    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
4006    mov     r0, r0, asr #16                              @ r0<- op, r0-r3 changed
4007    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4008    SET_VREG(r0, r9)                    @ vAA<- r0
4009    GOTO_OPCODE(ip)                     @ jump to next instruction
4010    /* 9-10 instructions */
4011
4012
4013/* ------------------------------ */
4014    .balign 64
4015.L_OP_ADD_INT: /* 0x90 */
4016/* File: armv5te/OP_ADD_INT.S */
4017/* File: armv5te/binop.S */
4018    /*
4019     * Generic 32-bit binary operation.  Provide an "instr" line that
4020     * specifies an instruction that performs "result = r0 op r1".
4021     * This could be an ARM instruction or a function call.  (If the result
4022     * comes back in a register other than r0, you can override "result".)
4023     *
4024     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4025     * vCC (r1).  Useful for integer division and modulus.  Note that we
4026     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4027     * handles it correctly.
4028     *
4029     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4030     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4031     *      mul-float, div-float, rem-float
4032     */
4033    /* binop vAA, vBB, vCC */
4034    FETCH(r0, 1)                        @ r0<- CCBB
4035    mov     r9, rINST, lsr #8           @ r9<- AA
4036    mov     r3, r0, lsr #8              @ r3<- CC
4037    and     r2, r0, #255                @ r2<- BB
4038    GET_VREG(r1, r3)                    @ r1<- vCC
4039    GET_VREG(r0, r2)                    @ r0<- vBB
4040    .if 0
4041    cmp     r1, #0                      @ is second operand zero?
4042    beq     common_errDivideByZero
4043    .endif
4044
4045    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4046                               @ optional op; may set condition codes
4047    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
4048    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4049    SET_VREG(r0, r9)               @ vAA<- r0
4050    GOTO_OPCODE(ip)                     @ jump to next instruction
4051    /* 11-14 instructions */
4052
4053
4054/* ------------------------------ */
4055    .balign 64
4056.L_OP_SUB_INT: /* 0x91 */
4057/* File: armv5te/OP_SUB_INT.S */
4058/* File: armv5te/binop.S */
4059    /*
4060     * Generic 32-bit binary operation.  Provide an "instr" line that
4061     * specifies an instruction that performs "result = r0 op r1".
4062     * This could be an ARM instruction or a function call.  (If the result
4063     * comes back in a register other than r0, you can override "result".)
4064     *
4065     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4066     * vCC (r1).  Useful for integer division and modulus.  Note that we
4067     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4068     * handles it correctly.
4069     *
4070     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4071     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4072     *      mul-float, div-float, rem-float
4073     */
4074    /* binop vAA, vBB, vCC */
4075    FETCH(r0, 1)                        @ r0<- CCBB
4076    mov     r9, rINST, lsr #8           @ r9<- AA
4077    mov     r3, r0, lsr #8              @ r3<- CC
4078    and     r2, r0, #255                @ r2<- BB
4079    GET_VREG(r1, r3)                    @ r1<- vCC
4080    GET_VREG(r0, r2)                    @ r0<- vBB
4081    .if 0
4082    cmp     r1, #0                      @ is second operand zero?
4083    beq     common_errDivideByZero
4084    .endif
4085
4086    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4087                               @ optional op; may set condition codes
4088    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
4089    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4090    SET_VREG(r0, r9)               @ vAA<- r0
4091    GOTO_OPCODE(ip)                     @ jump to next instruction
4092    /* 11-14 instructions */
4093
4094
4095/* ------------------------------ */
4096    .balign 64
4097.L_OP_MUL_INT: /* 0x92 */
4098/* File: armv5te/OP_MUL_INT.S */
4099/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
4100/* File: armv5te/binop.S */
4101    /*
4102     * Generic 32-bit binary operation.  Provide an "instr" line that
4103     * specifies an instruction that performs "result = r0 op r1".
4104     * This could be an ARM instruction or a function call.  (If the result
4105     * comes back in a register other than r0, you can override "result".)
4106     *
4107     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4108     * vCC (r1).  Useful for integer division and modulus.  Note that we
4109     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4110     * handles it correctly.
4111     *
4112     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4113     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4114     *      mul-float, div-float, rem-float
4115     */
4116    /* binop vAA, vBB, vCC */
4117    FETCH(r0, 1)                        @ r0<- CCBB
4118    mov     r9, rINST, lsr #8           @ r9<- AA
4119    mov     r3, r0, lsr #8              @ r3<- CC
4120    and     r2, r0, #255                @ r2<- BB
4121    GET_VREG(r1, r3)                    @ r1<- vCC
4122    GET_VREG(r0, r2)                    @ r0<- vBB
4123    .if 0
4124    cmp     r1, #0                      @ is second operand zero?
4125    beq     common_errDivideByZero
4126    .endif
4127
4128    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4129                               @ optional op; may set condition codes
4130    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
4131    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4132    SET_VREG(r0, r9)               @ vAA<- r0
4133    GOTO_OPCODE(ip)                     @ jump to next instruction
4134    /* 11-14 instructions */
4135
4136
4137/* ------------------------------ */
4138    .balign 64
4139.L_OP_DIV_INT: /* 0x93 */
4140/* File: armv5te/OP_DIV_INT.S */
4141/* File: armv5te/binop.S */
4142    /*
4143     * Generic 32-bit binary operation.  Provide an "instr" line that
4144     * specifies an instruction that performs "result = r0 op r1".
4145     * This could be an ARM instruction or a function call.  (If the result
4146     * comes back in a register other than r0, you can override "result".)
4147     *
4148     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4149     * vCC (r1).  Useful for integer division and modulus.  Note that we
4150     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4151     * handles it correctly.
4152     *
4153     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4154     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4155     *      mul-float, div-float, rem-float
4156     */
4157    /* binop vAA, vBB, vCC */
4158    FETCH(r0, 1)                        @ r0<- CCBB
4159    mov     r9, rINST, lsr #8           @ r9<- AA
4160    mov     r3, r0, lsr #8              @ r3<- CC
4161    and     r2, r0, #255                @ r2<- BB
4162    GET_VREG(r1, r3)                    @ r1<- vCC
4163    GET_VREG(r0, r2)                    @ r0<- vBB
4164    .if 1
4165    cmp     r1, #0                      @ is second operand zero?
4166    beq     common_errDivideByZero
4167    .endif
4168
4169    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4170                               @ optional op; may set condition codes
4171    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
4172    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4173    SET_VREG(r0, r9)               @ vAA<- r0
4174    GOTO_OPCODE(ip)                     @ jump to next instruction
4175    /* 11-14 instructions */
4176
4177
4178/* ------------------------------ */
4179    .balign 64
4180.L_OP_REM_INT: /* 0x94 */
4181/* File: armv5te/OP_REM_INT.S */
4182/* idivmod returns quotient in r0 and remainder in r1 */
4183/* File: armv5te/binop.S */
4184    /*
4185     * Generic 32-bit binary operation.  Provide an "instr" line that
4186     * specifies an instruction that performs "result = r0 op r1".
4187     * This could be an ARM instruction or a function call.  (If the result
4188     * comes back in a register other than r0, you can override "result".)
4189     *
4190     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4191     * vCC (r1).  Useful for integer division and modulus.  Note that we
4192     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4193     * handles it correctly.
4194     *
4195     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4196     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4197     *      mul-float, div-float, rem-float
4198     */
4199    /* binop vAA, vBB, vCC */
4200    FETCH(r0, 1)                        @ r0<- CCBB
4201    mov     r9, rINST, lsr #8           @ r9<- AA
4202    mov     r3, r0, lsr #8              @ r3<- CC
4203    and     r2, r0, #255                @ r2<- BB
4204    GET_VREG(r1, r3)                    @ r1<- vCC
4205    GET_VREG(r0, r2)                    @ r0<- vBB
4206    .if 1
4207    cmp     r1, #0                      @ is second operand zero?
4208    beq     common_errDivideByZero
4209    .endif
4210
4211    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4212                               @ optional op; may set condition codes
4213    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
4214    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4215    SET_VREG(r1, r9)               @ vAA<- r1
4216    GOTO_OPCODE(ip)                     @ jump to next instruction
4217    /* 11-14 instructions */
4218
4219
4220/* ------------------------------ */
4221    .balign 64
4222.L_OP_AND_INT: /* 0x95 */
4223/* File: armv5te/OP_AND_INT.S */
4224/* File: armv5te/binop.S */
4225    /*
4226     * Generic 32-bit binary operation.  Provide an "instr" line that
4227     * specifies an instruction that performs "result = r0 op r1".
4228     * This could be an ARM instruction or a function call.  (If the result
4229     * comes back in a register other than r0, you can override "result".)
4230     *
4231     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4232     * vCC (r1).  Useful for integer division and modulus.  Note that we
4233     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4234     * handles it correctly.
4235     *
4236     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4237     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4238     *      mul-float, div-float, rem-float
4239     */
4240    /* binop vAA, vBB, vCC */
4241    FETCH(r0, 1)                        @ r0<- CCBB
4242    mov     r9, rINST, lsr #8           @ r9<- AA
4243    mov     r3, r0, lsr #8              @ r3<- CC
4244    and     r2, r0, #255                @ r2<- BB
4245    GET_VREG(r1, r3)                    @ r1<- vCC
4246    GET_VREG(r0, r2)                    @ r0<- vBB
4247    .if 0
4248    cmp     r1, #0                      @ is second operand zero?
4249    beq     common_errDivideByZero
4250    .endif
4251
4252    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4253                               @ optional op; may set condition codes
4254    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
4255    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4256    SET_VREG(r0, r9)               @ vAA<- r0
4257    GOTO_OPCODE(ip)                     @ jump to next instruction
4258    /* 11-14 instructions */
4259
4260
4261/* ------------------------------ */
4262    .balign 64
4263.L_OP_OR_INT: /* 0x96 */
4264/* File: armv5te/OP_OR_INT.S */
4265/* File: armv5te/binop.S */
4266    /*
4267     * Generic 32-bit binary operation.  Provide an "instr" line that
4268     * specifies an instruction that performs "result = r0 op r1".
4269     * This could be an ARM instruction or a function call.  (If the result
4270     * comes back in a register other than r0, you can override "result".)
4271     *
4272     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4273     * vCC (r1).  Useful for integer division and modulus.  Note that we
4274     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4275     * handles it correctly.
4276     *
4277     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4278     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4279     *      mul-float, div-float, rem-float
4280     */
4281    /* binop vAA, vBB, vCC */
4282    FETCH(r0, 1)                        @ r0<- CCBB
4283    mov     r9, rINST, lsr #8           @ r9<- AA
4284    mov     r3, r0, lsr #8              @ r3<- CC
4285    and     r2, r0, #255                @ r2<- BB
4286    GET_VREG(r1, r3)                    @ r1<- vCC
4287    GET_VREG(r0, r2)                    @ r0<- vBB
4288    .if 0
4289    cmp     r1, #0                      @ is second operand zero?
4290    beq     common_errDivideByZero
4291    .endif
4292
4293    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4294                               @ optional op; may set condition codes
4295    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
4296    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4297    SET_VREG(r0, r9)               @ vAA<- r0
4298    GOTO_OPCODE(ip)                     @ jump to next instruction
4299    /* 11-14 instructions */
4300
4301
4302/* ------------------------------ */
4303    .balign 64
4304.L_OP_XOR_INT: /* 0x97 */
4305/* File: armv5te/OP_XOR_INT.S */
4306/* File: armv5te/binop.S */
4307    /*
4308     * Generic 32-bit binary operation.  Provide an "instr" line that
4309     * specifies an instruction that performs "result = r0 op r1".
4310     * This could be an ARM instruction or a function call.  (If the result
4311     * comes back in a register other than r0, you can override "result".)
4312     *
4313     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4314     * vCC (r1).  Useful for integer division and modulus.  Note that we
4315     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4316     * handles it correctly.
4317     *
4318     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4319     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4320     *      mul-float, div-float, rem-float
4321     */
4322    /* binop vAA, vBB, vCC */
4323    FETCH(r0, 1)                        @ r0<- CCBB
4324    mov     r9, rINST, lsr #8           @ r9<- AA
4325    mov     r3, r0, lsr #8              @ r3<- CC
4326    and     r2, r0, #255                @ r2<- BB
4327    GET_VREG(r1, r3)                    @ r1<- vCC
4328    GET_VREG(r0, r2)                    @ r0<- vBB
4329    .if 0
4330    cmp     r1, #0                      @ is second operand zero?
4331    beq     common_errDivideByZero
4332    .endif
4333
4334    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4335                               @ optional op; may set condition codes
4336    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
4337    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4338    SET_VREG(r0, r9)               @ vAA<- r0
4339    GOTO_OPCODE(ip)                     @ jump to next instruction
4340    /* 11-14 instructions */
4341
4342
4343/* ------------------------------ */
4344    .balign 64
4345.L_OP_SHL_INT: /* 0x98 */
4346/* File: armv5te/OP_SHL_INT.S */
4347/* File: armv5te/binop.S */
4348    /*
4349     * Generic 32-bit binary operation.  Provide an "instr" line that
4350     * specifies an instruction that performs "result = r0 op r1".
4351     * This could be an ARM instruction or a function call.  (If the result
4352     * comes back in a register other than r0, you can override "result".)
4353     *
4354     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4355     * vCC (r1).  Useful for integer division and modulus.  Note that we
4356     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4357     * handles it correctly.
4358     *
4359     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4360     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4361     *      mul-float, div-float, rem-float
4362     */
4363    /* binop vAA, vBB, vCC */
4364    FETCH(r0, 1)                        @ r0<- CCBB
4365    mov     r9, rINST, lsr #8           @ r9<- AA
4366    mov     r3, r0, lsr #8              @ r3<- CC
4367    and     r2, r0, #255                @ r2<- BB
4368    GET_VREG(r1, r3)                    @ r1<- vCC
4369    GET_VREG(r0, r2)                    @ r0<- vBB
4370    .if 0
4371    cmp     r1, #0                      @ is second operand zero?
4372    beq     common_errDivideByZero
4373    .endif
4374
4375    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4376    and     r1, r1, #31                           @ optional op; may set condition codes
4377    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
4378    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4379    SET_VREG(r0, r9)               @ vAA<- r0
4380    GOTO_OPCODE(ip)                     @ jump to next instruction
4381    /* 11-14 instructions */
4382
4383
4384/* ------------------------------ */
4385    .balign 64
4386.L_OP_SHR_INT: /* 0x99 */
4387/* File: armv5te/OP_SHR_INT.S */
4388/* File: armv5te/binop.S */
4389    /*
4390     * Generic 32-bit binary operation.  Provide an "instr" line that
4391     * specifies an instruction that performs "result = r0 op r1".
4392     * This could be an ARM instruction or a function call.  (If the result
4393     * comes back in a register other than r0, you can override "result".)
4394     *
4395     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4396     * vCC (r1).  Useful for integer division and modulus.  Note that we
4397     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4398     * handles it correctly.
4399     *
4400     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4401     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4402     *      mul-float, div-float, rem-float
4403     */
4404    /* binop vAA, vBB, vCC */
4405    FETCH(r0, 1)                        @ r0<- CCBB
4406    mov     r9, rINST, lsr #8           @ r9<- AA
4407    mov     r3, r0, lsr #8              @ r3<- CC
4408    and     r2, r0, #255                @ r2<- BB
4409    GET_VREG(r1, r3)                    @ r1<- vCC
4410    GET_VREG(r0, r2)                    @ r0<- vBB
4411    .if 0
4412    cmp     r1, #0                      @ is second operand zero?
4413    beq     common_errDivideByZero
4414    .endif
4415
4416    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4417    and     r1, r1, #31                           @ optional op; may set condition codes
4418    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
4419    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4420    SET_VREG(r0, r9)               @ vAA<- r0
4421    GOTO_OPCODE(ip)                     @ jump to next instruction
4422    /* 11-14 instructions */
4423
4424
4425/* ------------------------------ */
4426    .balign 64
4427.L_OP_USHR_INT: /* 0x9a */
4428/* File: armv5te/OP_USHR_INT.S */
4429/* File: armv5te/binop.S */
4430    /*
4431     * Generic 32-bit binary operation.  Provide an "instr" line that
4432     * specifies an instruction that performs "result = r0 op r1".
4433     * This could be an ARM instruction or a function call.  (If the result
4434     * comes back in a register other than r0, you can override "result".)
4435     *
4436     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4437     * vCC (r1).  Useful for integer division and modulus.  Note that we
4438     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4439     * handles it correctly.
4440     *
4441     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4442     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4443     *      mul-float, div-float, rem-float
4444     */
4445    /* binop vAA, vBB, vCC */
4446    FETCH(r0, 1)                        @ r0<- CCBB
4447    mov     r9, rINST, lsr #8           @ r9<- AA
4448    mov     r3, r0, lsr #8              @ r3<- CC
4449    and     r2, r0, #255                @ r2<- BB
4450    GET_VREG(r1, r3)                    @ r1<- vCC
4451    GET_VREG(r0, r2)                    @ r0<- vBB
4452    .if 0
4453    cmp     r1, #0                      @ is second operand zero?
4454    beq     common_errDivideByZero
4455    .endif
4456
4457    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4458    and     r1, r1, #31                           @ optional op; may set condition codes
4459    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
4460    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4461    SET_VREG(r0, r9)               @ vAA<- r0
4462    GOTO_OPCODE(ip)                     @ jump to next instruction
4463    /* 11-14 instructions */
4464
4465
4466/* ------------------------------ */
4467    .balign 64
4468.L_OP_ADD_LONG: /* 0x9b */
4469/* File: armv5te/OP_ADD_LONG.S */
4470/* File: armv5te/binopWide.S */
4471    /*
4472     * Generic 64-bit binary operation.  Provide an "instr" line that
4473     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4474     * This could be an ARM instruction or a function call.  (If the result
4475     * comes back in a register other than r0, you can override "result".)
4476     *
4477     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4478     * vCC (r1).  Useful for integer division and modulus.
4479     *
4480     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4481     *      xor-long, add-double, sub-double, mul-double, div-double,
4482     *      rem-double
4483     *
4484     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4485     */
4486    /* binop vAA, vBB, vCC */
4487    FETCH(r0, 1)                        @ r0<- CCBB
4488    mov     r9, rINST, lsr #8           @ r9<- AA
4489    and     r2, r0, #255                @ r2<- BB
4490    mov     r3, r0, lsr #8              @ r3<- CC
4491    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4492    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4493    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4494    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4495    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4496    .if 0
4497    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4498    beq     common_errDivideByZero
4499    .endif
4500    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4501
4502    adds    r0, r0, r2                           @ optional op; may set condition codes
4503    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
4504    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4505    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4506    GOTO_OPCODE(ip)                     @ jump to next instruction
4507    /* 14-17 instructions */
4508
4509
4510/* ------------------------------ */
4511    .balign 64
4512.L_OP_SUB_LONG: /* 0x9c */
4513/* File: armv5te/OP_SUB_LONG.S */
4514/* File: armv5te/binopWide.S */
4515    /*
4516     * Generic 64-bit binary operation.  Provide an "instr" line that
4517     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4518     * This could be an ARM instruction or a function call.  (If the result
4519     * comes back in a register other than r0, you can override "result".)
4520     *
4521     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4522     * vCC (r1).  Useful for integer division and modulus.
4523     *
4524     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4525     *      xor-long, add-double, sub-double, mul-double, div-double,
4526     *      rem-double
4527     *
4528     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4529     */
4530    /* binop vAA, vBB, vCC */
4531    FETCH(r0, 1)                        @ r0<- CCBB
4532    mov     r9, rINST, lsr #8           @ r9<- AA
4533    and     r2, r0, #255                @ r2<- BB
4534    mov     r3, r0, lsr #8              @ r3<- CC
4535    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4536    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4537    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4538    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4539    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4540    .if 0
4541    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4542    beq     common_errDivideByZero
4543    .endif
4544    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4545
4546    subs    r0, r0, r2                           @ optional op; may set condition codes
4547    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
4548    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4549    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4550    GOTO_OPCODE(ip)                     @ jump to next instruction
4551    /* 14-17 instructions */
4552
4553
4554/* ------------------------------ */
4555    .balign 64
4556.L_OP_MUL_LONG: /* 0x9d */
4557/* File: armv5te/OP_MUL_LONG.S */
4558    /*
4559     * Signed 64-bit integer multiply.
4560     *
4561     * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
4562     *        WX
4563     *      x YZ
4564     *  --------
4565     *     ZW ZX
4566     *  YW YX
4567     *
4568     * The low word of the result holds ZX, the high word holds
4569     * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
4570     * it doesn't fit in the low 64 bits.
4571     *
4572     * Unlike most ARM math operations, multiply instructions have
4573     * restrictions on using the same register more than once (Rd and Rm
4574     * cannot be the same).
4575     */
4576    /* mul-long vAA, vBB, vCC */
4577    FETCH(r0, 1)                        @ r0<- CCBB
4578    and     r2, r0, #255                @ r2<- BB
4579    mov     r3, r0, lsr #8              @ r3<- CC
4580    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4581    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4582    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4583    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4584    mul     ip, r2, r1                  @  ip<- ZxW
4585    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
4586    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
4587    mov     r0, rINST, lsr #8           @ r0<- AA
4588    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
4589    add     r0, rFP, r0, lsl #2         @ r0<- &fp[AA]
4590    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4591    b       .LOP_MUL_LONG_finish
4592
4593/* ------------------------------ */
4594    .balign 64
4595.L_OP_DIV_LONG: /* 0x9e */
4596/* File: armv5te/OP_DIV_LONG.S */
4597/* File: armv5te/binopWide.S */
4598    /*
4599     * Generic 64-bit binary operation.  Provide an "instr" line that
4600     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4601     * This could be an ARM instruction or a function call.  (If the result
4602     * comes back in a register other than r0, you can override "result".)
4603     *
4604     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4605     * vCC (r1).  Useful for integer division and modulus.
4606     *
4607     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4608     *      xor-long, add-double, sub-double, mul-double, div-double,
4609     *      rem-double
4610     *
4611     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4612     */
4613    /* binop vAA, vBB, vCC */
4614    FETCH(r0, 1)                        @ r0<- CCBB
4615    mov     r9, rINST, lsr #8           @ r9<- AA
4616    and     r2, r0, #255                @ r2<- BB
4617    mov     r3, r0, lsr #8              @ r3<- CC
4618    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4619    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4620    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4621    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4622    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4623    .if 1
4624    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4625    beq     common_errDivideByZero
4626    .endif
4627    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4628
4629                               @ optional op; may set condition codes
4630    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4631    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4632    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4633    GOTO_OPCODE(ip)                     @ jump to next instruction
4634    /* 14-17 instructions */
4635
4636
4637/* ------------------------------ */
4638    .balign 64
4639.L_OP_REM_LONG: /* 0x9f */
4640/* File: armv5te/OP_REM_LONG.S */
4641/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
4642/* File: armv5te/binopWide.S */
4643    /*
4644     * Generic 64-bit binary operation.  Provide an "instr" line that
4645     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4646     * This could be an ARM instruction or a function call.  (If the result
4647     * comes back in a register other than r0, you can override "result".)
4648     *
4649     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4650     * vCC (r1).  Useful for integer division and modulus.
4651     *
4652     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4653     *      xor-long, add-double, sub-double, mul-double, div-double,
4654     *      rem-double
4655     *
4656     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4657     */
4658    /* binop vAA, vBB, vCC */
4659    FETCH(r0, 1)                        @ r0<- CCBB
4660    mov     r9, rINST, lsr #8           @ r9<- AA
4661    and     r2, r0, #255                @ r2<- BB
4662    mov     r3, r0, lsr #8              @ r3<- CC
4663    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4664    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4665    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4666    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4667    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4668    .if 1
4669    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4670    beq     common_errDivideByZero
4671    .endif
4672    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4673
4674                               @ optional op; may set condition codes
4675    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4676    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4677    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
4678    GOTO_OPCODE(ip)                     @ jump to next instruction
4679    /* 14-17 instructions */
4680
4681
4682/* ------------------------------ */
4683    .balign 64
4684.L_OP_AND_LONG: /* 0xa0 */
4685/* File: armv5te/OP_AND_LONG.S */
4686/* File: armv5te/binopWide.S */
4687    /*
4688     * Generic 64-bit binary operation.  Provide an "instr" line that
4689     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4690     * This could be an ARM instruction or a function call.  (If the result
4691     * comes back in a register other than r0, you can override "result".)
4692     *
4693     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4694     * vCC (r1).  Useful for integer division and modulus.
4695     *
4696     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4697     *      xor-long, add-double, sub-double, mul-double, div-double,
4698     *      rem-double
4699     *
4700     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4701     */
4702    /* binop vAA, vBB, vCC */
4703    FETCH(r0, 1)                        @ r0<- CCBB
4704    mov     r9, rINST, lsr #8           @ r9<- AA
4705    and     r2, r0, #255                @ r2<- BB
4706    mov     r3, r0, lsr #8              @ r3<- CC
4707    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4708    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4709    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4710    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4711    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4712    .if 0
4713    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4714    beq     common_errDivideByZero
4715    .endif
4716    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4717
4718    and     r0, r0, r2                           @ optional op; may set condition codes
4719    and     r1, r1, r3                              @ result<- op, r0-r3 changed
4720    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4721    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4722    GOTO_OPCODE(ip)                     @ jump to next instruction
4723    /* 14-17 instructions */
4724
4725
4726/* ------------------------------ */
4727    .balign 64
4728.L_OP_OR_LONG: /* 0xa1 */
4729/* File: armv5te/OP_OR_LONG.S */
4730/* File: armv5te/binopWide.S */
4731    /*
4732     * Generic 64-bit binary operation.  Provide an "instr" line that
4733     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4734     * This could be an ARM instruction or a function call.  (If the result
4735     * comes back in a register other than r0, you can override "result".)
4736     *
4737     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4738     * vCC (r1).  Useful for integer division and modulus.
4739     *
4740     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4741     *      xor-long, add-double, sub-double, mul-double, div-double,
4742     *      rem-double
4743     *
4744     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4745     */
4746    /* binop vAA, vBB, vCC */
4747    FETCH(r0, 1)                        @ r0<- CCBB
4748    mov     r9, rINST, lsr #8           @ r9<- AA
4749    and     r2, r0, #255                @ r2<- BB
4750    mov     r3, r0, lsr #8              @ r3<- CC
4751    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4752    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4753    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4754    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4755    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4756    .if 0
4757    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4758    beq     common_errDivideByZero
4759    .endif
4760    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4761
4762    orr     r0, r0, r2                           @ optional op; may set condition codes
4763    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
4764    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4765    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4766    GOTO_OPCODE(ip)                     @ jump to next instruction
4767    /* 14-17 instructions */
4768
4769
4770/* ------------------------------ */
4771    .balign 64
4772.L_OP_XOR_LONG: /* 0xa2 */
4773/* File: armv5te/OP_XOR_LONG.S */
4774/* File: armv5te/binopWide.S */
4775    /*
4776     * Generic 64-bit binary operation.  Provide an "instr" line that
4777     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4778     * This could be an ARM instruction or a function call.  (If the result
4779     * comes back in a register other than r0, you can override "result".)
4780     *
4781     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4782     * vCC (r1).  Useful for integer division and modulus.
4783     *
4784     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4785     *      xor-long, add-double, sub-double, mul-double, div-double,
4786     *      rem-double
4787     *
4788     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4789     */
4790    /* binop vAA, vBB, vCC */
4791    FETCH(r0, 1)                        @ r0<- CCBB
4792    mov     r9, rINST, lsr #8           @ r9<- AA
4793    and     r2, r0, #255                @ r2<- BB
4794    mov     r3, r0, lsr #8              @ r3<- CC
4795    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4796    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4797    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4798    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4799    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4800    .if 0
4801    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4802    beq     common_errDivideByZero
4803    .endif
4804    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4805
4806    eor     r0, r0, r2                           @ optional op; may set condition codes
4807    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
4808    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4809    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4810    GOTO_OPCODE(ip)                     @ jump to next instruction
4811    /* 14-17 instructions */
4812
4813
4814/* ------------------------------ */
4815    .balign 64
4816.L_OP_SHL_LONG: /* 0xa3 */
4817/* File: armv5te/OP_SHL_LONG.S */
4818    /*
4819     * Long integer shift.  This is different from the generic 32/64-bit
4820     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4821     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4822     * 6 bits of the shift distance.
4823     */
4824    /* shl-long vAA, vBB, vCC */
4825    FETCH(r0, 1)                        @ r0<- CCBB
4826    mov     r9, rINST, lsr #8           @ r9<- AA
4827    and     r3, r0, #255                @ r3<- BB
4828    mov     r0, r0, lsr #8              @ r0<- CC
4829    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4830    GET_VREG(r2, r0)                    @ r2<- vCC
4831    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4832    and     r2, r2, #63                 @ r2<- r2 & 0x3f
4833    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4834
4835    mov     r1, r1, asl r2              @  r1<- r1 << r2
4836    rsb     r3, r2, #32                 @  r3<- 32 - r2
4837    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
4838    subs    ip, r2, #32                 @  ip<- r2 - 32
4839    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
4840    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4841    b       .LOP_SHL_LONG_finish
4842
4843/* ------------------------------ */
4844    .balign 64
4845.L_OP_SHR_LONG: /* 0xa4 */
4846/* File: armv5te/OP_SHR_LONG.S */
4847    /*
4848     * Long integer shift.  This is different from the generic 32/64-bit
4849     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4850     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4851     * 6 bits of the shift distance.
4852     */
4853    /* shr-long vAA, vBB, vCC */
4854    FETCH(r0, 1)                        @ r0<- CCBB
4855    mov     r9, rINST, lsr #8           @ r9<- AA
4856    and     r3, r0, #255                @ r3<- BB
4857    mov     r0, r0, lsr #8              @ r0<- CC
4858    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4859    GET_VREG(r2, r0)                    @ r2<- vCC
4860    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4861    and     r2, r2, #63                 @ r0<- r0 & 0x3f
4862    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4863
4864    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
4865    rsb     r3, r2, #32                 @  r3<- 32 - r2
4866    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
4867    subs    ip, r2, #32                 @  ip<- r2 - 32
4868    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
4869    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4870    b       .LOP_SHR_LONG_finish
4871
4872/* ------------------------------ */
4873    .balign 64
4874.L_OP_USHR_LONG: /* 0xa5 */
4875/* File: armv5te/OP_USHR_LONG.S */
4876    /*
4877     * Long integer shift.  This is different from the generic 32/64-bit
4878     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4879     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4880     * 6 bits of the shift distance.
4881     */
4882    /* ushr-long vAA, vBB, vCC */
4883    FETCH(r0, 1)                        @ r0<- CCBB
4884    mov     r9, rINST, lsr #8           @ r9<- AA
4885    and     r3, r0, #255                @ r3<- BB
4886    mov     r0, r0, lsr #8              @ r0<- CC
4887    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4888    GET_VREG(r2, r0)                    @ r2<- vCC
4889    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4890    and     r2, r2, #63                 @ r0<- r0 & 0x3f
4891    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4892
4893    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
4894    rsb     r3, r2, #32                 @  r3<- 32 - r2
4895    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
4896    subs    ip, r2, #32                 @  ip<- r2 - 32
4897    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
4898    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4899    b       .LOP_USHR_LONG_finish
4900
4901/* ------------------------------ */
4902    .balign 64
4903.L_OP_ADD_FLOAT: /* 0xa6 */
4904/* File: arm-vfp/OP_ADD_FLOAT.S */
4905/* File: arm-vfp/fbinop.S */
4906    /*
4907     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4908     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4909     * use the "softfp" ABI, this must be an instruction, not a function call.
4910     *
4911     * For: add-float, sub-float, mul-float, div-float
4912     */
4913    /* floatop vAA, vBB, vCC */
4914    FETCH(r0, 1)                        @ r0<- CCBB
4915    mov     r9, rINST, lsr #8           @ r9<- AA
4916    mov     r3, r0, lsr #8              @ r3<- CC
4917    and     r2, r0, #255                @ r2<- BB
4918    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4919    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4920    flds    s1, [r3]                    @ s1<- vCC
4921    flds    s0, [r2]                    @ s0<- vBB
4922
4923    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4924    fadds   s2, s0, s1                              @ s2<- op
4925    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4926    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4927    fsts    s2, [r9]                    @ vAA<- s2
4928    GOTO_OPCODE(ip)                     @ jump to next instruction
4929
4930
4931/* ------------------------------ */
4932    .balign 64
4933.L_OP_SUB_FLOAT: /* 0xa7 */
4934/* File: arm-vfp/OP_SUB_FLOAT.S */
4935/* File: arm-vfp/fbinop.S */
4936    /*
4937     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4938     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4939     * use the "softfp" ABI, this must be an instruction, not a function call.
4940     *
4941     * For: add-float, sub-float, mul-float, div-float
4942     */
4943    /* floatop vAA, vBB, vCC */
4944    FETCH(r0, 1)                        @ r0<- CCBB
4945    mov     r9, rINST, lsr #8           @ r9<- AA
4946    mov     r3, r0, lsr #8              @ r3<- CC
4947    and     r2, r0, #255                @ r2<- BB
4948    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4949    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4950    flds    s1, [r3]                    @ s1<- vCC
4951    flds    s0, [r2]                    @ s0<- vBB
4952
4953    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4954    fsubs   s2, s0, s1                              @ s2<- op
4955    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4956    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4957    fsts    s2, [r9]                    @ vAA<- s2
4958    GOTO_OPCODE(ip)                     @ jump to next instruction
4959
4960
4961/* ------------------------------ */
4962    .balign 64
4963.L_OP_MUL_FLOAT: /* 0xa8 */
4964/* File: arm-vfp/OP_MUL_FLOAT.S */
4965/* File: arm-vfp/fbinop.S */
4966    /*
4967     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4968     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4969     * use the "softfp" ABI, this must be an instruction, not a function call.
4970     *
4971     * For: add-float, sub-float, mul-float, div-float
4972     */
4973    /* floatop vAA, vBB, vCC */
4974    FETCH(r0, 1)                        @ r0<- CCBB
4975    mov     r9, rINST, lsr #8           @ r9<- AA
4976    mov     r3, r0, lsr #8              @ r3<- CC
4977    and     r2, r0, #255                @ r2<- BB
4978    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4979    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4980    flds    s1, [r3]                    @ s1<- vCC
4981    flds    s0, [r2]                    @ s0<- vBB
4982
4983    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4984    fmuls   s2, s0, s1                              @ s2<- op
4985    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4986    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4987    fsts    s2, [r9]                    @ vAA<- s2
4988    GOTO_OPCODE(ip)                     @ jump to next instruction
4989
4990
4991/* ------------------------------ */
4992    .balign 64
4993.L_OP_DIV_FLOAT: /* 0xa9 */
4994/* File: arm-vfp/OP_DIV_FLOAT.S */
4995/* File: arm-vfp/fbinop.S */
4996    /*
4997     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4998     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4999     * use the "softfp" ABI, this must be an instruction, not a function call.
5000     *
5001     * For: add-float, sub-float, mul-float, div-float
5002     */
5003    /* floatop vAA, vBB, vCC */
5004    FETCH(r0, 1)                        @ r0<- CCBB
5005    mov     r9, rINST, lsr #8           @ r9<- AA
5006    mov     r3, r0, lsr #8              @ r3<- CC
5007    and     r2, r0, #255                @ r2<- BB
5008    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5009    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5010    flds    s1, [r3]                    @ s1<- vCC
5011    flds    s0, [r2]                    @ s0<- vBB
5012
5013    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5014    fdivs   s2, s0, s1                              @ s2<- op
5015    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5016    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5017    fsts    s2, [r9]                    @ vAA<- s2
5018    GOTO_OPCODE(ip)                     @ jump to next instruction
5019
5020
5021/* ------------------------------ */
5022    .balign 64
5023.L_OP_REM_FLOAT: /* 0xaa */
5024/* File: armv5te/OP_REM_FLOAT.S */
5025/* EABI doesn't define a float remainder function, but libm does */
5026/* File: armv5te/binop.S */
5027    /*
5028     * Generic 32-bit binary operation.  Provide an "instr" line that
5029     * specifies an instruction that performs "result = r0 op r1".
5030     * This could be an ARM instruction or a function call.  (If the result
5031     * comes back in a register other than r0, you can override "result".)
5032     *
5033     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5034     * vCC (r1).  Useful for integer division and modulus.  Note that we
5035     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
5036     * handles it correctly.
5037     *
5038     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
5039     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
5040     *      mul-float, div-float, rem-float
5041     */
5042    /* binop vAA, vBB, vCC */
5043    FETCH(r0, 1)                        @ r0<- CCBB
5044    mov     r9, rINST, lsr #8           @ r9<- AA
5045    mov     r3, r0, lsr #8              @ r3<- CC
5046    and     r2, r0, #255                @ r2<- BB
5047    GET_VREG(r1, r3)                    @ r1<- vCC
5048    GET_VREG(r0, r2)                    @ r0<- vBB
5049    .if 0
5050    cmp     r1, #0                      @ is second operand zero?
5051    beq     common_errDivideByZero
5052    .endif
5053
5054    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5055                               @ optional op; may set condition codes
5056    bl      fmodf                              @ r0<- op, r0-r3 changed
5057    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5058    SET_VREG(r0, r9)               @ vAA<- r0
5059    GOTO_OPCODE(ip)                     @ jump to next instruction
5060    /* 11-14 instructions */
5061
5062
5063/* ------------------------------ */
5064    .balign 64
5065.L_OP_ADD_DOUBLE: /* 0xab */
5066/* File: arm-vfp/OP_ADD_DOUBLE.S */
5067/* File: arm-vfp/fbinopWide.S */
5068    /*
5069     * Generic 64-bit double-precision floating point binary operation.
5070     * Provide an "instr" line that specifies an instruction that performs
5071     * "d2 = d0 op d1".
5072     *
5073     * for: add-double, sub-double, mul-double, div-double
5074     */
5075    /* doubleop vAA, vBB, vCC */
5076    FETCH(r0, 1)                        @ r0<- CCBB
5077    mov     r9, rINST, lsr #8           @ r9<- AA
5078    mov     r3, r0, lsr #8              @ r3<- CC
5079    and     r2, r0, #255                @ r2<- BB
5080    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5081    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5082    fldd    d1, [r3]                    @ d1<- vCC
5083    fldd    d0, [r2]                    @ d0<- vBB
5084
5085    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5086    faddd   d2, d0, d1                              @ s2<- op
5087    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5088    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5089    fstd    d2, [r9]                    @ vAA<- d2
5090    GOTO_OPCODE(ip)                     @ jump to next instruction
5091
5092
5093/* ------------------------------ */
5094    .balign 64
5095.L_OP_SUB_DOUBLE: /* 0xac */
5096/* File: arm-vfp/OP_SUB_DOUBLE.S */
5097/* File: arm-vfp/fbinopWide.S */
5098    /*
5099     * Generic 64-bit double-precision floating point binary operation.
5100     * Provide an "instr" line that specifies an instruction that performs
5101     * "d2 = d0 op d1".
5102     *
5103     * for: add-double, sub-double, mul-double, div-double
5104     */
5105    /* doubleop vAA, vBB, vCC */
5106    FETCH(r0, 1)                        @ r0<- CCBB
5107    mov     r9, rINST, lsr #8           @ r9<- AA
5108    mov     r3, r0, lsr #8              @ r3<- CC
5109    and     r2, r0, #255                @ r2<- BB
5110    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5111    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5112    fldd    d1, [r3]                    @ d1<- vCC
5113    fldd    d0, [r2]                    @ d0<- vBB
5114
5115    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5116    fsubd   d2, d0, d1                              @ s2<- op
5117    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5118    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5119    fstd    d2, [r9]                    @ vAA<- d2
5120    GOTO_OPCODE(ip)                     @ jump to next instruction
5121
5122
5123/* ------------------------------ */
5124    .balign 64
5125.L_OP_MUL_DOUBLE: /* 0xad */
5126/* File: arm-vfp/OP_MUL_DOUBLE.S */
5127/* File: arm-vfp/fbinopWide.S */
5128    /*
5129     * Generic 64-bit double-precision floating point binary operation.
5130     * Provide an "instr" line that specifies an instruction that performs
5131     * "d2 = d0 op d1".
5132     *
5133     * for: add-double, sub-double, mul-double, div-double
5134     */
5135    /* doubleop vAA, vBB, vCC */
5136    FETCH(r0, 1)                        @ r0<- CCBB
5137    mov     r9, rINST, lsr #8           @ r9<- AA
5138    mov     r3, r0, lsr #8              @ r3<- CC
5139    and     r2, r0, #255                @ r2<- BB
5140    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5141    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5142    fldd    d1, [r3]                    @ d1<- vCC
5143    fldd    d0, [r2]                    @ d0<- vBB
5144
5145    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5146    fmuld   d2, d0, d1                              @ s2<- op
5147    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5148    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5149    fstd    d2, [r9]                    @ vAA<- d2
5150    GOTO_OPCODE(ip)                     @ jump to next instruction
5151
5152
5153/* ------------------------------ */
5154    .balign 64
5155.L_OP_DIV_DOUBLE: /* 0xae */
5156/* File: arm-vfp/OP_DIV_DOUBLE.S */
5157/* File: arm-vfp/fbinopWide.S */
5158    /*
5159     * Generic 64-bit double-precision floating point binary operation.
5160     * Provide an "instr" line that specifies an instruction that performs
5161     * "d2 = d0 op d1".
5162     *
5163     * for: add-double, sub-double, mul-double, div-double
5164     */
5165    /* doubleop vAA, vBB, vCC */
5166    FETCH(r0, 1)                        @ r0<- CCBB
5167    mov     r9, rINST, lsr #8           @ r9<- AA
5168    mov     r3, r0, lsr #8              @ r3<- CC
5169    and     r2, r0, #255                @ r2<- BB
5170    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5171    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5172    fldd    d1, [r3]                    @ d1<- vCC
5173    fldd    d0, [r2]                    @ d0<- vBB
5174
5175    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5176    fdivd   d2, d0, d1                              @ s2<- op
5177    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5178    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5179    fstd    d2, [r9]                    @ vAA<- d2
5180    GOTO_OPCODE(ip)                     @ jump to next instruction
5181
5182
5183/* ------------------------------ */
5184    .balign 64
5185.L_OP_REM_DOUBLE: /* 0xaf */
5186/* File: armv5te/OP_REM_DOUBLE.S */
5187/* EABI doesn't define a double remainder function, but libm does */
5188/* File: armv5te/binopWide.S */
5189    /*
5190     * Generic 64-bit binary operation.  Provide an "instr" line that
5191     * specifies an instruction that performs "result = r0-r1 op r2-r3".
5192     * This could be an ARM instruction or a function call.  (If the result
5193     * comes back in a register other than r0, you can override "result".)
5194     *
5195     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5196     * vCC (r1).  Useful for integer division and modulus.
5197     *
5198     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
5199     *      xor-long, add-double, sub-double, mul-double, div-double,
5200     *      rem-double
5201     *
5202     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
5203     */
5204    /* binop vAA, vBB, vCC */
5205    FETCH(r0, 1)                        @ r0<- CCBB
5206    mov     r9, rINST, lsr #8           @ r9<- AA
5207    and     r2, r0, #255                @ r2<- BB
5208    mov     r3, r0, lsr #8              @ r3<- CC
5209    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5210    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
5211    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
5212    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5213    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
5214    .if 0
5215    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5216    beq     common_errDivideByZero
5217    .endif
5218    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5219
5220                               @ optional op; may set condition codes
5221    bl      fmod                              @ result<- op, r0-r3 changed
5222    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5223    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5224    GOTO_OPCODE(ip)                     @ jump to next instruction
5225    /* 14-17 instructions */
5226
5227
5228/* ------------------------------ */
5229    .balign 64
5230.L_OP_ADD_INT_2ADDR: /* 0xb0 */
5231/* File: armv5te/OP_ADD_INT_2ADDR.S */
5232/* File: armv5te/binop2addr.S */
5233    /*
5234     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5235     * that specifies an instruction that performs "result = r0 op r1".
5236     * This could be an ARM instruction or a function call.  (If the result
5237     * comes back in a register other than r0, you can override "result".)
5238     *
5239     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5240     * vCC (r1).  Useful for integer division and modulus.
5241     *
5242     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5243     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5244     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5245     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5246     */
5247    /* binop/2addr vA, vB */
5248    mov     r9, rINST, lsr #8           @ r9<- A+
5249    mov     r3, rINST, lsr #12          @ r3<- B
5250    and     r9, r9, #15
5251    GET_VREG(r1, r3)                    @ r1<- vB
5252    GET_VREG(r0, r9)                    @ r0<- vA
5253    .if 0
5254    cmp     r1, #0                      @ is second operand zero?
5255    beq     common_errDivideByZero
5256    .endif
5257    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5258
5259                               @ optional op; may set condition codes
5260    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
5261    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5262    SET_VREG(r0, r9)               @ vAA<- r0
5263    GOTO_OPCODE(ip)                     @ jump to next instruction
5264    /* 10-13 instructions */
5265
5266
5267/* ------------------------------ */
5268    .balign 64
5269.L_OP_SUB_INT_2ADDR: /* 0xb1 */
5270/* File: armv5te/OP_SUB_INT_2ADDR.S */
5271/* File: armv5te/binop2addr.S */
5272    /*
5273     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5274     * that specifies an instruction that performs "result = r0 op r1".
5275     * This could be an ARM instruction or a function call.  (If the result
5276     * comes back in a register other than r0, you can override "result".)
5277     *
5278     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5279     * vCC (r1).  Useful for integer division and modulus.
5280     *
5281     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5282     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5283     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5284     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5285     */
5286    /* binop/2addr vA, vB */
5287    mov     r9, rINST, lsr #8           @ r9<- A+
5288    mov     r3, rINST, lsr #12          @ r3<- B
5289    and     r9, r9, #15
5290    GET_VREG(r1, r3)                    @ r1<- vB
5291    GET_VREG(r0, r9)                    @ r0<- vA
5292    .if 0
5293    cmp     r1, #0                      @ is second operand zero?
5294    beq     common_errDivideByZero
5295    .endif
5296    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5297
5298                               @ optional op; may set condition codes
5299    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
5300    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5301    SET_VREG(r0, r9)               @ vAA<- r0
5302    GOTO_OPCODE(ip)                     @ jump to next instruction
5303    /* 10-13 instructions */
5304
5305
5306/* ------------------------------ */
5307    .balign 64
5308.L_OP_MUL_INT_2ADDR: /* 0xb2 */
5309/* File: armv5te/OP_MUL_INT_2ADDR.S */
5310/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
5311/* File: armv5te/binop2addr.S */
5312    /*
5313     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5314     * that specifies an instruction that performs "result = r0 op r1".
5315     * This could be an ARM instruction or a function call.  (If the result
5316     * comes back in a register other than r0, you can override "result".)
5317     *
5318     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5319     * vCC (r1).  Useful for integer division and modulus.
5320     *
5321     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5322     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5323     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5324     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5325     */
5326    /* binop/2addr vA, vB */
5327    mov     r9, rINST, lsr #8           @ r9<- A+
5328    mov     r3, rINST, lsr #12          @ r3<- B
5329    and     r9, r9, #15
5330    GET_VREG(r1, r3)                    @ r1<- vB
5331    GET_VREG(r0, r9)                    @ r0<- vA
5332    .if 0
5333    cmp     r1, #0                      @ is second operand zero?
5334    beq     common_errDivideByZero
5335    .endif
5336    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5337
5338                               @ optional op; may set condition codes
5339    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
5340    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5341    SET_VREG(r0, r9)               @ vAA<- r0
5342    GOTO_OPCODE(ip)                     @ jump to next instruction
5343    /* 10-13 instructions */
5344
5345
5346/* ------------------------------ */
5347    .balign 64
5348.L_OP_DIV_INT_2ADDR: /* 0xb3 */
5349/* File: armv5te/OP_DIV_INT_2ADDR.S */
5350/* File: armv5te/binop2addr.S */
5351    /*
5352     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5353     * that specifies an instruction that performs "result = r0 op r1".
5354     * This could be an ARM instruction or a function call.  (If the result
5355     * comes back in a register other than r0, you can override "result".)
5356     *
5357     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5358     * vCC (r1).  Useful for integer division and modulus.
5359     *
5360     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5361     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5362     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5363     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5364     */
5365    /* binop/2addr vA, vB */
5366    mov     r9, rINST, lsr #8           @ r9<- A+
5367    mov     r3, rINST, lsr #12          @ r3<- B
5368    and     r9, r9, #15
5369    GET_VREG(r1, r3)                    @ r1<- vB
5370    GET_VREG(r0, r9)                    @ r0<- vA
5371    .if 1
5372    cmp     r1, #0                      @ is second operand zero?
5373    beq     common_errDivideByZero
5374    .endif
5375    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5376
5377                               @ optional op; may set condition codes
5378    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
5379    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5380    SET_VREG(r0, r9)               @ vAA<- r0
5381    GOTO_OPCODE(ip)                     @ jump to next instruction
5382    /* 10-13 instructions */
5383
5384
5385/* ------------------------------ */
5386    .balign 64
5387.L_OP_REM_INT_2ADDR: /* 0xb4 */
5388/* File: armv5te/OP_REM_INT_2ADDR.S */
5389/* idivmod returns quotient in r0 and remainder in r1 */
5390/* File: armv5te/binop2addr.S */
5391    /*
5392     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5393     * that specifies an instruction that performs "result = r0 op r1".
5394     * This could be an ARM instruction or a function call.  (If the result
5395     * comes back in a register other than r0, you can override "result".)
5396     *
5397     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5398     * vCC (r1).  Useful for integer division and modulus.
5399     *
5400     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5401     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5402     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5403     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5404     */
5405    /* binop/2addr vA, vB */
5406    mov     r9, rINST, lsr #8           @ r9<- A+
5407    mov     r3, rINST, lsr #12          @ r3<- B
5408    and     r9, r9, #15
5409    GET_VREG(r1, r3)                    @ r1<- vB
5410    GET_VREG(r0, r9)                    @ r0<- vA
5411    .if 1
5412    cmp     r1, #0                      @ is second operand zero?
5413    beq     common_errDivideByZero
5414    .endif
5415    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5416
5417                               @ optional op; may set condition codes
5418    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
5419    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5420    SET_VREG(r1, r9)               @ vAA<- r1
5421    GOTO_OPCODE(ip)                     @ jump to next instruction
5422    /* 10-13 instructions */
5423
5424
5425/* ------------------------------ */
5426    .balign 64
5427.L_OP_AND_INT_2ADDR: /* 0xb5 */
5428/* File: armv5te/OP_AND_INT_2ADDR.S */
5429/* File: armv5te/binop2addr.S */
5430    /*
5431     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5432     * that specifies an instruction that performs "result = r0 op r1".
5433     * This could be an ARM instruction or a function call.  (If the result
5434     * comes back in a register other than r0, you can override "result".)
5435     *
5436     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5437     * vCC (r1).  Useful for integer division and modulus.
5438     *
5439     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5440     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5441     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5442     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5443     */
5444    /* binop/2addr vA, vB */
5445    mov     r9, rINST, lsr #8           @ r9<- A+
5446    mov     r3, rINST, lsr #12          @ r3<- B
5447    and     r9, r9, #15
5448    GET_VREG(r1, r3)                    @ r1<- vB
5449    GET_VREG(r0, r9)                    @ r0<- vA
5450    .if 0
5451    cmp     r1, #0                      @ is second operand zero?
5452    beq     common_errDivideByZero
5453    .endif
5454    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5455
5456                               @ optional op; may set condition codes
5457    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
5458    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5459    SET_VREG(r0, r9)               @ vAA<- r0
5460    GOTO_OPCODE(ip)                     @ jump to next instruction
5461    /* 10-13 instructions */
5462
5463
5464/* ------------------------------ */
5465    .balign 64
5466.L_OP_OR_INT_2ADDR: /* 0xb6 */
5467/* File: armv5te/OP_OR_INT_2ADDR.S */
5468/* File: armv5te/binop2addr.S */
5469    /*
5470     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5471     * that specifies an instruction that performs "result = r0 op r1".
5472     * This could be an ARM instruction or a function call.  (If the result
5473     * comes back in a register other than r0, you can override "result".)
5474     *
5475     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5476     * vCC (r1).  Useful for integer division and modulus.
5477     *
5478     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5479     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5480     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5481     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5482     */
5483    /* binop/2addr vA, vB */
5484    mov     r9, rINST, lsr #8           @ r9<- A+
5485    mov     r3, rINST, lsr #12          @ r3<- B
5486    and     r9, r9, #15
5487    GET_VREG(r1, r3)                    @ r1<- vB
5488    GET_VREG(r0, r9)                    @ r0<- vA
5489    .if 0
5490    cmp     r1, #0                      @ is second operand zero?
5491    beq     common_errDivideByZero
5492    .endif
5493    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5494
5495                               @ optional op; may set condition codes
5496    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
5497    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5498    SET_VREG(r0, r9)               @ vAA<- r0
5499    GOTO_OPCODE(ip)                     @ jump to next instruction
5500    /* 10-13 instructions */
5501
5502
5503/* ------------------------------ */
5504    .balign 64
5505.L_OP_XOR_INT_2ADDR: /* 0xb7 */
5506/* File: armv5te/OP_XOR_INT_2ADDR.S */
5507/* File: armv5te/binop2addr.S */
5508    /*
5509     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5510     * that specifies an instruction that performs "result = r0 op r1".
5511     * This could be an ARM instruction or a function call.  (If the result
5512     * comes back in a register other than r0, you can override "result".)
5513     *
5514     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5515     * vCC (r1).  Useful for integer division and modulus.
5516     *
5517     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5518     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5519     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5520     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5521     */
5522    /* binop/2addr vA, vB */
5523    mov     r9, rINST, lsr #8           @ r9<- A+
5524    mov     r3, rINST, lsr #12          @ r3<- B
5525    and     r9, r9, #15
5526    GET_VREG(r1, r3)                    @ r1<- vB
5527    GET_VREG(r0, r9)                    @ r0<- vA
5528    .if 0
5529    cmp     r1, #0                      @ is second operand zero?
5530    beq     common_errDivideByZero
5531    .endif
5532    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5533
5534                               @ optional op; may set condition codes
5535    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
5536    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5537    SET_VREG(r0, r9)               @ vAA<- r0
5538    GOTO_OPCODE(ip)                     @ jump to next instruction
5539    /* 10-13 instructions */
5540
5541
5542/* ------------------------------ */
5543    .balign 64
5544.L_OP_SHL_INT_2ADDR: /* 0xb8 */
5545/* File: armv5te/OP_SHL_INT_2ADDR.S */
5546/* File: armv5te/binop2addr.S */
5547    /*
5548     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5549     * that specifies an instruction that performs "result = r0 op r1".
5550     * This could be an ARM instruction or a function call.  (If the result
5551     * comes back in a register other than r0, you can override "result".)
5552     *
5553     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5554     * vCC (r1).  Useful for integer division and modulus.
5555     *
5556     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5557     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5558     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5559     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5560     */
5561    /* binop/2addr vA, vB */
5562    mov     r9, rINST, lsr #8           @ r9<- A+
5563    mov     r3, rINST, lsr #12          @ r3<- B
5564    and     r9, r9, #15
5565    GET_VREG(r1, r3)                    @ r1<- vB
5566    GET_VREG(r0, r9)                    @ r0<- vA
5567    .if 0
5568    cmp     r1, #0                      @ is second operand zero?
5569    beq     common_errDivideByZero
5570    .endif
5571    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5572
5573    and     r1, r1, #31                           @ optional op; may set condition codes
5574    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
5575    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5576    SET_VREG(r0, r9)               @ vAA<- r0
5577    GOTO_OPCODE(ip)                     @ jump to next instruction
5578    /* 10-13 instructions */
5579
5580
5581/* ------------------------------ */
5582    .balign 64
5583.L_OP_SHR_INT_2ADDR: /* 0xb9 */
5584/* File: armv5te/OP_SHR_INT_2ADDR.S */
5585/* File: armv5te/binop2addr.S */
5586    /*
5587     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5588     * that specifies an instruction that performs "result = r0 op r1".
5589     * This could be an ARM instruction or a function call.  (If the result
5590     * comes back in a register other than r0, you can override "result".)
5591     *
5592     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5593     * vCC (r1).  Useful for integer division and modulus.
5594     *
5595     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5596     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5597     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5598     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5599     */
5600    /* binop/2addr vA, vB */
5601    mov     r9, rINST, lsr #8           @ r9<- A+
5602    mov     r3, rINST, lsr #12          @ r3<- B
5603    and     r9, r9, #15
5604    GET_VREG(r1, r3)                    @ r1<- vB
5605    GET_VREG(r0, r9)                    @ r0<- vA
5606    .if 0
5607    cmp     r1, #0                      @ is second operand zero?
5608    beq     common_errDivideByZero
5609    .endif
5610    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5611
5612    and     r1, r1, #31                           @ optional op; may set condition codes
5613    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
5614    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5615    SET_VREG(r0, r9)               @ vAA<- r0
5616    GOTO_OPCODE(ip)                     @ jump to next instruction
5617    /* 10-13 instructions */
5618
5619
5620/* ------------------------------ */
5621    .balign 64
5622.L_OP_USHR_INT_2ADDR: /* 0xba */
5623/* File: armv5te/OP_USHR_INT_2ADDR.S */
5624/* File: armv5te/binop2addr.S */
5625    /*
5626     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5627     * that specifies an instruction that performs "result = r0 op r1".
5628     * This could be an ARM instruction or a function call.  (If the result
5629     * comes back in a register other than r0, you can override "result".)
5630     *
5631     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5632     * vCC (r1).  Useful for integer division and modulus.
5633     *
5634     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5635     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5636     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5637     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5638     */
5639    /* binop/2addr vA, vB */
5640    mov     r9, rINST, lsr #8           @ r9<- A+
5641    mov     r3, rINST, lsr #12          @ r3<- B
5642    and     r9, r9, #15
5643    GET_VREG(r1, r3)                    @ r1<- vB
5644    GET_VREG(r0, r9)                    @ r0<- vA
5645    .if 0
5646    cmp     r1, #0                      @ is second operand zero?
5647    beq     common_errDivideByZero
5648    .endif
5649    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5650
5651    and     r1, r1, #31                           @ optional op; may set condition codes
5652    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
5653    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5654    SET_VREG(r0, r9)               @ vAA<- r0
5655    GOTO_OPCODE(ip)                     @ jump to next instruction
5656    /* 10-13 instructions */
5657
5658
5659/* ------------------------------ */
5660    .balign 64
5661.L_OP_ADD_LONG_2ADDR: /* 0xbb */
5662/* File: armv5te/OP_ADD_LONG_2ADDR.S */
5663/* File: armv5te/binopWide2addr.S */
5664    /*
5665     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5666     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5667     * This could be an ARM instruction or a function call.  (If the result
5668     * comes back in a register other than r0, you can override "result".)
5669     *
5670     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5671     * vCC (r1).  Useful for integer division and modulus.
5672     *
5673     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5674     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5675     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5676     *      rem-double/2addr
5677     */
5678    /* binop/2addr vA, vB */
5679    mov     r9, rINST, lsr #8           @ r9<- A+
5680    mov     r1, rINST, lsr #12          @ r1<- B
5681    and     r9, r9, #15
5682    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5683    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5684    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5685    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5686    .if 0
5687    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5688    beq     common_errDivideByZero
5689    .endif
5690    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5691
5692    adds    r0, r0, r2                           @ optional op; may set condition codes
5693    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
5694    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5695    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5696    GOTO_OPCODE(ip)                     @ jump to next instruction
5697    /* 12-15 instructions */
5698
5699
5700/* ------------------------------ */
5701    .balign 64
5702.L_OP_SUB_LONG_2ADDR: /* 0xbc */
5703/* File: armv5te/OP_SUB_LONG_2ADDR.S */
5704/* File: armv5te/binopWide2addr.S */
5705    /*
5706     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5707     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5708     * This could be an ARM instruction or a function call.  (If the result
5709     * comes back in a register other than r0, you can override "result".)
5710     *
5711     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5712     * vCC (r1).  Useful for integer division and modulus.
5713     *
5714     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5715     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5716     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5717     *      rem-double/2addr
5718     */
5719    /* binop/2addr vA, vB */
5720    mov     r9, rINST, lsr #8           @ r9<- A+
5721    mov     r1, rINST, lsr #12          @ r1<- B
5722    and     r9, r9, #15
5723    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5724    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5725    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5726    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5727    .if 0
5728    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5729    beq     common_errDivideByZero
5730    .endif
5731    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5732
5733    subs    r0, r0, r2                           @ optional op; may set condition codes
5734    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
5735    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5736    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5737    GOTO_OPCODE(ip)                     @ jump to next instruction
5738    /* 12-15 instructions */
5739
5740
5741/* ------------------------------ */
5742    .balign 64
5743.L_OP_MUL_LONG_2ADDR: /* 0xbd */
5744/* File: armv5te/OP_MUL_LONG_2ADDR.S */
5745    /*
5746     * Signed 64-bit integer multiply, "/2addr" version.
5747     *
5748     * See OP_MUL_LONG for an explanation.
5749     *
5750     * We get a little tight on registers, so to avoid looking up &fp[A]
5751     * again we stuff it into rINST.
5752     */
5753    /* mul-long/2addr vA, vB */
5754    mov     r9, rINST, lsr #8           @ r9<- A+
5755    mov     r1, rINST, lsr #12          @ r1<- B
5756    and     r9, r9, #15
5757    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5758    add     rINST, rFP, r9, lsl #2      @ rINST<- &fp[A]
5759    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5760    ldmia   rINST, {r0-r1}              @ r0/r1<- vAA/vAA+1
5761    mul     ip, r2, r1                  @  ip<- ZxW
5762    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
5763    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
5764    mov     r0, rINST                   @ r0<- &fp[A] (free up rINST)
5765    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5766    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
5767    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5768    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
5769    GOTO_OPCODE(ip)                     @ jump to next instruction
5770
5771/* ------------------------------ */
5772    .balign 64
5773.L_OP_DIV_LONG_2ADDR: /* 0xbe */
5774/* File: armv5te/OP_DIV_LONG_2ADDR.S */
5775/* File: armv5te/binopWide2addr.S */
5776    /*
5777     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5778     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5779     * This could be an ARM instruction or a function call.  (If the result
5780     * comes back in a register other than r0, you can override "result".)
5781     *
5782     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5783     * vCC (r1).  Useful for integer division and modulus.
5784     *
5785     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5786     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5787     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5788     *      rem-double/2addr
5789     */
5790    /* binop/2addr vA, vB */
5791    mov     r9, rINST, lsr #8           @ r9<- A+
5792    mov     r1, rINST, lsr #12          @ r1<- B
5793    and     r9, r9, #15
5794    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5795    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5796    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5797    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5798    .if 1
5799    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5800    beq     common_errDivideByZero
5801    .endif
5802    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5803
5804                               @ optional op; may set condition codes
5805    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
5806    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5807    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5808    GOTO_OPCODE(ip)                     @ jump to next instruction
5809    /* 12-15 instructions */
5810
5811
5812/* ------------------------------ */
5813    .balign 64
5814.L_OP_REM_LONG_2ADDR: /* 0xbf */
5815/* File: armv5te/OP_REM_LONG_2ADDR.S */
5816/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
5817/* File: armv5te/binopWide2addr.S */
5818    /*
5819     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5820     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5821     * This could be an ARM instruction or a function call.  (If the result
5822     * comes back in a register other than r0, you can override "result".)
5823     *
5824     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5825     * vCC (r1).  Useful for integer division and modulus.
5826     *
5827     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5828     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5829     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5830     *      rem-double/2addr
5831     */
5832    /* binop/2addr vA, vB */
5833    mov     r9, rINST, lsr #8           @ r9<- A+
5834    mov     r1, rINST, lsr #12          @ r1<- B
5835    and     r9, r9, #15
5836    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5837    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5838    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5839    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5840    .if 1
5841    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5842    beq     common_errDivideByZero
5843    .endif
5844    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5845
5846                               @ optional op; may set condition codes
5847    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
5848    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5849    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
5850    GOTO_OPCODE(ip)                     @ jump to next instruction
5851    /* 12-15 instructions */
5852
5853
5854/* ------------------------------ */
5855    .balign 64
5856.L_OP_AND_LONG_2ADDR: /* 0xc0 */
5857/* File: armv5te/OP_AND_LONG_2ADDR.S */
5858/* File: armv5te/binopWide2addr.S */
5859    /*
5860     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5861     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5862     * This could be an ARM instruction or a function call.  (If the result
5863     * comes back in a register other than r0, you can override "result".)
5864     *
5865     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5866     * vCC (r1).  Useful for integer division and modulus.
5867     *
5868     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5869     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5870     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5871     *      rem-double/2addr
5872     */
5873    /* binop/2addr vA, vB */
5874    mov     r9, rINST, lsr #8           @ r9<- A+
5875    mov     r1, rINST, lsr #12          @ r1<- B
5876    and     r9, r9, #15
5877    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5878    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5879    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5880    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5881    .if 0
5882    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5883    beq     common_errDivideByZero
5884    .endif
5885    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5886
5887    and     r0, r0, r2                           @ optional op; may set condition codes
5888    and     r1, r1, r3                              @ result<- op, r0-r3 changed
5889    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5890    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5891    GOTO_OPCODE(ip)                     @ jump to next instruction
5892    /* 12-15 instructions */
5893
5894
5895/* ------------------------------ */
5896    .balign 64
5897.L_OP_OR_LONG_2ADDR: /* 0xc1 */
5898/* File: armv5te/OP_OR_LONG_2ADDR.S */
5899/* File: armv5te/binopWide2addr.S */
5900    /*
5901     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5902     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5903     * This could be an ARM instruction or a function call.  (If the result
5904     * comes back in a register other than r0, you can override "result".)
5905     *
5906     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5907     * vCC (r1).  Useful for integer division and modulus.
5908     *
5909     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5910     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5911     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5912     *      rem-double/2addr
5913     */
5914    /* binop/2addr vA, vB */
5915    mov     r9, rINST, lsr #8           @ r9<- A+
5916    mov     r1, rINST, lsr #12          @ r1<- B
5917    and     r9, r9, #15
5918    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5919    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5920    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5921    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5922    .if 0
5923    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5924    beq     common_errDivideByZero
5925    .endif
5926    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5927
5928    orr     r0, r0, r2                           @ optional op; may set condition codes
5929    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
5930    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5931    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5932    GOTO_OPCODE(ip)                     @ jump to next instruction
5933    /* 12-15 instructions */
5934
5935
5936/* ------------------------------ */
5937    .balign 64
5938.L_OP_XOR_LONG_2ADDR: /* 0xc2 */
5939/* File: armv5te/OP_XOR_LONG_2ADDR.S */
5940/* File: armv5te/binopWide2addr.S */
5941    /*
5942     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5943     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5944     * This could be an ARM instruction or a function call.  (If the result
5945     * comes back in a register other than r0, you can override "result".)
5946     *
5947     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5948     * vCC (r1).  Useful for integer division and modulus.
5949     *
5950     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5951     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5952     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5953     *      rem-double/2addr
5954     */
5955    /* binop/2addr vA, vB */
5956    mov     r9, rINST, lsr #8           @ r9<- A+
5957    mov     r1, rINST, lsr #12          @ r1<- B
5958    and     r9, r9, #15
5959    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5960    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5961    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5962    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5963    .if 0
5964    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5965    beq     common_errDivideByZero
5966    .endif
5967    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5968
5969    eor     r0, r0, r2                           @ optional op; may set condition codes
5970    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
5971    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5972    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5973    GOTO_OPCODE(ip)                     @ jump to next instruction
5974    /* 12-15 instructions */
5975
5976
5977/* ------------------------------ */
5978    .balign 64
5979.L_OP_SHL_LONG_2ADDR: /* 0xc3 */
5980/* File: armv5te/OP_SHL_LONG_2ADDR.S */
5981    /*
5982     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5983     * 32-bit shift distance.
5984     */
5985    /* shl-long/2addr vA, vB */
5986    mov     r9, rINST, lsr #8           @ r9<- A+
5987    mov     r3, rINST, lsr #12          @ r3<- B
5988    and     r9, r9, #15
5989    GET_VREG(r2, r3)                    @ r2<- vB
5990    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5991    and     r2, r2, #63                 @ r2<- r2 & 0x3f
5992    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5993
5994    mov     r1, r1, asl r2              @  r1<- r1 << r2
5995    rsb     r3, r2, #32                 @  r3<- 32 - r2
5996    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
5997    subs    ip, r2, #32                 @  ip<- r2 - 32
5998    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5999    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
6000    mov     r0, r0, asl r2              @  r0<- r0 << r2
6001    b       .LOP_SHL_LONG_2ADDR_finish
6002
6003/* ------------------------------ */
6004    .balign 64
6005.L_OP_SHR_LONG_2ADDR: /* 0xc4 */
6006/* File: armv5te/OP_SHR_LONG_2ADDR.S */
6007    /*
6008     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6009     * 32-bit shift distance.
6010     */
6011    /* shr-long/2addr vA, vB */
6012    mov     r9, rINST, lsr #8           @ r9<- A+
6013    mov     r3, rINST, lsr #12          @ r3<- B
6014    and     r9, r9, #15
6015    GET_VREG(r2, r3)                    @ r2<- vB
6016    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6017    and     r2, r2, #63                 @ r2<- r2 & 0x3f
6018    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6019
6020    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
6021    rsb     r3, r2, #32                 @  r3<- 32 - r2
6022    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
6023    subs    ip, r2, #32                 @  ip<- r2 - 32
6024    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6025    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
6026    mov     r1, r1, asr r2              @  r1<- r1 >> r2
6027    b       .LOP_SHR_LONG_2ADDR_finish
6028
6029/* ------------------------------ */
6030    .balign 64
6031.L_OP_USHR_LONG_2ADDR: /* 0xc5 */
6032/* File: armv5te/OP_USHR_LONG_2ADDR.S */
6033    /*
6034     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6035     * 32-bit shift distance.
6036     */
6037    /* ushr-long/2addr vA, vB */
6038    mov     r9, rINST, lsr #8           @ r9<- A+
6039    mov     r3, rINST, lsr #12          @ r3<- B
6040    and     r9, r9, #15
6041    GET_VREG(r2, r3)                    @ r2<- vB
6042    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6043    and     r2, r2, #63                 @ r2<- r2 & 0x3f
6044    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6045
6046    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
6047    rsb     r3, r2, #32                 @  r3<- 32 - r2
6048    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
6049    subs    ip, r2, #32                 @  ip<- r2 - 32
6050    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6051    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
6052    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
6053    b       .LOP_USHR_LONG_2ADDR_finish
6054
6055/* ------------------------------ */
6056    .balign 64
6057.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
6058/* File: arm-vfp/OP_ADD_FLOAT_2ADDR.S */
6059/* File: arm-vfp/fbinop2addr.S */
6060    /*
6061     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6062     * an "instr" line that specifies an instruction that performs
6063     * "s2 = s0 op s1".
6064     *
6065     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6066     */
6067    /* binop/2addr vA, vB */
6068    mov     r3, rINST, lsr #12          @ r3<- B
6069    mov     r9, rINST, lsr #8           @ r9<- A+
6070    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6071    and     r9, r9, #15                 @ r9<- A
6072    flds    s1, [r3]                    @ s1<- vB
6073    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6074    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6075    flds    s0, [r9]                    @ s0<- vA
6076
6077    fadds   s2, s0, s1                              @ s2<- op
6078    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6079    fsts    s2, [r9]                    @ vAA<- s2
6080    GOTO_OPCODE(ip)                     @ jump to next instruction
6081
6082
6083/* ------------------------------ */
6084    .balign 64
6085.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
6086/* File: arm-vfp/OP_SUB_FLOAT_2ADDR.S */
6087/* File: arm-vfp/fbinop2addr.S */
6088    /*
6089     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6090     * an "instr" line that specifies an instruction that performs
6091     * "s2 = s0 op s1".
6092     *
6093     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6094     */
6095    /* binop/2addr vA, vB */
6096    mov     r3, rINST, lsr #12          @ r3<- B
6097    mov     r9, rINST, lsr #8           @ r9<- A+
6098    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6099    and     r9, r9, #15                 @ r9<- A
6100    flds    s1, [r3]                    @ s1<- vB
6101    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6102    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6103    flds    s0, [r9]                    @ s0<- vA
6104
6105    fsubs   s2, s0, s1                              @ s2<- op
6106    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6107    fsts    s2, [r9]                    @ vAA<- s2
6108    GOTO_OPCODE(ip)                     @ jump to next instruction
6109
6110
6111/* ------------------------------ */
6112    .balign 64
6113.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
6114/* File: arm-vfp/OP_MUL_FLOAT_2ADDR.S */
6115/* File: arm-vfp/fbinop2addr.S */
6116    /*
6117     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6118     * an "instr" line that specifies an instruction that performs
6119     * "s2 = s0 op s1".
6120     *
6121     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6122     */
6123    /* binop/2addr vA, vB */
6124    mov     r3, rINST, lsr #12          @ r3<- B
6125    mov     r9, rINST, lsr #8           @ r9<- A+
6126    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6127    and     r9, r9, #15                 @ r9<- A
6128    flds    s1, [r3]                    @ s1<- vB
6129    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6130    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6131    flds    s0, [r9]                    @ s0<- vA
6132
6133    fmuls   s2, s0, s1                              @ s2<- op
6134    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6135    fsts    s2, [r9]                    @ vAA<- s2
6136    GOTO_OPCODE(ip)                     @ jump to next instruction
6137
6138
6139/* ------------------------------ */
6140    .balign 64
6141.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
6142/* File: arm-vfp/OP_DIV_FLOAT_2ADDR.S */
6143/* File: arm-vfp/fbinop2addr.S */
6144    /*
6145     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6146     * an "instr" line that specifies an instruction that performs
6147     * "s2 = s0 op s1".
6148     *
6149     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6150     */
6151    /* binop/2addr vA, vB */
6152    mov     r3, rINST, lsr #12          @ r3<- B
6153    mov     r9, rINST, lsr #8           @ r9<- A+
6154    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6155    and     r9, r9, #15                 @ r9<- A
6156    flds    s1, [r3]                    @ s1<- vB
6157    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6158    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6159    flds    s0, [r9]                    @ s0<- vA
6160
6161    fdivs   s2, s0, s1                              @ s2<- op
6162    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6163    fsts    s2, [r9]                    @ vAA<- s2
6164    GOTO_OPCODE(ip)                     @ jump to next instruction
6165
6166
6167/* ------------------------------ */
6168    .balign 64
6169.L_OP_REM_FLOAT_2ADDR: /* 0xca */
6170/* File: armv5te/OP_REM_FLOAT_2ADDR.S */
6171/* EABI doesn't define a float remainder function, but libm does */
6172/* File: armv5te/binop2addr.S */
6173    /*
6174     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6175     * that specifies an instruction that performs "result = r0 op r1".
6176     * This could be an ARM instruction or a function call.  (If the result
6177     * comes back in a register other than r0, you can override "result".)
6178     *
6179     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6180     * vCC (r1).  Useful for integer division and modulus.
6181     *
6182     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6183     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6184     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6185     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6186     */
6187    /* binop/2addr vA, vB */
6188    mov     r9, rINST, lsr #8           @ r9<- A+
6189    mov     r3, rINST, lsr #12          @ r3<- B
6190    and     r9, r9, #15
6191    GET_VREG(r1, r3)                    @ r1<- vB
6192    GET_VREG(r0, r9)                    @ r0<- vA
6193    .if 0
6194    cmp     r1, #0                      @ is second operand zero?
6195    beq     common_errDivideByZero
6196    .endif
6197    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6198
6199                               @ optional op; may set condition codes
6200    bl      fmodf                              @ r0<- op, r0-r3 changed
6201    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6202    SET_VREG(r0, r9)               @ vAA<- r0
6203    GOTO_OPCODE(ip)                     @ jump to next instruction
6204    /* 10-13 instructions */
6205
6206
6207/* ------------------------------ */
6208    .balign 64
6209.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
6210/* File: arm-vfp/OP_ADD_DOUBLE_2ADDR.S */
6211/* File: arm-vfp/fbinopWide2addr.S */
6212    /*
6213     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6214     * an "instr" line that specifies an instruction that performs
6215     * "d2 = d0 op d1".
6216     *
6217     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6218     *      div-double/2addr
6219     */
6220    /* binop/2addr vA, vB */
6221    mov     r3, rINST, lsr #12          @ r3<- B
6222    mov     r9, rINST, lsr #8           @ r9<- A+
6223    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6224    and     r9, r9, #15                 @ r9<- A
6225    fldd    d1, [r3]                    @ d1<- vB
6226    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6227    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6228    fldd    d0, [r9]                    @ d0<- vA
6229
6230    faddd   d2, d0, d1                              @ d2<- op
6231    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6232    fstd    d2, [r9]                    @ vAA<- d2
6233    GOTO_OPCODE(ip)                     @ jump to next instruction
6234
6235
6236/* ------------------------------ */
6237    .balign 64
6238.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
6239/* File: arm-vfp/OP_SUB_DOUBLE_2ADDR.S */
6240/* File: arm-vfp/fbinopWide2addr.S */
6241    /*
6242     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6243     * an "instr" line that specifies an instruction that performs
6244     * "d2 = d0 op d1".
6245     *
6246     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6247     *      div-double/2addr
6248     */
6249    /* binop/2addr vA, vB */
6250    mov     r3, rINST, lsr #12          @ r3<- B
6251    mov     r9, rINST, lsr #8           @ r9<- A+
6252    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6253    and     r9, r9, #15                 @ r9<- A
6254    fldd    d1, [r3]                    @ d1<- vB
6255    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6256    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6257    fldd    d0, [r9]                    @ d0<- vA
6258
6259    fsubd   d2, d0, d1                              @ d2<- op
6260    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6261    fstd    d2, [r9]                    @ vAA<- d2
6262    GOTO_OPCODE(ip)                     @ jump to next instruction
6263
6264
6265/* ------------------------------ */
6266    .balign 64
6267.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
6268/* File: arm-vfp/OP_MUL_DOUBLE_2ADDR.S */
6269/* File: arm-vfp/fbinopWide2addr.S */
6270    /*
6271     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6272     * an "instr" line that specifies an instruction that performs
6273     * "d2 = d0 op d1".
6274     *
6275     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6276     *      div-double/2addr
6277     */
6278    /* binop/2addr vA, vB */
6279    mov     r3, rINST, lsr #12          @ r3<- B
6280    mov     r9, rINST, lsr #8           @ r9<- A+
6281    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6282    and     r9, r9, #15                 @ r9<- A
6283    fldd    d1, [r3]                    @ d1<- vB
6284    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6285    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6286    fldd    d0, [r9]                    @ d0<- vA
6287
6288    fmuld   d2, d0, d1                              @ d2<- op
6289    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6290    fstd    d2, [r9]                    @ vAA<- d2
6291    GOTO_OPCODE(ip)                     @ jump to next instruction
6292
6293
6294/* ------------------------------ */
6295    .balign 64
6296.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */
6297/* File: arm-vfp/OP_DIV_DOUBLE_2ADDR.S */
6298/* File: arm-vfp/fbinopWide2addr.S */
6299    /*
6300     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6301     * an "instr" line that specifies an instruction that performs
6302     * "d2 = d0 op d1".
6303     *
6304     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6305     *      div-double/2addr
6306     */
6307    /* binop/2addr vA, vB */
6308    mov     r3, rINST, lsr #12          @ r3<- B
6309    mov     r9, rINST, lsr #8           @ r9<- A+
6310    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6311    and     r9, r9, #15                 @ r9<- A
6312    fldd    d1, [r3]                    @ d1<- vB
6313    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6314    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6315    fldd    d0, [r9]                    @ d0<- vA
6316
6317    fdivd   d2, d0, d1                              @ d2<- op
6318    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6319    fstd    d2, [r9]                    @ vAA<- d2
6320    GOTO_OPCODE(ip)                     @ jump to next instruction
6321
6322
6323/* ------------------------------ */
6324    .balign 64
6325.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */
6326/* File: armv5te/OP_REM_DOUBLE_2ADDR.S */
6327/* EABI doesn't define a double remainder function, but libm does */
6328/* File: armv5te/binopWide2addr.S */
6329    /*
6330     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6331     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6332     * This could be an ARM instruction or a function call.  (If the result
6333     * comes back in a register other than r0, you can override "result".)
6334     *
6335     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6336     * vCC (r1).  Useful for integer division and modulus.
6337     *
6338     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6339     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6340     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6341     *      rem-double/2addr
6342     */
6343    /* binop/2addr vA, vB */
6344    mov     r9, rINST, lsr #8           @ r9<- A+
6345    mov     r1, rINST, lsr #12          @ r1<- B
6346    and     r9, r9, #15
6347    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6348    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6349    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6350    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6351    .if 0
6352    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6353    beq     common_errDivideByZero
6354    .endif
6355    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6356
6357                               @ optional op; may set condition codes
6358    bl      fmod                              @ result<- op, r0-r3 changed
6359    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6360    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6361    GOTO_OPCODE(ip)                     @ jump to next instruction
6362    /* 12-15 instructions */
6363
6364
6365/* ------------------------------ */
6366    .balign 64
6367.L_OP_ADD_INT_LIT16: /* 0xd0 */
6368/* File: armv5te/OP_ADD_INT_LIT16.S */
6369/* File: armv5te/binopLit16.S */
6370    /*
6371     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6372     * that specifies an instruction that performs "result = r0 op r1".
6373     * This could be an ARM instruction or a function call.  (If the result
6374     * comes back in a register other than r0, you can override "result".)
6375     *
6376     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6377     * vCC (r1).  Useful for integer division and modulus.
6378     *
6379     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6380     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6381     */
6382    /* binop/lit16 vA, vB, #+CCCC */
6383    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6384    mov     r2, rINST, lsr #12          @ r2<- B
6385    mov     r9, rINST, lsr #8           @ r9<- A+
6386    GET_VREG(r0, r2)                    @ r0<- vB
6387    and     r9, r9, #15
6388    .if 0
6389    cmp     r1, #0                      @ is second operand zero?
6390    beq     common_errDivideByZero
6391    .endif
6392    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6393
6394    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
6395    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6396    SET_VREG(r0, r9)               @ vAA<- r0
6397    GOTO_OPCODE(ip)                     @ jump to next instruction
6398    /* 10-13 instructions */
6399
6400
6401/* ------------------------------ */
6402    .balign 64
6403.L_OP_RSUB_INT: /* 0xd1 */
6404/* File: armv5te/OP_RSUB_INT.S */
6405/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
6406/* File: armv5te/binopLit16.S */
6407    /*
6408     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6409     * that specifies an instruction that performs "result = r0 op r1".
6410     * This could be an ARM instruction or a function call.  (If the result
6411     * comes back in a register other than r0, you can override "result".)
6412     *
6413     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6414     * vCC (r1).  Useful for integer division and modulus.
6415     *
6416     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6417     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6418     */
6419    /* binop/lit16 vA, vB, #+CCCC */
6420    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6421    mov     r2, rINST, lsr #12          @ r2<- B
6422    mov     r9, rINST, lsr #8           @ r9<- A+
6423    GET_VREG(r0, r2)                    @ r0<- vB
6424    and     r9, r9, #15
6425    .if 0
6426    cmp     r1, #0                      @ is second operand zero?
6427    beq     common_errDivideByZero
6428    .endif
6429    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6430
6431    rsb     r0, r0, r1                              @ r0<- op, r0-r3 changed
6432    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6433    SET_VREG(r0, r9)               @ vAA<- r0
6434    GOTO_OPCODE(ip)                     @ jump to next instruction
6435    /* 10-13 instructions */
6436
6437
6438/* ------------------------------ */
6439    .balign 64
6440.L_OP_MUL_INT_LIT16: /* 0xd2 */
6441/* File: armv5te/OP_MUL_INT_LIT16.S */
6442/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
6443/* File: armv5te/binopLit16.S */
6444    /*
6445     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6446     * that specifies an instruction that performs "result = r0 op r1".
6447     * This could be an ARM instruction or a function call.  (If the result
6448     * comes back in a register other than r0, you can override "result".)
6449     *
6450     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6451     * vCC (r1).  Useful for integer division and modulus.
6452     *
6453     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6454     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6455     */
6456    /* binop/lit16 vA, vB, #+CCCC */
6457    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6458    mov     r2, rINST, lsr #12          @ r2<- B
6459    mov     r9, rINST, lsr #8           @ r9<- A+
6460    GET_VREG(r0, r2)                    @ r0<- vB
6461    and     r9, r9, #15
6462    .if 0
6463    cmp     r1, #0                      @ is second operand zero?
6464    beq     common_errDivideByZero
6465    .endif
6466    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6467
6468    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
6469    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6470    SET_VREG(r0, r9)               @ vAA<- r0
6471    GOTO_OPCODE(ip)                     @ jump to next instruction
6472    /* 10-13 instructions */
6473
6474
6475/* ------------------------------ */
6476    .balign 64
6477.L_OP_DIV_INT_LIT16: /* 0xd3 */
6478/* File: armv5te/OP_DIV_INT_LIT16.S */
6479/* File: armv5te/binopLit16.S */
6480    /*
6481     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6482     * that specifies an instruction that performs "result = r0 op r1".
6483     * This could be an ARM instruction or a function call.  (If the result
6484     * comes back in a register other than r0, you can override "result".)
6485     *
6486     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6487     * vCC (r1).  Useful for integer division and modulus.
6488     *
6489     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6490     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6491     */
6492    /* binop/lit16 vA, vB, #+CCCC */
6493    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6494    mov     r2, rINST, lsr #12          @ r2<- B
6495    mov     r9, rINST, lsr #8           @ r9<- A+
6496    GET_VREG(r0, r2)                    @ r0<- vB
6497    and     r9, r9, #15
6498    .if 1
6499    cmp     r1, #0                      @ is second operand zero?
6500    beq     common_errDivideByZero
6501    .endif
6502    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6503
6504    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
6505    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6506    SET_VREG(r0, r9)               @ vAA<- r0
6507    GOTO_OPCODE(ip)                     @ jump to next instruction
6508    /* 10-13 instructions */
6509
6510
6511/* ------------------------------ */
6512    .balign 64
6513.L_OP_REM_INT_LIT16: /* 0xd4 */
6514/* File: armv5te/OP_REM_INT_LIT16.S */
6515/* idivmod returns quotient in r0 and remainder in r1 */
6516/* File: armv5te/binopLit16.S */
6517    /*
6518     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6519     * that specifies an instruction that performs "result = r0 op r1".
6520     * This could be an ARM instruction or a function call.  (If the result
6521     * comes back in a register other than r0, you can override "result".)
6522     *
6523     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6524     * vCC (r1).  Useful for integer division and modulus.
6525     *
6526     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6527     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6528     */
6529    /* binop/lit16 vA, vB, #+CCCC */
6530    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6531    mov     r2, rINST, lsr #12          @ r2<- B
6532    mov     r9, rINST, lsr #8           @ r9<- A+
6533    GET_VREG(r0, r2)                    @ r0<- vB
6534    and     r9, r9, #15
6535    .if 1
6536    cmp     r1, #0                      @ is second operand zero?
6537    beq     common_errDivideByZero
6538    .endif
6539    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6540
6541    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
6542    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6543    SET_VREG(r1, r9)               @ vAA<- r1
6544    GOTO_OPCODE(ip)                     @ jump to next instruction
6545    /* 10-13 instructions */
6546
6547
6548/* ------------------------------ */
6549    .balign 64
6550.L_OP_AND_INT_LIT16: /* 0xd5 */
6551/* File: armv5te/OP_AND_INT_LIT16.S */
6552/* File: armv5te/binopLit16.S */
6553    /*
6554     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6555     * that specifies an instruction that performs "result = r0 op r1".
6556     * This could be an ARM instruction or a function call.  (If the result
6557     * comes back in a register other than r0, you can override "result".)
6558     *
6559     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6560     * vCC (r1).  Useful for integer division and modulus.
6561     *
6562     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6563     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6564     */
6565    /* binop/lit16 vA, vB, #+CCCC */
6566    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6567    mov     r2, rINST, lsr #12          @ r2<- B
6568    mov     r9, rINST, lsr #8           @ r9<- A+
6569    GET_VREG(r0, r2)                    @ r0<- vB
6570    and     r9, r9, #15
6571    .if 0
6572    cmp     r1, #0                      @ is second operand zero?
6573    beq     common_errDivideByZero
6574    .endif
6575    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6576
6577    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
6578    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6579    SET_VREG(r0, r9)               @ vAA<- r0
6580    GOTO_OPCODE(ip)                     @ jump to next instruction
6581    /* 10-13 instructions */
6582
6583
6584/* ------------------------------ */
6585    .balign 64
6586.L_OP_OR_INT_LIT16: /* 0xd6 */
6587/* File: armv5te/OP_OR_INT_LIT16.S */
6588/* File: armv5te/binopLit16.S */
6589    /*
6590     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6591     * that specifies an instruction that performs "result = r0 op r1".
6592     * This could be an ARM instruction or a function call.  (If the result
6593     * comes back in a register other than r0, you can override "result".)
6594     *
6595     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6596     * vCC (r1).  Useful for integer division and modulus.
6597     *
6598     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6599     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6600     */
6601    /* binop/lit16 vA, vB, #+CCCC */
6602    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6603    mov     r2, rINST, lsr #12          @ r2<- B
6604    mov     r9, rINST, lsr #8           @ r9<- A+
6605    GET_VREG(r0, r2)                    @ r0<- vB
6606    and     r9, r9, #15
6607    .if 0
6608    cmp     r1, #0                      @ is second operand zero?
6609    beq     common_errDivideByZero
6610    .endif
6611    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6612
6613    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
6614    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6615    SET_VREG(r0, r9)               @ vAA<- r0
6616    GOTO_OPCODE(ip)                     @ jump to next instruction
6617    /* 10-13 instructions */
6618
6619
6620/* ------------------------------ */
6621    .balign 64
6622.L_OP_XOR_INT_LIT16: /* 0xd7 */
6623/* File: armv5te/OP_XOR_INT_LIT16.S */
6624/* File: armv5te/binopLit16.S */
6625    /*
6626     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6627     * that specifies an instruction that performs "result = r0 op r1".
6628     * This could be an ARM instruction or a function call.  (If the result
6629     * comes back in a register other than r0, you can override "result".)
6630     *
6631     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6632     * vCC (r1).  Useful for integer division and modulus.
6633     *
6634     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6635     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6636     */
6637    /* binop/lit16 vA, vB, #+CCCC */
6638    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6639    mov     r2, rINST, lsr #12          @ r2<- B
6640    mov     r9, rINST, lsr #8           @ r9<- A+
6641    GET_VREG(r0, r2)                    @ r0<- vB
6642    and     r9, r9, #15
6643    .if 0
6644    cmp     r1, #0                      @ is second operand zero?
6645    beq     common_errDivideByZero
6646    .endif
6647    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6648
6649    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
6650    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6651    SET_VREG(r0, r9)               @ vAA<- r0
6652    GOTO_OPCODE(ip)                     @ jump to next instruction
6653    /* 10-13 instructions */
6654
6655
6656/* ------------------------------ */
6657    .balign 64
6658.L_OP_ADD_INT_LIT8: /* 0xd8 */
6659/* File: armv5te/OP_ADD_INT_LIT8.S */
6660/* File: armv5te/binopLit8.S */
6661    /*
6662     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6663     * that specifies an instruction that performs "result = r0 op r1".
6664     * This could be an ARM instruction or a function call.  (If the result
6665     * comes back in a register other than r0, you can override "result".)
6666     *
6667     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6668     * vCC (r1).  Useful for integer division and modulus.
6669     *
6670     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6671     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6672     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6673     */
6674    /* binop/lit8 vAA, vBB, #+CC */
6675    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6676    mov     r9, rINST, lsr #8           @ r9<- AA
6677    and     r2, r3, #255                @ r2<- BB
6678    GET_VREG(r0, r2)                    @ r0<- vBB
6679    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6680    .if 0
6681    @cmp     r1, #0                      @ is second operand zero?
6682    beq     common_errDivideByZero
6683    .endif
6684    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6685
6686                               @ optional op; may set condition codes
6687    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
6688    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6689    SET_VREG(r0, r9)               @ vAA<- r0
6690    GOTO_OPCODE(ip)                     @ jump to next instruction
6691    /* 10-12 instructions */
6692
6693
6694/* ------------------------------ */
6695    .balign 64
6696.L_OP_RSUB_INT_LIT8: /* 0xd9 */
6697/* File: armv5te/OP_RSUB_INT_LIT8.S */
6698/* File: armv5te/binopLit8.S */
6699    /*
6700     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6701     * that specifies an instruction that performs "result = r0 op r1".
6702     * This could be an ARM instruction or a function call.  (If the result
6703     * comes back in a register other than r0, you can override "result".)
6704     *
6705     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6706     * vCC (r1).  Useful for integer division and modulus.
6707     *
6708     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6709     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6710     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6711     */
6712    /* binop/lit8 vAA, vBB, #+CC */
6713    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6714    mov     r9, rINST, lsr #8           @ r9<- AA
6715    and     r2, r3, #255                @ r2<- BB
6716    GET_VREG(r0, r2)                    @ r0<- vBB
6717    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6718    .if 0
6719    @cmp     r1, #0                      @ is second operand zero?
6720    beq     common_errDivideByZero
6721    .endif
6722    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6723
6724                               @ optional op; may set condition codes
6725    rsb     r0, r0, r1                              @ r0<- op, r0-r3 changed
6726    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6727    SET_VREG(r0, r9)               @ vAA<- r0
6728    GOTO_OPCODE(ip)                     @ jump to next instruction
6729    /* 10-12 instructions */
6730
6731
6732/* ------------------------------ */
6733    .balign 64
6734.L_OP_MUL_INT_LIT8: /* 0xda */
6735/* File: armv5te/OP_MUL_INT_LIT8.S */
6736/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
6737/* File: armv5te/binopLit8.S */
6738    /*
6739     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6740     * that specifies an instruction that performs "result = r0 op r1".
6741     * This could be an ARM instruction or a function call.  (If the result
6742     * comes back in a register other than r0, you can override "result".)
6743     *
6744     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6745     * vCC (r1).  Useful for integer division and modulus.
6746     *
6747     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6748     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6749     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6750     */
6751    /* binop/lit8 vAA, vBB, #+CC */
6752    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6753    mov     r9, rINST, lsr #8           @ r9<- AA
6754    and     r2, r3, #255                @ r2<- BB
6755    GET_VREG(r0, r2)                    @ r0<- vBB
6756    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6757    .if 0
6758    @cmp     r1, #0                      @ is second operand zero?
6759    beq     common_errDivideByZero
6760    .endif
6761    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6762
6763                               @ optional op; may set condition codes
6764    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
6765    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6766    SET_VREG(r0, r9)               @ vAA<- r0
6767    GOTO_OPCODE(ip)                     @ jump to next instruction
6768    /* 10-12 instructions */
6769
6770
6771/* ------------------------------ */
6772    .balign 64
6773.L_OP_DIV_INT_LIT8: /* 0xdb */
6774/* File: armv5te/OP_DIV_INT_LIT8.S */
6775/* File: armv5te/binopLit8.S */
6776    /*
6777     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6778     * that specifies an instruction that performs "result = r0 op r1".
6779     * This could be an ARM instruction or a function call.  (If the result
6780     * comes back in a register other than r0, you can override "result".)
6781     *
6782     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6783     * vCC (r1).  Useful for integer division and modulus.
6784     *
6785     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6786     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6787     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6788     */
6789    /* binop/lit8 vAA, vBB, #+CC */
6790    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6791    mov     r9, rINST, lsr #8           @ r9<- AA
6792    and     r2, r3, #255                @ r2<- BB
6793    GET_VREG(r0, r2)                    @ r0<- vBB
6794    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6795    .if 1
6796    @cmp     r1, #0                      @ is second operand zero?
6797    beq     common_errDivideByZero
6798    .endif
6799    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6800
6801                               @ optional op; may set condition codes
6802    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
6803    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6804    SET_VREG(r0, r9)               @ vAA<- r0
6805    GOTO_OPCODE(ip)                     @ jump to next instruction
6806    /* 10-12 instructions */
6807
6808
6809/* ------------------------------ */
6810    .balign 64
6811.L_OP_REM_INT_LIT8: /* 0xdc */
6812/* File: armv5te/OP_REM_INT_LIT8.S */
6813/* idivmod returns quotient in r0 and remainder in r1 */
6814/* File: armv5te/binopLit8.S */
6815    /*
6816     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6817     * that specifies an instruction that performs "result = r0 op r1".
6818     * This could be an ARM instruction or a function call.  (If the result
6819     * comes back in a register other than r0, you can override "result".)
6820     *
6821     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6822     * vCC (r1).  Useful for integer division and modulus.
6823     *
6824     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6825     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6826     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6827     */
6828    /* binop/lit8 vAA, vBB, #+CC */
6829    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6830    mov     r9, rINST, lsr #8           @ r9<- AA
6831    and     r2, r3, #255                @ r2<- BB
6832    GET_VREG(r0, r2)                    @ r0<- vBB
6833    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6834    .if 1
6835    @cmp     r1, #0                      @ is second operand zero?
6836    beq     common_errDivideByZero
6837    .endif
6838    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6839
6840                               @ optional op; may set condition codes
6841    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
6842    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6843    SET_VREG(r1, r9)               @ vAA<- r1
6844    GOTO_OPCODE(ip)                     @ jump to next instruction
6845    /* 10-12 instructions */
6846
6847
6848/* ------------------------------ */
6849    .balign 64
6850.L_OP_AND_INT_LIT8: /* 0xdd */
6851/* File: armv5te/OP_AND_INT_LIT8.S */
6852/* File: armv5te/binopLit8.S */
6853    /*
6854     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6855     * that specifies an instruction that performs "result = r0 op r1".
6856     * This could be an ARM instruction or a function call.  (If the result
6857     * comes back in a register other than r0, you can override "result".)
6858     *
6859     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6860     * vCC (r1).  Useful for integer division and modulus.
6861     *
6862     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6863     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6864     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6865     */
6866    /* binop/lit8 vAA, vBB, #+CC */
6867    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6868    mov     r9, rINST, lsr #8           @ r9<- AA
6869    and     r2, r3, #255                @ r2<- BB
6870    GET_VREG(r0, r2)                    @ r0<- vBB
6871    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6872    .if 0
6873    @cmp     r1, #0                      @ is second operand zero?
6874    beq     common_errDivideByZero
6875    .endif
6876    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6877
6878                               @ optional op; may set condition codes
6879    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
6880    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6881    SET_VREG(r0, r9)               @ vAA<- r0
6882    GOTO_OPCODE(ip)                     @ jump to next instruction
6883    /* 10-12 instructions */
6884
6885
6886/* ------------------------------ */
6887    .balign 64
6888.L_OP_OR_INT_LIT8: /* 0xde */
6889/* File: armv5te/OP_OR_INT_LIT8.S */
6890/* File: armv5te/binopLit8.S */
6891    /*
6892     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6893     * that specifies an instruction that performs "result = r0 op r1".
6894     * This could be an ARM instruction or a function call.  (If the result
6895     * comes back in a register other than r0, you can override "result".)
6896     *
6897     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6898     * vCC (r1).  Useful for integer division and modulus.
6899     *
6900     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6901     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6902     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6903     */
6904    /* binop/lit8 vAA, vBB, #+CC */
6905    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6906    mov     r9, rINST, lsr #8           @ r9<- AA
6907    and     r2, r3, #255                @ r2<- BB
6908    GET_VREG(r0, r2)                    @ r0<- vBB
6909    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6910    .if 0
6911    @cmp     r1, #0                      @ is second operand zero?
6912    beq     common_errDivideByZero
6913    .endif
6914    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6915
6916                               @ optional op; may set condition codes
6917    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
6918    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6919    SET_VREG(r0, r9)               @ vAA<- r0
6920    GOTO_OPCODE(ip)                     @ jump to next instruction
6921    /* 10-12 instructions */
6922
6923
6924/* ------------------------------ */
6925    .balign 64
6926.L_OP_XOR_INT_LIT8: /* 0xdf */
6927/* File: armv5te/OP_XOR_INT_LIT8.S */
6928/* File: armv5te/binopLit8.S */
6929    /*
6930     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6931     * that specifies an instruction that performs "result = r0 op r1".
6932     * This could be an ARM instruction or a function call.  (If the result
6933     * comes back in a register other than r0, you can override "result".)
6934     *
6935     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6936     * vCC (r1).  Useful for integer division and modulus.
6937     *
6938     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6939     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6940     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6941     */
6942    /* binop/lit8 vAA, vBB, #+CC */
6943    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6944    mov     r9, rINST, lsr #8           @ r9<- AA
6945    and     r2, r3, #255                @ r2<- BB
6946    GET_VREG(r0, r2)                    @ r0<- vBB
6947    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6948    .if 0
6949    @cmp     r1, #0                      @ is second operand zero?
6950    beq     common_errDivideByZero
6951    .endif
6952    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6953
6954                               @ optional op; may set condition codes
6955    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
6956    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6957    SET_VREG(r0, r9)               @ vAA<- r0
6958    GOTO_OPCODE(ip)                     @ jump to next instruction
6959    /* 10-12 instructions */
6960
6961
6962/* ------------------------------ */
6963    .balign 64
6964.L_OP_SHL_INT_LIT8: /* 0xe0 */
6965/* File: armv5te/OP_SHL_INT_LIT8.S */
6966/* File: armv5te/binopLit8.S */
6967    /*
6968     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6969     * that specifies an instruction that performs "result = r0 op r1".
6970     * This could be an ARM instruction or a function call.  (If the result
6971     * comes back in a register other than r0, you can override "result".)
6972     *
6973     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6974     * vCC (r1).  Useful for integer division and modulus.
6975     *
6976     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6977     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6978     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6979     */
6980    /* binop/lit8 vAA, vBB, #+CC */
6981    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6982    mov     r9, rINST, lsr #8           @ r9<- AA
6983    and     r2, r3, #255                @ r2<- BB
6984    GET_VREG(r0, r2)                    @ r0<- vBB
6985    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6986    .if 0
6987    @cmp     r1, #0                      @ is second operand zero?
6988    beq     common_errDivideByZero
6989    .endif
6990    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6991
6992    and     r1, r1, #31                           @ optional op; may set condition codes
6993    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
6994    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6995    SET_VREG(r0, r9)               @ vAA<- r0
6996    GOTO_OPCODE(ip)                     @ jump to next instruction
6997    /* 10-12 instructions */
6998
6999
7000/* ------------------------------ */
7001    .balign 64
7002.L_OP_SHR_INT_LIT8: /* 0xe1 */
7003/* File: armv5te/OP_SHR_INT_LIT8.S */
7004/* File: armv5te/binopLit8.S */
7005    /*
7006     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7007     * that specifies an instruction that performs "result = r0 op r1".
7008     * This could be an ARM instruction or a function call.  (If the result
7009     * comes back in a register other than r0, you can override "result".)
7010     *
7011     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7012     * vCC (r1).  Useful for integer division and modulus.
7013     *
7014     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7015     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7016     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7017     */
7018    /* binop/lit8 vAA, vBB, #+CC */
7019    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7020    mov     r9, rINST, lsr #8           @ r9<- AA
7021    and     r2, r3, #255                @ r2<- BB
7022    GET_VREG(r0, r2)                    @ r0<- vBB
7023    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7024    .if 0
7025    @cmp     r1, #0                      @ is second operand zero?
7026    beq     common_errDivideByZero
7027    .endif
7028    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7029
7030    and     r1, r1, #31                           @ optional op; may set condition codes
7031    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
7032    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7033    SET_VREG(r0, r9)               @ vAA<- r0
7034    GOTO_OPCODE(ip)                     @ jump to next instruction
7035    /* 10-12 instructions */
7036
7037
7038/* ------------------------------ */
7039    .balign 64
7040.L_OP_USHR_INT_LIT8: /* 0xe2 */
7041/* File: armv5te/OP_USHR_INT_LIT8.S */
7042/* File: armv5te/binopLit8.S */
7043    /*
7044     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7045     * that specifies an instruction that performs "result = r0 op r1".
7046     * This could be an ARM instruction or a function call.  (If the result
7047     * comes back in a register other than r0, you can override "result".)
7048     *
7049     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7050     * vCC (r1).  Useful for integer division and modulus.
7051     *
7052     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7053     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7054     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7055     */
7056    /* binop/lit8 vAA, vBB, #+CC */
7057    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7058    mov     r9, rINST, lsr #8           @ r9<- AA
7059    and     r2, r3, #255                @ r2<- BB
7060    GET_VREG(r0, r2)                    @ r0<- vBB
7061    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7062    .if 0
7063    @cmp     r1, #0                      @ is second operand zero?
7064    beq     common_errDivideByZero
7065    .endif
7066    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7067
7068    and     r1, r1, #31                           @ optional op; may set condition codes
7069    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
7070    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7071    SET_VREG(r0, r9)               @ vAA<- r0
7072    GOTO_OPCODE(ip)                     @ jump to next instruction
7073    /* 10-12 instructions */
7074
7075
7076/* ------------------------------ */
7077    .balign 64
7078.L_OP_IGET_VOLATILE: /* 0xe3 */
7079/* File: armv5te/OP_IGET_VOLATILE.S */
7080/* File: armv5te/OP_IGET.S */
7081    /*
7082     * General 32-bit instance field get.
7083     *
7084     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7085     */
7086    /* op vA, vB, field@CCCC */
7087    mov     r0, rINST, lsr #12          @ r0<- B
7088    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7089    FETCH(r1, 1)                        @ r1<- field ref CCCC
7090    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7091    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7092    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7093    cmp     r0, #0                      @ is resolved entry null?
7094    bne     .LOP_IGET_VOLATILE_finish          @ no, already resolved
70958:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7096    EXPORT_PC()                         @ resolve() could throw
7097    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7098    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7099    cmp     r0, #0
7100    bne     .LOP_IGET_VOLATILE_finish
7101    b       common_exceptionThrown
7102
7103
7104/* ------------------------------ */
7105    .balign 64
7106.L_OP_IPUT_VOLATILE: /* 0xe4 */
7107/* File: armv5te/OP_IPUT_VOLATILE.S */
7108/* File: armv5te/OP_IPUT.S */
7109    /*
7110     * General 32-bit instance field put.
7111     *
7112     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
7113     */
7114    /* op vA, vB, field@CCCC */
7115    mov     r0, rINST, lsr #12          @ r0<- B
7116    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7117    FETCH(r1, 1)                        @ r1<- field ref CCCC
7118    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7119    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7120    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7121    cmp     r0, #0                      @ is resolved entry null?
7122    bne     .LOP_IPUT_VOLATILE_finish          @ no, already resolved
71238:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7124    EXPORT_PC()                         @ resolve() could throw
7125    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7126    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7127    cmp     r0, #0                      @ success?
7128    bne     .LOP_IPUT_VOLATILE_finish          @ yes, finish up
7129    b       common_exceptionThrown
7130
7131
7132/* ------------------------------ */
7133    .balign 64
7134.L_OP_SGET_VOLATILE: /* 0xe5 */
7135/* File: armv5te/OP_SGET_VOLATILE.S */
7136/* File: armv5te/OP_SGET.S */
7137    /*
7138     * General 32-bit SGET handler.
7139     *
7140     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7141     */
7142    /* op vAA, field@BBBB */
7143    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7144    FETCH(r1, 1)                        @ r1<- field ref BBBB
7145    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7146    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7147    cmp     r0, #0                      @ is resolved entry null?
7148    beq     .LOP_SGET_VOLATILE_resolve         @ yes, do resolve
7149.LOP_SGET_VOLATILE_finish: @ field ptr in r0
7150    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7151    SMP_DMB                            @ acquiring load
7152    mov     r2, rINST, lsr #8           @ r2<- AA
7153    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7154    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7155    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7156    GOTO_OPCODE(ip)                     @ jump to next instruction
7157
7158
7159/* ------------------------------ */
7160    .balign 64
7161.L_OP_SPUT_VOLATILE: /* 0xe6 */
7162/* File: armv5te/OP_SPUT_VOLATILE.S */
7163/* File: armv5te/OP_SPUT.S */
7164    /*
7165     * General 32-bit SPUT handler.
7166     *
7167     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
7168     */
7169    /* op vAA, field@BBBB */
7170    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7171    FETCH(r1, 1)                        @ r1<- field ref BBBB
7172    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7173    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7174    cmp     r0, #0                      @ is resolved entry null?
7175    beq     .LOP_SPUT_VOLATILE_resolve         @ yes, do resolve
7176.LOP_SPUT_VOLATILE_finish:   @ field ptr in r0
7177    mov     r2, rINST, lsr #8           @ r2<- AA
7178    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7179    GET_VREG(r1, r2)                    @ r1<- fp[AA]
7180    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7181    SMP_DMB                            @ releasing store
7182    str     r1, [r0, #offStaticField_value] @ field<- vAA
7183    GOTO_OPCODE(ip)                     @ jump to next instruction
7184
7185
7186/* ------------------------------ */
7187    .balign 64
7188.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
7189/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */
7190/* File: armv5te/OP_IGET.S */
7191    /*
7192     * General 32-bit instance field get.
7193     *
7194     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7195     */
7196    /* op vA, vB, field@CCCC */
7197    mov     r0, rINST, lsr #12          @ r0<- B
7198    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7199    FETCH(r1, 1)                        @ r1<- field ref CCCC
7200    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7201    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7202    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7203    cmp     r0, #0                      @ is resolved entry null?
7204    bne     .LOP_IGET_OBJECT_VOLATILE_finish          @ no, already resolved
72058:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7206    EXPORT_PC()                         @ resolve() could throw
7207    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7208    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7209    cmp     r0, #0
7210    bne     .LOP_IGET_OBJECT_VOLATILE_finish
7211    b       common_exceptionThrown
7212
7213
7214/* ------------------------------ */
7215    .balign 64
7216.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
7217/* File: armv5te/OP_IGET_WIDE_VOLATILE.S */
7218/* File: armv5te/OP_IGET_WIDE.S */
7219    /*
7220     * Wide 32-bit instance field get.
7221     */
7222    /* iget-wide vA, vB, field@CCCC */
7223    mov     r0, rINST, lsr #12          @ r0<- B
7224    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7225    FETCH(r1, 1)                        @ r1<- field ref CCCC
7226    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7227    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7228    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7229    cmp     r0, #0                      @ is resolved entry null?
7230    bne     .LOP_IGET_WIDE_VOLATILE_finish          @ no, already resolved
72318:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
7232    EXPORT_PC()                         @ resolve() could throw
7233    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7234    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7235    cmp     r0, #0
7236    bne     .LOP_IGET_WIDE_VOLATILE_finish
7237    b       common_exceptionThrown
7238
7239
7240/* ------------------------------ */
7241    .balign 64
7242.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
7243/* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */
7244/* File: armv5te/OP_IPUT_WIDE.S */
7245    /* iput-wide vA, vB, field@CCCC */
7246    mov     r0, rINST, lsr #12          @ r0<- B
7247    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7248    FETCH(r1, 1)                        @ r1<- field ref CCCC
7249    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7250    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7251    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7252    cmp     r0, #0                      @ is resolved entry null?
7253    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ no, already resolved
72548:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
7255    EXPORT_PC()                         @ resolve() could throw
7256    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7257    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7258    cmp     r0, #0                      @ success?
7259    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ yes, finish up
7260    b       common_exceptionThrown
7261
7262
7263/* ------------------------------ */
7264    .balign 64
7265.L_OP_SGET_WIDE_VOLATILE: /* 0xea */
7266/* File: armv5te/OP_SGET_WIDE_VOLATILE.S */
7267/* File: armv5te/OP_SGET_WIDE.S */
7268    /*
7269     * 64-bit SGET handler.
7270     */
7271    /* sget-wide vAA, field@BBBB */
7272    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7273    FETCH(r1, 1)                        @ r1<- field ref BBBB
7274    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7275    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7276    cmp     r0, #0                      @ is resolved entry null?
7277    beq     .LOP_SGET_WIDE_VOLATILE_resolve         @ yes, do resolve
7278.LOP_SGET_WIDE_VOLATILE_finish:
7279    mov     r9, rINST, lsr #8           @ r9<- AA
7280    .if 1
7281    add     r0, r0, #offStaticField_value @ r0<- pointer to data
7282    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
7283    .else
7284    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
7285    .endif
7286    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7287    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7288    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
7289    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7290    GOTO_OPCODE(ip)                     @ jump to next instruction
7291
7292
7293/* ------------------------------ */
7294    .balign 64
7295.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
7296/* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */
7297/* File: armv5te/OP_SPUT_WIDE.S */
7298    /*
7299     * 64-bit SPUT handler.
7300     */
7301    /* sput-wide vAA, field@BBBB */
7302    ldr     r0, [rSELF, #offThread_methodClassDex]  @ r0<- DvmDex
7303    FETCH(r1, 1)                        @ r1<- field ref BBBB
7304    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
7305    mov     r9, rINST, lsr #8           @ r9<- AA
7306    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
7307    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7308    cmp     r2, #0                      @ is resolved entry null?
7309    beq     .LOP_SPUT_WIDE_VOLATILE_resolve         @ yes, do resolve
7310.LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9
7311    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7312    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
7313    GET_INST_OPCODE(r10)                @ extract opcode from rINST
7314    .if 1
7315    add     r2, r2, #offStaticField_value @ r2<- pointer to data
7316    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
7317    .else
7318    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
7319    .endif
7320    GOTO_OPCODE(r10)                    @ jump to next instruction
7321
7322
7323/* ------------------------------ */
7324    .balign 64
7325.L_OP_BREAKPOINT: /* 0xec */
7326/* File: armv5te/OP_BREAKPOINT.S */
7327/* File: armv5te/unused.S */
7328    bl      common_abort
7329
7330
7331/* ------------------------------ */
7332    .balign 64
7333.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
7334/* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */
7335    /*
7336     * Handle a throw-verification-error instruction.  This throws an
7337     * exception for an error discovered during verification.  The
7338     * exception is indicated by AA, with some detail provided by BBBB.
7339     */
7340    /* op AA, ref@BBBB */
7341    ldr     r0, [rSELF, #offThread_method]    @ r0<- self->method
7342    FETCH(r2, 1)                        @ r2<- BBBB
7343    EXPORT_PC()                         @ export the PC
7344    mov     r1, rINST, lsr #8           @ r1<- AA
7345    bl      dvmThrowVerificationError   @ always throws
7346    b       common_exceptionThrown      @ handle exception
7347
7348/* ------------------------------ */
7349    .balign 64
7350.L_OP_EXECUTE_INLINE: /* 0xee */
7351/* File: armv5te/OP_EXECUTE_INLINE.S */
7352    /*
7353     * Execute a "native inline" instruction.
7354     *
7355     * We need to call an InlineOp4Func:
7356     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7357     *
7358     * The first four args are in r0-r3, pointer to return value storage
7359     * is on the stack.  The function's return value is a flag that tells
7360     * us if an exception was thrown.
7361     */
7362    /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
7363    FETCH(r10, 1)                       @ r10<- BBBB
7364    add     r1, rSELF, #offThread_retval  @ r1<- &self->retval
7365    EXPORT_PC()                         @ can throw
7366    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7367    mov     r0, rINST, lsr #12          @ r0<- B
7368    str     r1, [sp]                    @ push &self->retval
7369    bl      .LOP_EXECUTE_INLINE_continue        @ make call; will return after
7370    add     sp, sp, #8                  @ pop stack
7371    cmp     r0, #0                      @ test boolean result of inline
7372    beq     common_exceptionThrown      @ returned false, handle exception
7373    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7374    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7375    GOTO_OPCODE(ip)                     @ jump to next instruction
7376
7377/* ------------------------------ */
7378    .balign 64
7379.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
7380/* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */
7381    /*
7382     * Execute a "native inline" instruction, using "/range" semantics.
7383     * Same idea as execute-inline, but we get the args differently.
7384     *
7385     * We need to call an InlineOp4Func:
7386     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7387     *
7388     * The first four args are in r0-r3, pointer to return value storage
7389     * is on the stack.  The function's return value is a flag that tells
7390     * us if an exception was thrown.
7391     */
7392    /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */
7393    FETCH(r10, 1)                       @ r10<- BBBB
7394    add     r1, rSELF, #offThread_retval  @ r1<- &self->retval
7395    EXPORT_PC()                         @ can throw
7396    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7397    mov     r0, rINST, lsr #8           @ r0<- AA
7398    str     r1, [sp]                    @ push &self->retval
7399    bl      .LOP_EXECUTE_INLINE_RANGE_continue        @ make call; will return after
7400    add     sp, sp, #8                  @ pop stack
7401    cmp     r0, #0                      @ test boolean result of inline
7402    beq     common_exceptionThrown      @ returned false, handle exception
7403    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7404    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7405    GOTO_OPCODE(ip)                     @ jump to next instruction
7406
7407/* ------------------------------ */
7408    .balign 64
7409.L_OP_INVOKE_OBJECT_INIT: /* 0xf0 */
7410/* File: armv5te/OP_INVOKE_OBJECT_INIT.S */
7411    /*
7412     * Invoke Object.<init> on an object.  In practice we know that
7413     * Object's nullary constructor doesn't do anything, so we just
7414     * skip it (we know a debugger isn't active).
7415     */
7416    FETCH(r0, 2)                        @ r0<- GFED
7417    and     r1, r0, #15                 @ r1<- D
7418    GET_VREG(r0, r1)                    @ r0<- "this" ptr
7419    cmp     r0, #0                      @ check for NULL
7420    beq     common_errNullObject        @ export PC and throw NPE
7421    ldr     r1, [r0, #offObject_clazz]  @ r1<- obj->clazz
7422    ldr     r2, [r1, #offClassObject_accessFlags] @ r2<- clazz->accessFlags
7423    tst     r2, #CLASS_ISFINALIZABLE    @ is this class finalizable?
7424    beq     1f                          @ nope, done
7425    bl      dvmSetFinalizable           @ call dvmSetFinalizable(obj)
74261:  FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
7427    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
7428    GOTO_OPCODE(ip)                     @ execute it
7429
7430/* ------------------------------ */
7431    .balign 64
7432.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */
7433/* File: armv5te/OP_RETURN_VOID_BARRIER.S */
7434    SMP_DMB_ST
7435    b       common_returnFromMethod
7436
7437/* ------------------------------ */
7438    .balign 64
7439.L_OP_IGET_QUICK: /* 0xf2 */
7440/* File: armv5te/OP_IGET_QUICK.S */
7441    /* For: iget-quick, iget-object-quick */
7442    /* op vA, vB, offset@CCCC */
7443    mov     r2, rINST, lsr #12          @ r2<- B
7444    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7445    FETCH(r1, 1)                        @ r1<- field byte offset
7446    cmp     r3, #0                      @ check object for null
7447    mov     r2, rINST, lsr #8           @ r2<- A(+)
7448    beq     common_errNullObject        @ object was null
7449    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7450    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7451    and     r2, r2, #15
7452    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7453    SET_VREG(r0, r2)                    @ fp[A]<- r0
7454    GOTO_OPCODE(ip)                     @ jump to next instruction
7455
7456/* ------------------------------ */
7457    .balign 64
7458.L_OP_IGET_WIDE_QUICK: /* 0xf3 */
7459/* File: armv5te/OP_IGET_WIDE_QUICK.S */
7460    /* iget-wide-quick vA, vB, offset@CCCC */
7461    mov     r2, rINST, lsr #12          @ r2<- B
7462    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7463    FETCH(ip, 1)                        @ ip<- field byte offset
7464    cmp     r3, #0                      @ check object for null
7465    mov     r2, rINST, lsr #8           @ r2<- A(+)
7466    beq     common_errNullObject        @ object was null
7467    ldrd    r0, [r3, ip]                @ r0<- obj.field (64 bits, aligned)
7468    and     r2, r2, #15
7469    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7470    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
7471    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7472    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
7473    GOTO_OPCODE(ip)                     @ jump to next instruction
7474
7475/* ------------------------------ */
7476    .balign 64
7477.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */
7478/* File: armv5te/OP_IGET_OBJECT_QUICK.S */
7479/* File: armv5te/OP_IGET_QUICK.S */
7480    /* For: iget-quick, iget-object-quick */
7481    /* op vA, vB, offset@CCCC */
7482    mov     r2, rINST, lsr #12          @ r2<- B
7483    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7484    FETCH(r1, 1)                        @ r1<- field byte offset
7485    cmp     r3, #0                      @ check object for null
7486    mov     r2, rINST, lsr #8           @ r2<- A(+)
7487    beq     common_errNullObject        @ object was null
7488    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7489    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7490    and     r2, r2, #15
7491    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7492    SET_VREG(r0, r2)                    @ fp[A]<- r0
7493    GOTO_OPCODE(ip)                     @ jump to next instruction
7494
7495
7496/* ------------------------------ */
7497    .balign 64
7498.L_OP_IPUT_QUICK: /* 0xf5 */
7499/* File: armv5te/OP_IPUT_QUICK.S */
7500    /* For: iput-quick */
7501    /* op vA, vB, offset@CCCC */
7502    mov     r2, rINST, lsr #12          @ r2<- B
7503    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7504    FETCH(r1, 1)                        @ r1<- field byte offset
7505    cmp     r3, #0                      @ check object for null
7506    mov     r2, rINST, lsr #8           @ r2<- A(+)
7507    beq     common_errNullObject        @ object was null
7508    and     r2, r2, #15
7509    GET_VREG(r0, r2)                    @ r0<- fp[A]
7510    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7511    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7512    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7513    GOTO_OPCODE(ip)                     @ jump to next instruction
7514
7515/* ------------------------------ */
7516    .balign 64
7517.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */
7518/* File: armv5te/OP_IPUT_WIDE_QUICK.S */
7519    /* iput-wide-quick vA, vB, offset@CCCC */
7520    mov     r0, rINST, lsr #8           @ r0<- A(+)
7521    mov     r1, rINST, lsr #12          @ r1<- B
7522    and     r0, r0, #15
7523    GET_VREG(r2, r1)                    @ r2<- fp[B], the object pointer
7524    add     r3, rFP, r0, lsl #2         @ r3<- &fp[A]
7525    cmp     r2, #0                      @ check object for null
7526    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[A]
7527    beq     common_errNullObject        @ object was null
7528    FETCH(r3, 1)                        @ r3<- field byte offset
7529    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7530    strd    r0, [r2, r3]                @ obj.field (64 bits, aligned)<- r0/r1
7531    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7532    GOTO_OPCODE(ip)                     @ jump to next instruction
7533
7534/* ------------------------------ */
7535    .balign 64
7536.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
7537/* File: armv5te/OP_IPUT_OBJECT_QUICK.S */
7538    /* For: iput-object-quick */
7539    /* op vA, vB, offset@CCCC */
7540    mov     r2, rINST, lsr #12          @ r2<- B
7541    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7542    FETCH(r1, 1)                        @ r1<- field byte offset
7543    cmp     r3, #0                      @ check object for null
7544    mov     r2, rINST, lsr #8           @ r2<- A(+)
7545    beq     common_errNullObject        @ object was null
7546    and     r2, r2, #15
7547    GET_VREG(r0, r2)                    @ r0<- fp[A]
7548    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
7549    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7550    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7551    cmp     r0, #0
7552    strneb  r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head
7553    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7554    GOTO_OPCODE(ip)                     @ jump to next instruction
7555
7556/* ------------------------------ */
7557    .balign 64
7558.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
7559/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7560    /*
7561     * Handle an optimized virtual method call.
7562     *
7563     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7564     */
7565    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7566    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7567    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7568    FETCH(r1, 1)                        @ r1<- BBBB
7569    .if     (!0)
7570    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7571    .endif
7572    GET_VREG(r2, r3)                    @ r2<- vC ("this" ptr)
7573    cmp     r2, #0                      @ is "this" null?
7574    beq     common_errNullObject        @ null "this", throw exception
7575    ldr     r2, [r2, #offObject_clazz]  @ r2<- thisPtr->clazz
7576    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7577    EXPORT_PC()                         @ invoke must export
7578    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7579    bl      common_invokeMethodNoRange @ continue on
7580
7581/* ------------------------------ */
7582    .balign 64
7583.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
7584/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */
7585/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7586    /*
7587     * Handle an optimized virtual method call.
7588     *
7589     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7590     */
7591    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7592    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7593    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7594    FETCH(r1, 1)                        @ r1<- BBBB
7595    .if     (!1)
7596    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7597    .endif
7598    GET_VREG(r2, r3)                    @ r2<- vC ("this" ptr)
7599    cmp     r2, #0                      @ is "this" null?
7600    beq     common_errNullObject        @ null "this", throw exception
7601    ldr     r2, [r2, #offObject_clazz]  @ r2<- thisPtr->clazz
7602    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7603    EXPORT_PC()                         @ invoke must export
7604    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7605    bl      common_invokeMethodRange @ continue on
7606
7607
7608/* ------------------------------ */
7609    .balign 64
7610.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */
7611/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7612    /*
7613     * Handle an optimized "super" method call.
7614     *
7615     * for: [opt] invoke-super-quick, invoke-super-quick/range
7616     */
7617    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7618    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7619    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7620    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7621    .if     (!0)
7622    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7623    .endif
7624    FETCH(r1, 1)                        @ r1<- BBBB
7625    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7626    EXPORT_PC()                         @ must export for invoke
7627    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7628    GET_VREG(r3, r10)                   @ r3<- "this"
7629    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7630    cmp     r3, #0                      @ null "this" ref?
7631    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7632    beq     common_errNullObject        @ "this" is null, throw exception
7633    bl      common_invokeMethodNoRange @ continue on
7634
7635/* ------------------------------ */
7636    .balign 64
7637.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
7638/* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */
7639/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7640    /*
7641     * Handle an optimized "super" method call.
7642     *
7643     * for: [opt] invoke-super-quick, invoke-super-quick/range
7644     */
7645    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7646    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7647    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7648    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7649    .if     (!1)
7650    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7651    .endif
7652    FETCH(r1, 1)                        @ r1<- BBBB
7653    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7654    EXPORT_PC()                         @ must export for invoke
7655    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7656    GET_VREG(r3, r10)                   @ r3<- "this"
7657    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7658    cmp     r3, #0                      @ null "this" ref?
7659    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7660    beq     common_errNullObject        @ "this" is null, throw exception
7661    bl      common_invokeMethodRange @ continue on
7662
7663
7664/* ------------------------------ */
7665    .balign 64
7666.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
7667/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */
7668/* File: armv5te/OP_IPUT_OBJECT.S */
7669    /*
7670     * 32-bit instance field put.
7671     *
7672     * for: iput-object, iput-object-volatile
7673     */
7674    /* op vA, vB, field@CCCC */
7675    mov     r0, rINST, lsr #12          @ r0<- B
7676    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7677    FETCH(r1, 1)                        @ r1<- field ref CCCC
7678    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7679    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7680    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7681    cmp     r0, #0                      @ is resolved entry null?
7682    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ no, already resolved
76838:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7684    EXPORT_PC()                         @ resolve() could throw
7685    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7686    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7687    cmp     r0, #0                      @ success?
7688    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ yes, finish up
7689    b       common_exceptionThrown
7690
7691
7692/* ------------------------------ */
7693    .balign 64
7694.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
7695/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */
7696/* File: armv5te/OP_SGET.S */
7697    /*
7698     * General 32-bit SGET handler.
7699     *
7700     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7701     */
7702    /* op vAA, field@BBBB */
7703    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7704    FETCH(r1, 1)                        @ r1<- field ref BBBB
7705    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7706    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7707    cmp     r0, #0                      @ is resolved entry null?
7708    beq     .LOP_SGET_OBJECT_VOLATILE_resolve         @ yes, do resolve
7709.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0
7710    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7711    SMP_DMB                            @ acquiring load
7712    mov     r2, rINST, lsr #8           @ r2<- AA
7713    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7714    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7715    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7716    GOTO_OPCODE(ip)                     @ jump to next instruction
7717
7718
7719/* ------------------------------ */
7720    .balign 64
7721.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
7722/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */
7723/* File: armv5te/OP_SPUT_OBJECT.S */
7724    /*
7725     * 32-bit SPUT handler for objects
7726     *
7727     * for: sput-object, sput-object-volatile
7728     */
7729    /* op vAA, field@BBBB */
7730    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7731    FETCH(r1, 1)                        @ r1<- field ref BBBB
7732    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7733    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7734    cmp     r0, #0                      @ is resolved entry null?
7735    bne     .LOP_SPUT_OBJECT_VOLATILE_finish          @ no, continue
7736    ldr     r9, [rSELF, #offThread_method]    @ r9<- current method
7737    EXPORT_PC()                         @ resolve() could throw, so export now
7738    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
7739    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
7740    cmp     r0, #0                      @ success?
7741    bne     .LOP_SPUT_OBJECT_VOLATILE_finish          @ yes, finish
7742    b       common_exceptionThrown      @ no, handle exception
7743
7744
7745
7746/* ------------------------------ */
7747    .balign 64
7748.L_OP_DISPATCH_FF: /* 0xff */
7749/* File: armv5te/OP_DISPATCH_FF.S */
7750    mov     ip, rINST, lsr #8           @ r9<- extended opcode
7751    add     ip, ip, #256                @ add offset for extended opcodes
7752    GOTO_OPCODE(ip)                     @ go to proper extended handler
7753
7754
7755/* ------------------------------ */
7756    .balign 64
7757.L_OP_CONST_CLASS_JUMBO: /* 0x100 */
7758/* File: armv5te/OP_CONST_CLASS_JUMBO.S */
7759    /* const-class/jumbo vBBBB, Class@AAAAAAAA */
7760    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7761    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<-self>methodClassDex
7762    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7763    ldr     r2, [r2, #offDvmDex_pResClasses]   @ r2<- dvmDex->pResClasses
7764    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7765    FETCH(r9, 3)                        @ r9<- BBBB
7766    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResClasses[AAAAaaaa]
7767    cmp     r0, #0                      @ not yet resolved?
7768    beq     .LOP_CONST_CLASS_JUMBO_resolve
7769    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
7770    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7771    SET_VREG(r0, r9)                    @ vBBBB<- r0
7772    GOTO_OPCODE(ip)                     @ jump to next instruction
7773
7774/* ------------------------------ */
7775    .balign 64
7776.L_OP_CHECK_CAST_JUMBO: /* 0x101 */
7777/* File: armv5te/OP_CHECK_CAST_JUMBO.S */
7778    /*
7779     * Check to see if a cast from one class to another is allowed.
7780     */
7781    /* check-cast/jumbo vBBBB, class@AAAAAAAA */
7782    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7783    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7784    FETCH(r3, 3)                        @ r3<- BBBB
7785    orr     r2, r0, r2, lsl #16         @ r2<- AAAAaaaa
7786    GET_VREG(r9, r3)                    @ r9<- object
7787    ldr     r0, [rSELF, #offThread_methodClassDex]    @ r0<- pDvmDex
7788    cmp     r9, #0                      @ is object null?
7789    ldr     r0, [r0, #offDvmDex_pResClasses]    @ r0<- pDvmDex->pResClasses
7790    beq     .LOP_CHECK_CAST_JUMBO_okay            @ null obj, cast always succeeds
7791    ldr     r1, [r0, r2, lsl #2]        @ r1<- resolved class
7792    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
7793    cmp     r1, #0                      @ have we resolved this before?
7794    beq     .LOP_CHECK_CAST_JUMBO_resolve         @ not resolved, do it now
7795.LOP_CHECK_CAST_JUMBO_resolved:
7796    cmp     r0, r1                      @ same class (trivial success)?
7797    bne     .LOP_CHECK_CAST_JUMBO_fullcheck       @ no, do full check
7798    b       .LOP_CHECK_CAST_JUMBO_okay            @ yes, finish up
7799
7800/* ------------------------------ */
7801    .balign 64
7802.L_OP_INSTANCE_OF_JUMBO: /* 0x102 */
7803/* File: armv5te/OP_INSTANCE_OF_JUMBO.S */
7804    /*
7805     * Check to see if an object reference is an instance of a class.
7806     *
7807     * Most common situation is a non-null object, being compared against
7808     * an already-resolved class.
7809     *
7810     * TODO: convert most of this into a common subroutine, shared with
7811     *       OP_INSTANCE_OF.S.
7812     */
7813    /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */
7814    FETCH(r3, 4)                        @ r3<- vCCCC
7815    FETCH(r9, 3)                        @ r9<- vBBBB
7816    GET_VREG(r0, r3)                    @ r0<- vCCCC (object)
7817    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- pDvmDex
7818    cmp     r0, #0                      @ is object null?
7819    beq     .LOP_INSTANCE_OF_JUMBO_store           @ null obj, not an instance, store r0
7820    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7821    FETCH(r3, 2)                        @ r3<- AAAA (hi)
7822    ldr     r2, [r2, #offDvmDex_pResClasses]    @ r2<- pDvmDex->pResClasses
7823    orr     r3, r1, r3, lsl #16         @ r3<- AAAAaaaa
7824    ldr     r1, [r2, r3, lsl #2]        @ r1<- resolved class
7825    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
7826    cmp     r1, #0                      @ have we resolved this before?
7827    beq     .LOP_INSTANCE_OF_JUMBO_resolve         @ not resolved, do it now
7828    b       .LOP_INSTANCE_OF_JUMBO_resolved        @ resolved, continue
7829
7830/* ------------------------------ */
7831    .balign 64
7832.L_OP_NEW_INSTANCE_JUMBO: /* 0x103 */
7833/* File: armv5te/OP_NEW_INSTANCE_JUMBO.S */
7834    /*
7835     * Create a new instance of a class.
7836     */
7837    /* new-instance/jumbo vBBBB, class@AAAAAAAA */
7838    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7839    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7840    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
7841    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7842    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7843    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
7844    EXPORT_PC()                         @ req'd for init, resolve, alloc
7845    cmp     r0, #0                      @ already resolved?
7846    beq     .LOP_NEW_INSTANCE_JUMBO_resolve         @ no, resolve it now
7847.LOP_NEW_INSTANCE_JUMBO_resolved:   @ r0=class
7848    ldrb    r1, [r0, #offClassObject_status]    @ r1<- ClassStatus enum
7849    cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
7850    bne     .LOP_NEW_INSTANCE_JUMBO_needinit        @ no, init class now
7851.LOP_NEW_INSTANCE_JUMBO_initialized: @ r0=class
7852    mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
7853    bl      dvmAllocObject              @ r0<- new object
7854    b       .LOP_NEW_INSTANCE_JUMBO_finish          @ continue
7855
7856/* ------------------------------ */
7857    .balign 64
7858.L_OP_NEW_ARRAY_JUMBO: /* 0x104 */
7859/* File: armv5te/OP_NEW_ARRAY_JUMBO.S */
7860    /*
7861     * Allocate an array of objects, specified with the array class
7862     * and a count.
7863     *
7864     * The verifier guarantees that this is an array class, so we don't
7865     * check for it here.
7866     */
7867    /* new-array/jumbo vBBBB, vCCCC, class@AAAAAAAA */
7868    FETCH(r2, 1)                        @ r2<- aaaa (lo)
7869    FETCH(r3, 2)                        @ r3<- AAAA (hi)
7870    FETCH(r0, 4)                        @ r0<- vCCCC
7871    orr     r2, r2, r3, lsl #16         @ r2<- AAAAaaaa
7872    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
7873    GET_VREG(r1, r0)                    @ r1<- vCCCC (array length)
7874    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7875    cmp     r1, #0                      @ check length
7876    ldr     r0, [r3, r2, lsl #2]        @ r0<- resolved class
7877    bmi     common_errNegativeArraySize @ negative length, bail - len in r1
7878    cmp     r0, #0                      @ already resolved?
7879    EXPORT_PC()                         @ req'd for resolve, alloc
7880    bne     .LOP_NEW_ARRAY_JUMBO_finish          @ resolved, continue
7881    b       .LOP_NEW_ARRAY_JUMBO_resolve         @ do resolve now
7882
7883/* ------------------------------ */
7884    .balign 64
7885.L_OP_FILLED_NEW_ARRAY_JUMBO: /* 0x105 */
7886/* File: armv5te/OP_FILLED_NEW_ARRAY_JUMBO.S */
7887    /*
7888     * Create a new array with elements filled from registers.
7889     *
7890     * TODO: convert most of this into a common subroutine, shared with
7891     *       OP_FILLED_NEW_ARRAY.S.
7892     */
7893    /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */
7894    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
7895    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7896    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7897    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7898    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7899    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
7900    EXPORT_PC()                         @ need for resolve and alloc
7901    cmp     r0, #0                      @ already resolved?
7902    bne     .LOP_FILLED_NEW_ARRAY_JUMBO_continue        @ yes, continue on
79038:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
7904    mov     r2, #0                      @ r2<- false
7905    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
7906    bl      dvmResolveClass             @ r0<- call(clazz, ref)
7907    cmp     r0, #0                      @ got null?
7908    beq     common_exceptionThrown      @ yes, handle exception
7909    b       .LOP_FILLED_NEW_ARRAY_JUMBO_continue
7910
7911/* ------------------------------ */
7912    .balign 64
7913.L_OP_IGET_JUMBO: /* 0x106 */
7914/* File: armv5te/OP_IGET_JUMBO.S */
7915    /*
7916     * Jumbo 32-bit instance field get.
7917     *
7918     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7919     *      iget-char/jumbo, iget-short/jumbo
7920     */
7921    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7922    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7923    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7924    FETCH(r0, 4)                        @ r0<- CCCC
7925    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7926    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7927    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7928    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7929    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7930    cmp     r0, #0                      @ is resolved entry null?
7931    bne     .LOP_IGET_JUMBO_finish          @ no, already resolved
79328:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7933    EXPORT_PC()                         @ resolve() could throw
7934    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7935    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7936    b       .LOP_IGET_JUMBO_resolved        @ resolved, continue
7937
7938/* ------------------------------ */
7939    .balign 64
7940.L_OP_IGET_WIDE_JUMBO: /* 0x107 */
7941/* File: armv5te/OP_IGET_WIDE_JUMBO.S */
7942    /*
7943     * Jumbo 64-bit instance field get.
7944     */
7945    /* iget-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
7946    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7947    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7948    FETCH(r0, 4)                        @ r0<- CCCC
7949    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7950    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7951    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7952    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7953    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7954    cmp     r0, #0                      @ is resolved entry null?
7955    bne     .LOP_IGET_WIDE_JUMBO_finish          @ no, already resolved
79568:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
7957    EXPORT_PC()                         @ resolve() could throw
7958    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7959    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7960    b       .LOP_IGET_WIDE_JUMBO_resolved        @ resolved, continue
7961
7962/* ------------------------------ */
7963    .balign 64
7964.L_OP_IGET_OBJECT_JUMBO: /* 0x108 */
7965/* File: armv5te/OP_IGET_OBJECT_JUMBO.S */
7966/* File: armv5te/OP_IGET_JUMBO.S */
7967    /*
7968     * Jumbo 32-bit instance field get.
7969     *
7970     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7971     *      iget-char/jumbo, iget-short/jumbo
7972     */
7973    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7974    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7975    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7976    FETCH(r0, 4)                        @ r0<- CCCC
7977    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7978    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7979    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7980    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7981    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7982    cmp     r0, #0                      @ is resolved entry null?
7983    bne     .LOP_IGET_OBJECT_JUMBO_finish          @ no, already resolved
79848:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7985    EXPORT_PC()                         @ resolve() could throw
7986    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7987    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7988    b       .LOP_IGET_OBJECT_JUMBO_resolved        @ resolved, continue
7989
7990
7991/* ------------------------------ */
7992    .balign 64
7993.L_OP_IGET_BOOLEAN_JUMBO: /* 0x109 */
7994/* File: armv5te/OP_IGET_BOOLEAN_JUMBO.S */
7995@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrb", "sqnum":"1" }
7996/* File: armv5te/OP_IGET_JUMBO.S */
7997    /*
7998     * Jumbo 32-bit instance field get.
7999     *
8000     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8001     *      iget-char/jumbo, iget-short/jumbo
8002     */
8003    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8004    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8005    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8006    FETCH(r0, 4)                        @ r0<- CCCC
8007    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8008    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8009    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8010    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8011    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8012    cmp     r0, #0                      @ is resolved entry null?
8013    bne     .LOP_IGET_BOOLEAN_JUMBO_finish          @ no, already resolved
80148:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8015    EXPORT_PC()                         @ resolve() could throw
8016    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8017    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8018    b       .LOP_IGET_BOOLEAN_JUMBO_resolved        @ resolved, continue
8019
8020
8021/* ------------------------------ */
8022    .balign 64
8023.L_OP_IGET_BYTE_JUMBO: /* 0x10a */
8024/* File: armv5te/OP_IGET_BYTE_JUMBO.S */
8025@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsb", "sqnum":"2" }
8026/* File: armv5te/OP_IGET_JUMBO.S */
8027    /*
8028     * Jumbo 32-bit instance field get.
8029     *
8030     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8031     *      iget-char/jumbo, iget-short/jumbo
8032     */
8033    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8034    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8035    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8036    FETCH(r0, 4)                        @ r0<- CCCC
8037    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8038    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8039    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8040    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8041    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8042    cmp     r0, #0                      @ is resolved entry null?
8043    bne     .LOP_IGET_BYTE_JUMBO_finish          @ no, already resolved
80448:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8045    EXPORT_PC()                         @ resolve() could throw
8046    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8047    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8048    b       .LOP_IGET_BYTE_JUMBO_resolved        @ resolved, continue
8049
8050
8051/* ------------------------------ */
8052    .balign 64
8053.L_OP_IGET_CHAR_JUMBO: /* 0x10b */
8054/* File: armv5te/OP_IGET_CHAR_JUMBO.S */
8055@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrh", "sqnum":"3" }
8056/* File: armv5te/OP_IGET_JUMBO.S */
8057    /*
8058     * Jumbo 32-bit instance field get.
8059     *
8060     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8061     *      iget-char/jumbo, iget-short/jumbo
8062     */
8063    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8064    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8065    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8066    FETCH(r0, 4)                        @ r0<- CCCC
8067    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8068    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8069    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8070    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8071    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8072    cmp     r0, #0                      @ is resolved entry null?
8073    bne     .LOP_IGET_CHAR_JUMBO_finish          @ no, already resolved
80748:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8075    EXPORT_PC()                         @ resolve() could throw
8076    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8077    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8078    b       .LOP_IGET_CHAR_JUMBO_resolved        @ resolved, continue
8079
8080
8081/* ------------------------------ */
8082    .balign 64
8083.L_OP_IGET_SHORT_JUMBO: /* 0x10c */
8084/* File: armv5te/OP_IGET_SHORT_JUMBO.S */
8085@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsh", "sqnum":"4" }
8086/* File: armv5te/OP_IGET_JUMBO.S */
8087    /*
8088     * Jumbo 32-bit instance field get.
8089     *
8090     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8091     *      iget-char/jumbo, iget-short/jumbo
8092     */
8093    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8094    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8095    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8096    FETCH(r0, 4)                        @ r0<- CCCC
8097    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8098    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8099    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8100    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8101    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8102    cmp     r0, #0                      @ is resolved entry null?
8103    bne     .LOP_IGET_SHORT_JUMBO_finish          @ no, already resolved
81048:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8105    EXPORT_PC()                         @ resolve() could throw
8106    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8107    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8108    b       .LOP_IGET_SHORT_JUMBO_resolved        @ resolved, continue
8109
8110
8111/* ------------------------------ */
8112    .balign 64
8113.L_OP_IPUT_JUMBO: /* 0x10d */
8114/* File: armv5te/OP_IPUT_JUMBO.S */
8115    /*
8116     * Jumbo 32-bit instance field put.
8117     *
8118     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8119     *      iput-short/jumbo
8120     */
8121    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8122    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8123    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8124    FETCH(r0, 4)                        @ r0<- CCCC
8125    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8126    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8127    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8128    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8129    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8130    cmp     r0, #0                      @ is resolved entry null?
8131    bne     .LOP_IPUT_JUMBO_finish          @ no, already resolved
81328:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8133    EXPORT_PC()                         @ resolve() could throw
8134    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8135    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8136    b       .LOP_IPUT_JUMBO_resolved        @ resolved, continue
8137
8138/* ------------------------------ */
8139    .balign 64
8140.L_OP_IPUT_WIDE_JUMBO: /* 0x10e */
8141/* File: armv5te/OP_IPUT_WIDE_JUMBO.S */
8142    /* iput-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
8143    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8144    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8145    FETCH(r0, 4)                        @ r0<- CCCC
8146    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8147    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8148    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
8149    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
8150    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8151    cmp     r0, #0                      @ is resolved entry null?
8152    bne     .LOP_IPUT_WIDE_JUMBO_finish          @ no, already resolved
81538:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
8154    EXPORT_PC()                         @ resolve() could throw
8155    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8156    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8157    b       .LOP_IPUT_WIDE_JUMBO_resolved        @ resolved, continue
8158
8159/* ------------------------------ */
8160    .balign 64
8161.L_OP_IPUT_OBJECT_JUMBO: /* 0x10f */
8162/* File: armv5te/OP_IPUT_OBJECT_JUMBO.S */
8163    /*
8164     * Jumbo 32-bit instance field put.
8165     */
8166    /* iput-object/jumbo vBBBB, vCCCC, field@AAAAAAAA */
8167    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8168    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8169    FETCH(r0, 4)                        @ r0<- CCCC
8170    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8171    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8172    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8173    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8174    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8175    cmp     r0, #0                      @ is resolved entry null?
8176    bne     .LOP_IPUT_OBJECT_JUMBO_finish          @ no, already resolved
81778:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8178    EXPORT_PC()                         @ resolve() could throw
8179    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8180    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8181    b       .LOP_IPUT_OBJECT_JUMBO_resolved        @ resolved, continue
8182
8183/* ------------------------------ */
8184    .balign 64
8185.L_OP_IPUT_BOOLEAN_JUMBO: /* 0x110 */
8186/* File: armv5te/OP_IPUT_BOOLEAN_JUMBO.S */
8187@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"1" }
8188/* File: armv5te/OP_IPUT_JUMBO.S */
8189    /*
8190     * Jumbo 32-bit instance field put.
8191     *
8192     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8193     *      iput-short/jumbo
8194     */
8195    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8196    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8197    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8198    FETCH(r0, 4)                        @ r0<- CCCC
8199    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8200    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8201    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8202    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8203    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8204    cmp     r0, #0                      @ is resolved entry null?
8205    bne     .LOP_IPUT_BOOLEAN_JUMBO_finish          @ no, already resolved
82068:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8207    EXPORT_PC()                         @ resolve() could throw
8208    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8209    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8210    b       .LOP_IPUT_BOOLEAN_JUMBO_resolved        @ resolved, continue
8211
8212
8213/* ------------------------------ */
8214    .balign 64
8215.L_OP_IPUT_BYTE_JUMBO: /* 0x111 */
8216/* File: armv5te/OP_IPUT_BYTE_JUMBO.S */
8217@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"2" }
8218/* File: armv5te/OP_IPUT_JUMBO.S */
8219    /*
8220     * Jumbo 32-bit instance field put.
8221     *
8222     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8223     *      iput-short/jumbo
8224     */
8225    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8226    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8227    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8228    FETCH(r0, 4)                        @ r0<- CCCC
8229    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8230    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8231    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8232    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8233    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8234    cmp     r0, #0                      @ is resolved entry null?
8235    bne     .LOP_IPUT_BYTE_JUMBO_finish          @ no, already resolved
82368:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8237    EXPORT_PC()                         @ resolve() could throw
8238    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8239    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8240    b       .LOP_IPUT_BYTE_JUMBO_resolved        @ resolved, continue
8241
8242
8243/* ------------------------------ */
8244    .balign 64
8245.L_OP_IPUT_CHAR_JUMBO: /* 0x112 */
8246/* File: armv5te/OP_IPUT_CHAR_JUMBO.S */
8247@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"3" }
8248/* File: armv5te/OP_IPUT_JUMBO.S */
8249    /*
8250     * Jumbo 32-bit instance field put.
8251     *
8252     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8253     *      iput-short/jumbo
8254     */
8255    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8256    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8257    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8258    FETCH(r0, 4)                        @ r0<- CCCC
8259    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8260    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8261    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8262    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8263    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8264    cmp     r0, #0                      @ is resolved entry null?
8265    bne     .LOP_IPUT_CHAR_JUMBO_finish          @ no, already resolved
82668:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8267    EXPORT_PC()                         @ resolve() could throw
8268    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8269    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8270    b       .LOP_IPUT_CHAR_JUMBO_resolved        @ resolved, continue
8271
8272
8273/* ------------------------------ */
8274    .balign 64
8275.L_OP_IPUT_SHORT_JUMBO: /* 0x113 */
8276/* File: armv5te/OP_IPUT_SHORT_JUMBO.S */
8277@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"4" }
8278/* File: armv5te/OP_IPUT_JUMBO.S */
8279    /*
8280     * Jumbo 32-bit instance field put.
8281     *
8282     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8283     *      iput-short/jumbo
8284     */
8285    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8286    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8287    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8288    FETCH(r0, 4)                        @ r0<- CCCC
8289    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8290    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8291    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8292    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8293    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8294    cmp     r0, #0                      @ is resolved entry null?
8295    bne     .LOP_IPUT_SHORT_JUMBO_finish          @ no, already resolved
82968:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8297    EXPORT_PC()                         @ resolve() could throw
8298    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8299    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8300    b       .LOP_IPUT_SHORT_JUMBO_resolved        @ resolved, continue
8301
8302
8303/* ------------------------------ */
8304    .balign 64
8305.L_OP_SGET_JUMBO: /* 0x114 */
8306/* File: armv5te/OP_SGET_JUMBO.S */
8307    /*
8308     * Jumbo 32-bit SGET handler.
8309     *
8310     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8311     *      sget-char/jumbo, sget-short/jumbo
8312     */
8313    /* exop vBBBB, field@AAAAAAAA */
8314    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8315    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8316    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8317    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8318    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8319    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8320    cmp     r0, #0                      @ is resolved entry null?
8321    beq     .LOP_SGET_JUMBO_resolve         @ yes, do resolve
8322.LOP_SGET_JUMBO_finish: @ field ptr in r0
8323    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8324    @ no-op                             @ acquiring load
8325    FETCH(r2, 3)                        @ r2<- BBBB
8326    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8327    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8328    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8329    GOTO_OPCODE(ip)                     @ jump to next instruction
8330
8331/* ------------------------------ */
8332    .balign 64
8333.L_OP_SGET_WIDE_JUMBO: /* 0x115 */
8334/* File: armv5te/OP_SGET_WIDE_JUMBO.S */
8335    /*
8336     * Jumbo 64-bit SGET handler.
8337     */
8338    /* sget-wide/jumbo vBBBB, field@AAAAAAAA */
8339    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8340    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8341    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8342    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8343    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8344    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8345    cmp     r0, #0                      @ is resolved entry null?
8346    beq     .LOP_SGET_WIDE_JUMBO_resolve         @ yes, do resolve
8347.LOP_SGET_WIDE_JUMBO_finish:
8348    FETCH(r9, 3)                        @ r9<- BBBB
8349    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
8350    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BBBB]
8351    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8352    stmia   r9, {r0-r1}                 @ vBBBB/vBBBB+1<- r0/r1
8353    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8354    GOTO_OPCODE(ip)                     @ jump to next instruction
8355
8356/* ------------------------------ */
8357    .balign 64
8358.L_OP_SGET_OBJECT_JUMBO: /* 0x116 */
8359/* File: armv5te/OP_SGET_OBJECT_JUMBO.S */
8360/* File: armv5te/OP_SGET_JUMBO.S */
8361    /*
8362     * Jumbo 32-bit SGET handler.
8363     *
8364     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8365     *      sget-char/jumbo, sget-short/jumbo
8366     */
8367    /* exop vBBBB, field@AAAAAAAA */
8368    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8369    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8370    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8371    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8372    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8373    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8374    cmp     r0, #0                      @ is resolved entry null?
8375    beq     .LOP_SGET_OBJECT_JUMBO_resolve         @ yes, do resolve
8376.LOP_SGET_OBJECT_JUMBO_finish: @ field ptr in r0
8377    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8378    @ no-op                             @ acquiring load
8379    FETCH(r2, 3)                        @ r2<- BBBB
8380    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8381    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8382    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8383    GOTO_OPCODE(ip)                     @ jump to next instruction
8384
8385
8386/* ------------------------------ */
8387    .balign 64
8388.L_OP_SGET_BOOLEAN_JUMBO: /* 0x117 */
8389/* File: armv5te/OP_SGET_BOOLEAN_JUMBO.S */
8390/* File: armv5te/OP_SGET_JUMBO.S */
8391    /*
8392     * Jumbo 32-bit SGET handler.
8393     *
8394     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8395     *      sget-char/jumbo, sget-short/jumbo
8396     */
8397    /* exop vBBBB, field@AAAAAAAA */
8398    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8399    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8400    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8401    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8402    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8403    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8404    cmp     r0, #0                      @ is resolved entry null?
8405    beq     .LOP_SGET_BOOLEAN_JUMBO_resolve         @ yes, do resolve
8406.LOP_SGET_BOOLEAN_JUMBO_finish: @ field ptr in r0
8407    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8408    @ no-op                             @ acquiring load
8409    FETCH(r2, 3)                        @ r2<- BBBB
8410    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8411    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8412    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8413    GOTO_OPCODE(ip)                     @ jump to next instruction
8414
8415
8416/* ------------------------------ */
8417    .balign 64
8418.L_OP_SGET_BYTE_JUMBO: /* 0x118 */
8419/* File: armv5te/OP_SGET_BYTE_JUMBO.S */
8420/* File: armv5te/OP_SGET_JUMBO.S */
8421    /*
8422     * Jumbo 32-bit SGET handler.
8423     *
8424     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8425     *      sget-char/jumbo, sget-short/jumbo
8426     */
8427    /* exop vBBBB, field@AAAAAAAA */
8428    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8429    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8430    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8431    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8432    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8433    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8434    cmp     r0, #0                      @ is resolved entry null?
8435    beq     .LOP_SGET_BYTE_JUMBO_resolve         @ yes, do resolve
8436.LOP_SGET_BYTE_JUMBO_finish: @ field ptr in r0
8437    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8438    @ no-op                             @ acquiring load
8439    FETCH(r2, 3)                        @ r2<- BBBB
8440    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8441    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8442    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8443    GOTO_OPCODE(ip)                     @ jump to next instruction
8444
8445
8446/* ------------------------------ */
8447    .balign 64
8448.L_OP_SGET_CHAR_JUMBO: /* 0x119 */
8449/* File: armv5te/OP_SGET_CHAR_JUMBO.S */
8450/* File: armv5te/OP_SGET_JUMBO.S */
8451    /*
8452     * Jumbo 32-bit SGET handler.
8453     *
8454     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8455     *      sget-char/jumbo, sget-short/jumbo
8456     */
8457    /* exop vBBBB, field@AAAAAAAA */
8458    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8459    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8460    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8461    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8462    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8463    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8464    cmp     r0, #0                      @ is resolved entry null?
8465    beq     .LOP_SGET_CHAR_JUMBO_resolve         @ yes, do resolve
8466.LOP_SGET_CHAR_JUMBO_finish: @ field ptr in r0
8467    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8468    @ no-op                             @ acquiring load
8469    FETCH(r2, 3)                        @ r2<- BBBB
8470    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8471    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8472    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8473    GOTO_OPCODE(ip)                     @ jump to next instruction
8474
8475
8476/* ------------------------------ */
8477    .balign 64
8478.L_OP_SGET_SHORT_JUMBO: /* 0x11a */
8479/* File: armv5te/OP_SGET_SHORT_JUMBO.S */
8480/* File: armv5te/OP_SGET_JUMBO.S */
8481    /*
8482     * Jumbo 32-bit SGET handler.
8483     *
8484     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8485     *      sget-char/jumbo, sget-short/jumbo
8486     */
8487    /* exop vBBBB, field@AAAAAAAA */
8488    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8489    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8490    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8491    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8492    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8493    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8494    cmp     r0, #0                      @ is resolved entry null?
8495    beq     .LOP_SGET_SHORT_JUMBO_resolve         @ yes, do resolve
8496.LOP_SGET_SHORT_JUMBO_finish: @ field ptr in r0
8497    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8498    @ no-op                             @ acquiring load
8499    FETCH(r2, 3)                        @ r2<- BBBB
8500    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8501    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8502    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8503    GOTO_OPCODE(ip)                     @ jump to next instruction
8504
8505
8506/* ------------------------------ */
8507    .balign 64
8508.L_OP_SPUT_JUMBO: /* 0x11b */
8509/* File: armv5te/OP_SPUT_JUMBO.S */
8510    /*
8511     * Jumbo 32-bit SPUT handler.
8512     *
8513     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8514     *      sput-short/jumbo
8515     */
8516    /* exop vBBBB, field@AAAAAAAA */
8517    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8518    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8519    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8520    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8521    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8522    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8523    cmp     r0, #0                      @ is resolved entry null?
8524    beq     .LOP_SPUT_JUMBO_resolve         @ yes, do resolve
8525.LOP_SPUT_JUMBO_finish:   @ field ptr in r0
8526    FETCH(r2, 3)                        @ r2<- BBBB
8527    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8528    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8529    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8530    @ no-op                             @ releasing store
8531    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8532    GOTO_OPCODE(ip)                     @ jump to next instruction
8533
8534/* ------------------------------ */
8535    .balign 64
8536.L_OP_SPUT_WIDE_JUMBO: /* 0x11c */
8537/* File: armv5te/OP_SPUT_WIDE_JUMBO.S */
8538    /*
8539     * Jumbo 64-bit SPUT handler.
8540     */
8541    /* sput-wide/jumbo vBBBB, field@AAAAAAAA */
8542    ldr     r0, [rSELF, #offThread_methodClassDex]  @ r0<- DvmDex
8543    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8544    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8545    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
8546    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8547    FETCH(r9, 3)                        @ r9<- BBBB
8548    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
8549    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BBBB]
8550    cmp     r2, #0                      @ is resolved entry null?
8551    beq     .LOP_SPUT_WIDE_JUMBO_resolve         @ yes, do resolve
8552.LOP_SPUT_WIDE_JUMBO_finish: @ field ptr in r2, BBBB in r9
8553    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8554    ldmia   r9, {r0-r1}                 @ r0/r1<- vBBBB/vBBBB+1
8555    GET_INST_OPCODE(r10)                @ extract opcode from rINST
8556    strd    r0, [r2, #offStaticField_value] @ field<- vBBBB/vBBBB+1
8557    GOTO_OPCODE(r10)                    @ jump to next instruction
8558
8559/* ------------------------------ */
8560    .balign 64
8561.L_OP_SPUT_OBJECT_JUMBO: /* 0x11d */
8562/* File: armv5te/OP_SPUT_OBJECT_JUMBO.S */
8563    /*
8564     * Jumbo 32-bit SPUT handler for objects
8565     */
8566    /* sput-object/jumbo vBBBB, field@AAAAAAAA */
8567    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8568    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8569    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8570    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8571    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8572    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8573    cmp     r0, #0                      @ is resolved entry null?
8574    bne     .LOP_SPUT_OBJECT_JUMBO_finish          @ no, continue
8575    ldr     r9, [rSELF, #offThread_method]    @ r9<- current method
8576    EXPORT_PC()                         @ resolve() could throw, so export now
8577    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
8578    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8579    cmp     r0, #0                      @ success?
8580    bne     .LOP_SPUT_OBJECT_JUMBO_finish          @ yes, finish
8581    b       common_exceptionThrown      @ no, handle exception
8582
8583/* ------------------------------ */
8584    .balign 64
8585.L_OP_SPUT_BOOLEAN_JUMBO: /* 0x11e */
8586/* File: armv5te/OP_SPUT_BOOLEAN_JUMBO.S */
8587/* File: armv5te/OP_SPUT_JUMBO.S */
8588    /*
8589     * Jumbo 32-bit SPUT handler.
8590     *
8591     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8592     *      sput-short/jumbo
8593     */
8594    /* exop vBBBB, field@AAAAAAAA */
8595    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8596    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8597    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8598    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8599    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8600    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8601    cmp     r0, #0                      @ is resolved entry null?
8602    beq     .LOP_SPUT_BOOLEAN_JUMBO_resolve         @ yes, do resolve
8603.LOP_SPUT_BOOLEAN_JUMBO_finish:   @ field ptr in r0
8604    FETCH(r2, 3)                        @ r2<- BBBB
8605    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8606    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8607    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8608    @ no-op                             @ releasing store
8609    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8610    GOTO_OPCODE(ip)                     @ jump to next instruction
8611
8612
8613/* ------------------------------ */
8614    .balign 64
8615.L_OP_SPUT_BYTE_JUMBO: /* 0x11f */
8616/* File: armv5te/OP_SPUT_BYTE_JUMBO.S */
8617/* File: armv5te/OP_SPUT_JUMBO.S */
8618    /*
8619     * Jumbo 32-bit SPUT handler.
8620     *
8621     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8622     *      sput-short/jumbo
8623     */
8624    /* exop vBBBB, field@AAAAAAAA */
8625    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8626    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8627    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8628    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8629    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8630    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8631    cmp     r0, #0                      @ is resolved entry null?
8632    beq     .LOP_SPUT_BYTE_JUMBO_resolve         @ yes, do resolve
8633.LOP_SPUT_BYTE_JUMBO_finish:   @ field ptr in r0
8634    FETCH(r2, 3)                        @ r2<- BBBB
8635    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8636    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8637    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8638    @ no-op                             @ releasing store
8639    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8640    GOTO_OPCODE(ip)                     @ jump to next instruction
8641
8642
8643/* ------------------------------ */
8644    .balign 64
8645.L_OP_SPUT_CHAR_JUMBO: /* 0x120 */
8646/* File: armv5te/OP_SPUT_CHAR_JUMBO.S */
8647/* File: armv5te/OP_SPUT_JUMBO.S */
8648    /*
8649     * Jumbo 32-bit SPUT handler.
8650     *
8651     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8652     *      sput-short/jumbo
8653     */
8654    /* exop vBBBB, field@AAAAAAAA */
8655    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8656    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8657    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8658    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8659    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8660    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8661    cmp     r0, #0                      @ is resolved entry null?
8662    beq     .LOP_SPUT_CHAR_JUMBO_resolve         @ yes, do resolve
8663.LOP_SPUT_CHAR_JUMBO_finish:   @ field ptr in r0
8664    FETCH(r2, 3)                        @ r2<- BBBB
8665    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8666    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8667    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8668    @ no-op                             @ releasing store
8669    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8670    GOTO_OPCODE(ip)                     @ jump to next instruction
8671
8672
8673/* ------------------------------ */
8674    .balign 64
8675.L_OP_SPUT_SHORT_JUMBO: /* 0x121 */
8676/* File: armv5te/OP_SPUT_SHORT_JUMBO.S */
8677/* File: armv5te/OP_SPUT_JUMBO.S */
8678    /*
8679     * Jumbo 32-bit SPUT handler.
8680     *
8681     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8682     *      sput-short/jumbo
8683     */
8684    /* exop vBBBB, field@AAAAAAAA */
8685    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8686    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8687    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8688    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8689    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8690    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8691    cmp     r0, #0                      @ is resolved entry null?
8692    beq     .LOP_SPUT_SHORT_JUMBO_resolve         @ yes, do resolve
8693.LOP_SPUT_SHORT_JUMBO_finish:   @ field ptr in r0
8694    FETCH(r2, 3)                        @ r2<- BBBB
8695    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8696    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8697    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8698    @ no-op                             @ releasing store
8699    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8700    GOTO_OPCODE(ip)                     @ jump to next instruction
8701
8702
8703/* ------------------------------ */
8704    .balign 64
8705.L_OP_INVOKE_VIRTUAL_JUMBO: /* 0x122 */
8706/* File: armv5te/OP_INVOKE_VIRTUAL_JUMBO.S */
8707    /*
8708     * Handle a virtual method call.
8709     */
8710    /* invoke-virtual/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8711    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
8712    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8713    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8714    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8715    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8716    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
8717    cmp     r0, #0                      @ already resolved?
8718    EXPORT_PC()                         @ must export for invoke
8719    bne     .LOP_INVOKE_VIRTUAL_JUMBO_continue        @ yes, continue on
8720    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
8721    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8722    mov     r2, #METHOD_VIRTUAL         @ resolver method type
8723    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8724    cmp     r0, #0                      @ got null?
8725    bne     .LOP_INVOKE_VIRTUAL_JUMBO_continue        @ no, continue
8726    b       common_exceptionThrown      @ yes, handle exception
8727
8728/* ------------------------------ */
8729    .balign 64
8730.L_OP_INVOKE_SUPER_JUMBO: /* 0x123 */
8731/* File: armv5te/OP_INVOKE_SUPER_JUMBO.S */
8732    /*
8733     * Handle a "super" method call.
8734     */
8735    /* invoke-super/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8736    FETCH(r10, 4)                       @ r10<- CCCC
8737    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
8738    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8739    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8740    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8741    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8742    GET_VREG(r2, r10)                   @ r2<- "this" ptr
8743    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
8744    cmp     r2, #0                      @ null "this"?
8745    ldr     r9, [rSELF, #offThread_method] @ r9<- current method
8746    beq     common_errNullObject        @ null "this", throw exception
8747    cmp     r0, #0                      @ already resolved?
8748    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
8749    EXPORT_PC()                         @ must export for invoke
8750    bne     .LOP_INVOKE_SUPER_JUMBO_continue        @ resolved, continue on
8751    b       .LOP_INVOKE_SUPER_JUMBO_resolve         @ do resolve now
8752
8753/* ------------------------------ */
8754    .balign 64
8755.L_OP_INVOKE_DIRECT_JUMBO: /* 0x124 */
8756/* File: armv5te/OP_INVOKE_DIRECT_JUMBO.S */
8757    /*
8758     * Handle a direct method call.
8759     *
8760     * (We could defer the "is 'this' pointer null" test to the common
8761     * method invocation code, and use a flag to indicate that static
8762     * calls don't count.  If we do this as part of copying the arguments
8763     * out we could avoiding loading the first arg twice.)
8764     *
8765     */
8766    /* invoke-direct/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8767    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
8768    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8769    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8770    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8771    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8772    FETCH(r10, 4)                       @ r10<- CCCC
8773    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
8774    cmp     r0, #0                      @ already resolved?
8775    EXPORT_PC()                         @ must export for invoke
8776    GET_VREG(r2, r10)                   @ r2<- "this" ptr
8777    beq     .LOP_INVOKE_DIRECT_JUMBO_resolve         @ not resolved, do it now
8778.LOP_INVOKE_DIRECT_JUMBO_finish:
8779    cmp     r2, #0                      @ null "this" ref?
8780    bne     common_invokeMethodJumbo    @ no, continue on
8781    b       common_errNullObject        @ yes, throw exception
8782
8783/* ------------------------------ */
8784    .balign 64
8785.L_OP_INVOKE_STATIC_JUMBO: /* 0x125 */
8786/* File: armv5te/OP_INVOKE_STATIC_JUMBO.S */
8787    /*
8788     * Handle a static method call.
8789     */
8790    /* invoke-static/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8791    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
8792    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8793    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8794    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8795    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8796    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
8797    cmp     r0, #0                      @ already resolved?
8798    EXPORT_PC()                         @ must export for invoke
8799    bne     common_invokeMethodJumbo    @ yes, continue on
88000:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
8801    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8802    mov     r2, #METHOD_STATIC          @ resolver method type
8803    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8804    cmp     r0, #0                      @ got null?
8805    bne     common_invokeMethodJumbo    @ no, continue
8806    b       common_exceptionThrown      @ yes, handle exception
8807
8808/* ------------------------------ */
8809    .balign 64
8810.L_OP_INVOKE_INTERFACE_JUMBO: /* 0x126 */
8811/* File: armv5te/OP_INVOKE_INTERFACE_JUMBO.S */
8812    /*
8813     * Handle an interface method call.
8814     */
8815    /* invoke-interface/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8816    FETCH(r2, 4)                        @ r2<- CCCC
8817    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8818    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8819    EXPORT_PC()                         @ must export for invoke
8820    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8821    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
8822    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- methodClassDex
8823    cmp     r0, #0                      @ null obj?
8824    ldr     r2, [rSELF, #offThread_method]  @ r2<- method
8825    beq     common_errNullObject        @ yes, fail
8826    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
8827    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
8828    cmp     r0, #0                      @ failed?
8829    beq     common_exceptionThrown      @ yes, handle exception
8830    b       common_invokeMethodJumbo    @ jump to common handler
8831
8832/* ------------------------------ */
8833    .balign 64
8834.L_OP_UNUSED_27FF: /* 0x127 */
8835/* File: armv5te/OP_UNUSED_27FF.S */
8836/* File: armv5te/unused.S */
8837    bl      common_abort
8838
8839
8840/* ------------------------------ */
8841    .balign 64
8842.L_OP_UNUSED_28FF: /* 0x128 */
8843/* File: armv5te/OP_UNUSED_28FF.S */
8844/* File: armv5te/unused.S */
8845    bl      common_abort
8846
8847
8848/* ------------------------------ */
8849    .balign 64
8850.L_OP_UNUSED_29FF: /* 0x129 */
8851/* File: armv5te/OP_UNUSED_29FF.S */
8852/* File: armv5te/unused.S */
8853    bl      common_abort
8854
8855
8856/* ------------------------------ */
8857    .balign 64
8858.L_OP_UNUSED_2AFF: /* 0x12a */
8859/* File: armv5te/OP_UNUSED_2AFF.S */
8860/* File: armv5te/unused.S */
8861    bl      common_abort
8862
8863
8864/* ------------------------------ */
8865    .balign 64
8866.L_OP_UNUSED_2BFF: /* 0x12b */
8867/* File: armv5te/OP_UNUSED_2BFF.S */
8868/* File: armv5te/unused.S */
8869    bl      common_abort
8870
8871
8872/* ------------------------------ */
8873    .balign 64
8874.L_OP_UNUSED_2CFF: /* 0x12c */
8875/* File: armv5te/OP_UNUSED_2CFF.S */
8876/* File: armv5te/unused.S */
8877    bl      common_abort
8878
8879
8880/* ------------------------------ */
8881    .balign 64
8882.L_OP_UNUSED_2DFF: /* 0x12d */
8883/* File: armv5te/OP_UNUSED_2DFF.S */
8884/* File: armv5te/unused.S */
8885    bl      common_abort
8886
8887
8888/* ------------------------------ */
8889    .balign 64
8890.L_OP_UNUSED_2EFF: /* 0x12e */
8891/* File: armv5te/OP_UNUSED_2EFF.S */
8892/* File: armv5te/unused.S */
8893    bl      common_abort
8894
8895
8896/* ------------------------------ */
8897    .balign 64
8898.L_OP_UNUSED_2FFF: /* 0x12f */
8899/* File: armv5te/OP_UNUSED_2FFF.S */
8900/* File: armv5te/unused.S */
8901    bl      common_abort
8902
8903
8904/* ------------------------------ */
8905    .balign 64
8906.L_OP_UNUSED_30FF: /* 0x130 */
8907/* File: armv5te/OP_UNUSED_30FF.S */
8908/* File: armv5te/unused.S */
8909    bl      common_abort
8910
8911
8912/* ------------------------------ */
8913    .balign 64
8914.L_OP_UNUSED_31FF: /* 0x131 */
8915/* File: armv5te/OP_UNUSED_31FF.S */
8916/* File: armv5te/unused.S */
8917    bl      common_abort
8918
8919
8920/* ------------------------------ */
8921    .balign 64
8922.L_OP_UNUSED_32FF: /* 0x132 */
8923/* File: armv5te/OP_UNUSED_32FF.S */
8924/* File: armv5te/unused.S */
8925    bl      common_abort
8926
8927
8928/* ------------------------------ */
8929    .balign 64
8930.L_OP_UNUSED_33FF: /* 0x133 */
8931/* File: armv5te/OP_UNUSED_33FF.S */
8932/* File: armv5te/unused.S */
8933    bl      common_abort
8934
8935
8936/* ------------------------------ */
8937    .balign 64
8938.L_OP_UNUSED_34FF: /* 0x134 */
8939/* File: armv5te/OP_UNUSED_34FF.S */
8940/* File: armv5te/unused.S */
8941    bl      common_abort
8942
8943
8944/* ------------------------------ */
8945    .balign 64
8946.L_OP_UNUSED_35FF: /* 0x135 */
8947/* File: armv5te/OP_UNUSED_35FF.S */
8948/* File: armv5te/unused.S */
8949    bl      common_abort
8950
8951
8952/* ------------------------------ */
8953    .balign 64
8954.L_OP_UNUSED_36FF: /* 0x136 */
8955/* File: armv5te/OP_UNUSED_36FF.S */
8956/* File: armv5te/unused.S */
8957    bl      common_abort
8958
8959
8960/* ------------------------------ */
8961    .balign 64
8962.L_OP_UNUSED_37FF: /* 0x137 */
8963/* File: armv5te/OP_UNUSED_37FF.S */
8964/* File: armv5te/unused.S */
8965    bl      common_abort
8966
8967
8968/* ------------------------------ */
8969    .balign 64
8970.L_OP_UNUSED_38FF: /* 0x138 */
8971/* File: armv5te/OP_UNUSED_38FF.S */
8972/* File: armv5te/unused.S */
8973    bl      common_abort
8974
8975
8976/* ------------------------------ */
8977    .balign 64
8978.L_OP_UNUSED_39FF: /* 0x139 */
8979/* File: armv5te/OP_UNUSED_39FF.S */
8980/* File: armv5te/unused.S */
8981    bl      common_abort
8982
8983
8984/* ------------------------------ */
8985    .balign 64
8986.L_OP_UNUSED_3AFF: /* 0x13a */
8987/* File: armv5te/OP_UNUSED_3AFF.S */
8988/* File: armv5te/unused.S */
8989    bl      common_abort
8990
8991
8992/* ------------------------------ */
8993    .balign 64
8994.L_OP_UNUSED_3BFF: /* 0x13b */
8995/* File: armv5te/OP_UNUSED_3BFF.S */
8996/* File: armv5te/unused.S */
8997    bl      common_abort
8998
8999
9000/* ------------------------------ */
9001    .balign 64
9002.L_OP_UNUSED_3CFF: /* 0x13c */
9003/* File: armv5te/OP_UNUSED_3CFF.S */
9004/* File: armv5te/unused.S */
9005    bl      common_abort
9006
9007
9008/* ------------------------------ */
9009    .balign 64
9010.L_OP_UNUSED_3DFF: /* 0x13d */
9011/* File: armv5te/OP_UNUSED_3DFF.S */
9012/* File: armv5te/unused.S */
9013    bl      common_abort
9014
9015
9016/* ------------------------------ */
9017    .balign 64
9018.L_OP_UNUSED_3EFF: /* 0x13e */
9019/* File: armv5te/OP_UNUSED_3EFF.S */
9020/* File: armv5te/unused.S */
9021    bl      common_abort
9022
9023
9024/* ------------------------------ */
9025    .balign 64
9026.L_OP_UNUSED_3FFF: /* 0x13f */
9027/* File: armv5te/OP_UNUSED_3FFF.S */
9028/* File: armv5te/unused.S */
9029    bl      common_abort
9030
9031
9032/* ------------------------------ */
9033    .balign 64
9034.L_OP_UNUSED_40FF: /* 0x140 */
9035/* File: armv5te/OP_UNUSED_40FF.S */
9036/* File: armv5te/unused.S */
9037    bl      common_abort
9038
9039
9040/* ------------------------------ */
9041    .balign 64
9042.L_OP_UNUSED_41FF: /* 0x141 */
9043/* File: armv5te/OP_UNUSED_41FF.S */
9044/* File: armv5te/unused.S */
9045    bl      common_abort
9046
9047
9048/* ------------------------------ */
9049    .balign 64
9050.L_OP_UNUSED_42FF: /* 0x142 */
9051/* File: armv5te/OP_UNUSED_42FF.S */
9052/* File: armv5te/unused.S */
9053    bl      common_abort
9054
9055
9056/* ------------------------------ */
9057    .balign 64
9058.L_OP_UNUSED_43FF: /* 0x143 */
9059/* File: armv5te/OP_UNUSED_43FF.S */
9060/* File: armv5te/unused.S */
9061    bl      common_abort
9062
9063
9064/* ------------------------------ */
9065    .balign 64
9066.L_OP_UNUSED_44FF: /* 0x144 */
9067/* File: armv5te/OP_UNUSED_44FF.S */
9068/* File: armv5te/unused.S */
9069    bl      common_abort
9070
9071
9072/* ------------------------------ */
9073    .balign 64
9074.L_OP_UNUSED_45FF: /* 0x145 */
9075/* File: armv5te/OP_UNUSED_45FF.S */
9076/* File: armv5te/unused.S */
9077    bl      common_abort
9078
9079
9080/* ------------------------------ */
9081    .balign 64
9082.L_OP_UNUSED_46FF: /* 0x146 */
9083/* File: armv5te/OP_UNUSED_46FF.S */
9084/* File: armv5te/unused.S */
9085    bl      common_abort
9086
9087
9088/* ------------------------------ */
9089    .balign 64
9090.L_OP_UNUSED_47FF: /* 0x147 */
9091/* File: armv5te/OP_UNUSED_47FF.S */
9092/* File: armv5te/unused.S */
9093    bl      common_abort
9094
9095
9096/* ------------------------------ */
9097    .balign 64
9098.L_OP_UNUSED_48FF: /* 0x148 */
9099/* File: armv5te/OP_UNUSED_48FF.S */
9100/* File: armv5te/unused.S */
9101    bl      common_abort
9102
9103
9104/* ------------------------------ */
9105    .balign 64
9106.L_OP_UNUSED_49FF: /* 0x149 */
9107/* File: armv5te/OP_UNUSED_49FF.S */
9108/* File: armv5te/unused.S */
9109    bl      common_abort
9110
9111
9112/* ------------------------------ */
9113    .balign 64
9114.L_OP_UNUSED_4AFF: /* 0x14a */
9115/* File: armv5te/OP_UNUSED_4AFF.S */
9116/* File: armv5te/unused.S */
9117    bl      common_abort
9118
9119
9120/* ------------------------------ */
9121    .balign 64
9122.L_OP_UNUSED_4BFF: /* 0x14b */
9123/* File: armv5te/OP_UNUSED_4BFF.S */
9124/* File: armv5te/unused.S */
9125    bl      common_abort
9126
9127
9128/* ------------------------------ */
9129    .balign 64
9130.L_OP_UNUSED_4CFF: /* 0x14c */
9131/* File: armv5te/OP_UNUSED_4CFF.S */
9132/* File: armv5te/unused.S */
9133    bl      common_abort
9134
9135
9136/* ------------------------------ */
9137    .balign 64
9138.L_OP_UNUSED_4DFF: /* 0x14d */
9139/* File: armv5te/OP_UNUSED_4DFF.S */
9140/* File: armv5te/unused.S */
9141    bl      common_abort
9142
9143
9144/* ------------------------------ */
9145    .balign 64
9146.L_OP_UNUSED_4EFF: /* 0x14e */
9147/* File: armv5te/OP_UNUSED_4EFF.S */
9148/* File: armv5te/unused.S */
9149    bl      common_abort
9150
9151
9152/* ------------------------------ */
9153    .balign 64
9154.L_OP_UNUSED_4FFF: /* 0x14f */
9155/* File: armv5te/OP_UNUSED_4FFF.S */
9156/* File: armv5te/unused.S */
9157    bl      common_abort
9158
9159
9160/* ------------------------------ */
9161    .balign 64
9162.L_OP_UNUSED_50FF: /* 0x150 */
9163/* File: armv5te/OP_UNUSED_50FF.S */
9164/* File: armv5te/unused.S */
9165    bl      common_abort
9166
9167
9168/* ------------------------------ */
9169    .balign 64
9170.L_OP_UNUSED_51FF: /* 0x151 */
9171/* File: armv5te/OP_UNUSED_51FF.S */
9172/* File: armv5te/unused.S */
9173    bl      common_abort
9174
9175
9176/* ------------------------------ */
9177    .balign 64
9178.L_OP_UNUSED_52FF: /* 0x152 */
9179/* File: armv5te/OP_UNUSED_52FF.S */
9180/* File: armv5te/unused.S */
9181    bl      common_abort
9182
9183
9184/* ------------------------------ */
9185    .balign 64
9186.L_OP_UNUSED_53FF: /* 0x153 */
9187/* File: armv5te/OP_UNUSED_53FF.S */
9188/* File: armv5te/unused.S */
9189    bl      common_abort
9190
9191
9192/* ------------------------------ */
9193    .balign 64
9194.L_OP_UNUSED_54FF: /* 0x154 */
9195/* File: armv5te/OP_UNUSED_54FF.S */
9196/* File: armv5te/unused.S */
9197    bl      common_abort
9198
9199
9200/* ------------------------------ */
9201    .balign 64
9202.L_OP_UNUSED_55FF: /* 0x155 */
9203/* File: armv5te/OP_UNUSED_55FF.S */
9204/* File: armv5te/unused.S */
9205    bl      common_abort
9206
9207
9208/* ------------------------------ */
9209    .balign 64
9210.L_OP_UNUSED_56FF: /* 0x156 */
9211/* File: armv5te/OP_UNUSED_56FF.S */
9212/* File: armv5te/unused.S */
9213    bl      common_abort
9214
9215
9216/* ------------------------------ */
9217    .balign 64
9218.L_OP_UNUSED_57FF: /* 0x157 */
9219/* File: armv5te/OP_UNUSED_57FF.S */
9220/* File: armv5te/unused.S */
9221    bl      common_abort
9222
9223
9224/* ------------------------------ */
9225    .balign 64
9226.L_OP_UNUSED_58FF: /* 0x158 */
9227/* File: armv5te/OP_UNUSED_58FF.S */
9228/* File: armv5te/unused.S */
9229    bl      common_abort
9230
9231
9232/* ------------------------------ */
9233    .balign 64
9234.L_OP_UNUSED_59FF: /* 0x159 */
9235/* File: armv5te/OP_UNUSED_59FF.S */
9236/* File: armv5te/unused.S */
9237    bl      common_abort
9238
9239
9240/* ------------------------------ */
9241    .balign 64
9242.L_OP_UNUSED_5AFF: /* 0x15a */
9243/* File: armv5te/OP_UNUSED_5AFF.S */
9244/* File: armv5te/unused.S */
9245    bl      common_abort
9246
9247
9248/* ------------------------------ */
9249    .balign 64
9250.L_OP_UNUSED_5BFF: /* 0x15b */
9251/* File: armv5te/OP_UNUSED_5BFF.S */
9252/* File: armv5te/unused.S */
9253    bl      common_abort
9254
9255
9256/* ------------------------------ */
9257    .balign 64
9258.L_OP_UNUSED_5CFF: /* 0x15c */
9259/* File: armv5te/OP_UNUSED_5CFF.S */
9260/* File: armv5te/unused.S */
9261    bl      common_abort
9262
9263
9264/* ------------------------------ */
9265    .balign 64
9266.L_OP_UNUSED_5DFF: /* 0x15d */
9267/* File: armv5te/OP_UNUSED_5DFF.S */
9268/* File: armv5te/unused.S */
9269    bl      common_abort
9270
9271
9272/* ------------------------------ */
9273    .balign 64
9274.L_OP_UNUSED_5EFF: /* 0x15e */
9275/* File: armv5te/OP_UNUSED_5EFF.S */
9276/* File: armv5te/unused.S */
9277    bl      common_abort
9278
9279
9280/* ------------------------------ */
9281    .balign 64
9282.L_OP_UNUSED_5FFF: /* 0x15f */
9283/* File: armv5te/OP_UNUSED_5FFF.S */
9284/* File: armv5te/unused.S */
9285    bl      common_abort
9286
9287
9288/* ------------------------------ */
9289    .balign 64
9290.L_OP_UNUSED_60FF: /* 0x160 */
9291/* File: armv5te/OP_UNUSED_60FF.S */
9292/* File: armv5te/unused.S */
9293    bl      common_abort
9294
9295
9296/* ------------------------------ */
9297    .balign 64
9298.L_OP_UNUSED_61FF: /* 0x161 */
9299/* File: armv5te/OP_UNUSED_61FF.S */
9300/* File: armv5te/unused.S */
9301    bl      common_abort
9302
9303
9304/* ------------------------------ */
9305    .balign 64
9306.L_OP_UNUSED_62FF: /* 0x162 */
9307/* File: armv5te/OP_UNUSED_62FF.S */
9308/* File: armv5te/unused.S */
9309    bl      common_abort
9310
9311
9312/* ------------------------------ */
9313    .balign 64
9314.L_OP_UNUSED_63FF: /* 0x163 */
9315/* File: armv5te/OP_UNUSED_63FF.S */
9316/* File: armv5te/unused.S */
9317    bl      common_abort
9318
9319
9320/* ------------------------------ */
9321    .balign 64
9322.L_OP_UNUSED_64FF: /* 0x164 */
9323/* File: armv5te/OP_UNUSED_64FF.S */
9324/* File: armv5te/unused.S */
9325    bl      common_abort
9326
9327
9328/* ------------------------------ */
9329    .balign 64
9330.L_OP_UNUSED_65FF: /* 0x165 */
9331/* File: armv5te/OP_UNUSED_65FF.S */
9332/* File: armv5te/unused.S */
9333    bl      common_abort
9334
9335
9336/* ------------------------------ */
9337    .balign 64
9338.L_OP_UNUSED_66FF: /* 0x166 */
9339/* File: armv5te/OP_UNUSED_66FF.S */
9340/* File: armv5te/unused.S */
9341    bl      common_abort
9342
9343
9344/* ------------------------------ */
9345    .balign 64
9346.L_OP_UNUSED_67FF: /* 0x167 */
9347/* File: armv5te/OP_UNUSED_67FF.S */
9348/* File: armv5te/unused.S */
9349    bl      common_abort
9350
9351
9352/* ------------------------------ */
9353    .balign 64
9354.L_OP_UNUSED_68FF: /* 0x168 */
9355/* File: armv5te/OP_UNUSED_68FF.S */
9356/* File: armv5te/unused.S */
9357    bl      common_abort
9358
9359
9360/* ------------------------------ */
9361    .balign 64
9362.L_OP_UNUSED_69FF: /* 0x169 */
9363/* File: armv5te/OP_UNUSED_69FF.S */
9364/* File: armv5te/unused.S */
9365    bl      common_abort
9366
9367
9368/* ------------------------------ */
9369    .balign 64
9370.L_OP_UNUSED_6AFF: /* 0x16a */
9371/* File: armv5te/OP_UNUSED_6AFF.S */
9372/* File: armv5te/unused.S */
9373    bl      common_abort
9374
9375
9376/* ------------------------------ */
9377    .balign 64
9378.L_OP_UNUSED_6BFF: /* 0x16b */
9379/* File: armv5te/OP_UNUSED_6BFF.S */
9380/* File: armv5te/unused.S */
9381    bl      common_abort
9382
9383
9384/* ------------------------------ */
9385    .balign 64
9386.L_OP_UNUSED_6CFF: /* 0x16c */
9387/* File: armv5te/OP_UNUSED_6CFF.S */
9388/* File: armv5te/unused.S */
9389    bl      common_abort
9390
9391
9392/* ------------------------------ */
9393    .balign 64
9394.L_OP_UNUSED_6DFF: /* 0x16d */
9395/* File: armv5te/OP_UNUSED_6DFF.S */
9396/* File: armv5te/unused.S */
9397    bl      common_abort
9398
9399
9400/* ------------------------------ */
9401    .balign 64
9402.L_OP_UNUSED_6EFF: /* 0x16e */
9403/* File: armv5te/OP_UNUSED_6EFF.S */
9404/* File: armv5te/unused.S */
9405    bl      common_abort
9406
9407
9408/* ------------------------------ */
9409    .balign 64
9410.L_OP_UNUSED_6FFF: /* 0x16f */
9411/* File: armv5te/OP_UNUSED_6FFF.S */
9412/* File: armv5te/unused.S */
9413    bl      common_abort
9414
9415
9416/* ------------------------------ */
9417    .balign 64
9418.L_OP_UNUSED_70FF: /* 0x170 */
9419/* File: armv5te/OP_UNUSED_70FF.S */
9420/* File: armv5te/unused.S */
9421    bl      common_abort
9422
9423
9424/* ------------------------------ */
9425    .balign 64
9426.L_OP_UNUSED_71FF: /* 0x171 */
9427/* File: armv5te/OP_UNUSED_71FF.S */
9428/* File: armv5te/unused.S */
9429    bl      common_abort
9430
9431
9432/* ------------------------------ */
9433    .balign 64
9434.L_OP_UNUSED_72FF: /* 0x172 */
9435/* File: armv5te/OP_UNUSED_72FF.S */
9436/* File: armv5te/unused.S */
9437    bl      common_abort
9438
9439
9440/* ------------------------------ */
9441    .balign 64
9442.L_OP_UNUSED_73FF: /* 0x173 */
9443/* File: armv5te/OP_UNUSED_73FF.S */
9444/* File: armv5te/unused.S */
9445    bl      common_abort
9446
9447
9448/* ------------------------------ */
9449    .balign 64
9450.L_OP_UNUSED_74FF: /* 0x174 */
9451/* File: armv5te/OP_UNUSED_74FF.S */
9452/* File: armv5te/unused.S */
9453    bl      common_abort
9454
9455
9456/* ------------------------------ */
9457    .balign 64
9458.L_OP_UNUSED_75FF: /* 0x175 */
9459/* File: armv5te/OP_UNUSED_75FF.S */
9460/* File: armv5te/unused.S */
9461    bl      common_abort
9462
9463
9464/* ------------------------------ */
9465    .balign 64
9466.L_OP_UNUSED_76FF: /* 0x176 */
9467/* File: armv5te/OP_UNUSED_76FF.S */
9468/* File: armv5te/unused.S */
9469    bl      common_abort
9470
9471
9472/* ------------------------------ */
9473    .balign 64
9474.L_OP_UNUSED_77FF: /* 0x177 */
9475/* File: armv5te/OP_UNUSED_77FF.S */
9476/* File: armv5te/unused.S */
9477    bl      common_abort
9478
9479
9480/* ------------------------------ */
9481    .balign 64
9482.L_OP_UNUSED_78FF: /* 0x178 */
9483/* File: armv5te/OP_UNUSED_78FF.S */
9484/* File: armv5te/unused.S */
9485    bl      common_abort
9486
9487
9488/* ------------------------------ */
9489    .balign 64
9490.L_OP_UNUSED_79FF: /* 0x179 */
9491/* File: armv5te/OP_UNUSED_79FF.S */
9492/* File: armv5te/unused.S */
9493    bl      common_abort
9494
9495
9496/* ------------------------------ */
9497    .balign 64
9498.L_OP_UNUSED_7AFF: /* 0x17a */
9499/* File: armv5te/OP_UNUSED_7AFF.S */
9500/* File: armv5te/unused.S */
9501    bl      common_abort
9502
9503
9504/* ------------------------------ */
9505    .balign 64
9506.L_OP_UNUSED_7BFF: /* 0x17b */
9507/* File: armv5te/OP_UNUSED_7BFF.S */
9508/* File: armv5te/unused.S */
9509    bl      common_abort
9510
9511
9512/* ------------------------------ */
9513    .balign 64
9514.L_OP_UNUSED_7CFF: /* 0x17c */
9515/* File: armv5te/OP_UNUSED_7CFF.S */
9516/* File: armv5te/unused.S */
9517    bl      common_abort
9518
9519
9520/* ------------------------------ */
9521    .balign 64
9522.L_OP_UNUSED_7DFF: /* 0x17d */
9523/* File: armv5te/OP_UNUSED_7DFF.S */
9524/* File: armv5te/unused.S */
9525    bl      common_abort
9526
9527
9528/* ------------------------------ */
9529    .balign 64
9530.L_OP_UNUSED_7EFF: /* 0x17e */
9531/* File: armv5te/OP_UNUSED_7EFF.S */
9532/* File: armv5te/unused.S */
9533    bl      common_abort
9534
9535
9536/* ------------------------------ */
9537    .balign 64
9538.L_OP_UNUSED_7FFF: /* 0x17f */
9539/* File: armv5te/OP_UNUSED_7FFF.S */
9540/* File: armv5te/unused.S */
9541    bl      common_abort
9542
9543
9544/* ------------------------------ */
9545    .balign 64
9546.L_OP_UNUSED_80FF: /* 0x180 */
9547/* File: armv5te/OP_UNUSED_80FF.S */
9548/* File: armv5te/unused.S */
9549    bl      common_abort
9550
9551
9552/* ------------------------------ */
9553    .balign 64
9554.L_OP_UNUSED_81FF: /* 0x181 */
9555/* File: armv5te/OP_UNUSED_81FF.S */
9556/* File: armv5te/unused.S */
9557    bl      common_abort
9558
9559
9560/* ------------------------------ */
9561    .balign 64
9562.L_OP_UNUSED_82FF: /* 0x182 */
9563/* File: armv5te/OP_UNUSED_82FF.S */
9564/* File: armv5te/unused.S */
9565    bl      common_abort
9566
9567
9568/* ------------------------------ */
9569    .balign 64
9570.L_OP_UNUSED_83FF: /* 0x183 */
9571/* File: armv5te/OP_UNUSED_83FF.S */
9572/* File: armv5te/unused.S */
9573    bl      common_abort
9574
9575
9576/* ------------------------------ */
9577    .balign 64
9578.L_OP_UNUSED_84FF: /* 0x184 */
9579/* File: armv5te/OP_UNUSED_84FF.S */
9580/* File: armv5te/unused.S */
9581    bl      common_abort
9582
9583
9584/* ------------------------------ */
9585    .balign 64
9586.L_OP_UNUSED_85FF: /* 0x185 */
9587/* File: armv5te/OP_UNUSED_85FF.S */
9588/* File: armv5te/unused.S */
9589    bl      common_abort
9590
9591
9592/* ------------------------------ */
9593    .balign 64
9594.L_OP_UNUSED_86FF: /* 0x186 */
9595/* File: armv5te/OP_UNUSED_86FF.S */
9596/* File: armv5te/unused.S */
9597    bl      common_abort
9598
9599
9600/* ------------------------------ */
9601    .balign 64
9602.L_OP_UNUSED_87FF: /* 0x187 */
9603/* File: armv5te/OP_UNUSED_87FF.S */
9604/* File: armv5te/unused.S */
9605    bl      common_abort
9606
9607
9608/* ------------------------------ */
9609    .balign 64
9610.L_OP_UNUSED_88FF: /* 0x188 */
9611/* File: armv5te/OP_UNUSED_88FF.S */
9612/* File: armv5te/unused.S */
9613    bl      common_abort
9614
9615
9616/* ------------------------------ */
9617    .balign 64
9618.L_OP_UNUSED_89FF: /* 0x189 */
9619/* File: armv5te/OP_UNUSED_89FF.S */
9620/* File: armv5te/unused.S */
9621    bl      common_abort
9622
9623
9624/* ------------------------------ */
9625    .balign 64
9626.L_OP_UNUSED_8AFF: /* 0x18a */
9627/* File: armv5te/OP_UNUSED_8AFF.S */
9628/* File: armv5te/unused.S */
9629    bl      common_abort
9630
9631
9632/* ------------------------------ */
9633    .balign 64
9634.L_OP_UNUSED_8BFF: /* 0x18b */
9635/* File: armv5te/OP_UNUSED_8BFF.S */
9636/* File: armv5te/unused.S */
9637    bl      common_abort
9638
9639
9640/* ------------------------------ */
9641    .balign 64
9642.L_OP_UNUSED_8CFF: /* 0x18c */
9643/* File: armv5te/OP_UNUSED_8CFF.S */
9644/* File: armv5te/unused.S */
9645    bl      common_abort
9646
9647
9648/* ------------------------------ */
9649    .balign 64
9650.L_OP_UNUSED_8DFF: /* 0x18d */
9651/* File: armv5te/OP_UNUSED_8DFF.S */
9652/* File: armv5te/unused.S */
9653    bl      common_abort
9654
9655
9656/* ------------------------------ */
9657    .balign 64
9658.L_OP_UNUSED_8EFF: /* 0x18e */
9659/* File: armv5te/OP_UNUSED_8EFF.S */
9660/* File: armv5te/unused.S */
9661    bl      common_abort
9662
9663
9664/* ------------------------------ */
9665    .balign 64
9666.L_OP_UNUSED_8FFF: /* 0x18f */
9667/* File: armv5te/OP_UNUSED_8FFF.S */
9668/* File: armv5te/unused.S */
9669    bl      common_abort
9670
9671
9672/* ------------------------------ */
9673    .balign 64
9674.L_OP_UNUSED_90FF: /* 0x190 */
9675/* File: armv5te/OP_UNUSED_90FF.S */
9676/* File: armv5te/unused.S */
9677    bl      common_abort
9678
9679
9680/* ------------------------------ */
9681    .balign 64
9682.L_OP_UNUSED_91FF: /* 0x191 */
9683/* File: armv5te/OP_UNUSED_91FF.S */
9684/* File: armv5te/unused.S */
9685    bl      common_abort
9686
9687
9688/* ------------------------------ */
9689    .balign 64
9690.L_OP_UNUSED_92FF: /* 0x192 */
9691/* File: armv5te/OP_UNUSED_92FF.S */
9692/* File: armv5te/unused.S */
9693    bl      common_abort
9694
9695
9696/* ------------------------------ */
9697    .balign 64
9698.L_OP_UNUSED_93FF: /* 0x193 */
9699/* File: armv5te/OP_UNUSED_93FF.S */
9700/* File: armv5te/unused.S */
9701    bl      common_abort
9702
9703
9704/* ------------------------------ */
9705    .balign 64
9706.L_OP_UNUSED_94FF: /* 0x194 */
9707/* File: armv5te/OP_UNUSED_94FF.S */
9708/* File: armv5te/unused.S */
9709    bl      common_abort
9710
9711
9712/* ------------------------------ */
9713    .balign 64
9714.L_OP_UNUSED_95FF: /* 0x195 */
9715/* File: armv5te/OP_UNUSED_95FF.S */
9716/* File: armv5te/unused.S */
9717    bl      common_abort
9718
9719
9720/* ------------------------------ */
9721    .balign 64
9722.L_OP_UNUSED_96FF: /* 0x196 */
9723/* File: armv5te/OP_UNUSED_96FF.S */
9724/* File: armv5te/unused.S */
9725    bl      common_abort
9726
9727
9728/* ------------------------------ */
9729    .balign 64
9730.L_OP_UNUSED_97FF: /* 0x197 */
9731/* File: armv5te/OP_UNUSED_97FF.S */
9732/* File: armv5te/unused.S */
9733    bl      common_abort
9734
9735
9736/* ------------------------------ */
9737    .balign 64
9738.L_OP_UNUSED_98FF: /* 0x198 */
9739/* File: armv5te/OP_UNUSED_98FF.S */
9740/* File: armv5te/unused.S */
9741    bl      common_abort
9742
9743
9744/* ------------------------------ */
9745    .balign 64
9746.L_OP_UNUSED_99FF: /* 0x199 */
9747/* File: armv5te/OP_UNUSED_99FF.S */
9748/* File: armv5te/unused.S */
9749    bl      common_abort
9750
9751
9752/* ------------------------------ */
9753    .balign 64
9754.L_OP_UNUSED_9AFF: /* 0x19a */
9755/* File: armv5te/OP_UNUSED_9AFF.S */
9756/* File: armv5te/unused.S */
9757    bl      common_abort
9758
9759
9760/* ------------------------------ */
9761    .balign 64
9762.L_OP_UNUSED_9BFF: /* 0x19b */
9763/* File: armv5te/OP_UNUSED_9BFF.S */
9764/* File: armv5te/unused.S */
9765    bl      common_abort
9766
9767
9768/* ------------------------------ */
9769    .balign 64
9770.L_OP_UNUSED_9CFF: /* 0x19c */
9771/* File: armv5te/OP_UNUSED_9CFF.S */
9772/* File: armv5te/unused.S */
9773    bl      common_abort
9774
9775
9776/* ------------------------------ */
9777    .balign 64
9778.L_OP_UNUSED_9DFF: /* 0x19d */
9779/* File: armv5te/OP_UNUSED_9DFF.S */
9780/* File: armv5te/unused.S */
9781    bl      common_abort
9782
9783
9784/* ------------------------------ */
9785    .balign 64
9786.L_OP_UNUSED_9EFF: /* 0x19e */
9787/* File: armv5te/OP_UNUSED_9EFF.S */
9788/* File: armv5te/unused.S */
9789    bl      common_abort
9790
9791
9792/* ------------------------------ */
9793    .balign 64
9794.L_OP_UNUSED_9FFF: /* 0x19f */
9795/* File: armv5te/OP_UNUSED_9FFF.S */
9796/* File: armv5te/unused.S */
9797    bl      common_abort
9798
9799
9800/* ------------------------------ */
9801    .balign 64
9802.L_OP_UNUSED_A0FF: /* 0x1a0 */
9803/* File: armv5te/OP_UNUSED_A0FF.S */
9804/* File: armv5te/unused.S */
9805    bl      common_abort
9806
9807
9808/* ------------------------------ */
9809    .balign 64
9810.L_OP_UNUSED_A1FF: /* 0x1a1 */
9811/* File: armv5te/OP_UNUSED_A1FF.S */
9812/* File: armv5te/unused.S */
9813    bl      common_abort
9814
9815
9816/* ------------------------------ */
9817    .balign 64
9818.L_OP_UNUSED_A2FF: /* 0x1a2 */
9819/* File: armv5te/OP_UNUSED_A2FF.S */
9820/* File: armv5te/unused.S */
9821    bl      common_abort
9822
9823
9824/* ------------------------------ */
9825    .balign 64
9826.L_OP_UNUSED_A3FF: /* 0x1a3 */
9827/* File: armv5te/OP_UNUSED_A3FF.S */
9828/* File: armv5te/unused.S */
9829    bl      common_abort
9830
9831
9832/* ------------------------------ */
9833    .balign 64
9834.L_OP_UNUSED_A4FF: /* 0x1a4 */
9835/* File: armv5te/OP_UNUSED_A4FF.S */
9836/* File: armv5te/unused.S */
9837    bl      common_abort
9838
9839
9840/* ------------------------------ */
9841    .balign 64
9842.L_OP_UNUSED_A5FF: /* 0x1a5 */
9843/* File: armv5te/OP_UNUSED_A5FF.S */
9844/* File: armv5te/unused.S */
9845    bl      common_abort
9846
9847
9848/* ------------------------------ */
9849    .balign 64
9850.L_OP_UNUSED_A6FF: /* 0x1a6 */
9851/* File: armv5te/OP_UNUSED_A6FF.S */
9852/* File: armv5te/unused.S */
9853    bl      common_abort
9854
9855
9856/* ------------------------------ */
9857    .balign 64
9858.L_OP_UNUSED_A7FF: /* 0x1a7 */
9859/* File: armv5te/OP_UNUSED_A7FF.S */
9860/* File: armv5te/unused.S */
9861    bl      common_abort
9862
9863
9864/* ------------------------------ */
9865    .balign 64
9866.L_OP_UNUSED_A8FF: /* 0x1a8 */
9867/* File: armv5te/OP_UNUSED_A8FF.S */
9868/* File: armv5te/unused.S */
9869    bl      common_abort
9870
9871
9872/* ------------------------------ */
9873    .balign 64
9874.L_OP_UNUSED_A9FF: /* 0x1a9 */
9875/* File: armv5te/OP_UNUSED_A9FF.S */
9876/* File: armv5te/unused.S */
9877    bl      common_abort
9878
9879
9880/* ------------------------------ */
9881    .balign 64
9882.L_OP_UNUSED_AAFF: /* 0x1aa */
9883/* File: armv5te/OP_UNUSED_AAFF.S */
9884/* File: armv5te/unused.S */
9885    bl      common_abort
9886
9887
9888/* ------------------------------ */
9889    .balign 64
9890.L_OP_UNUSED_ABFF: /* 0x1ab */
9891/* File: armv5te/OP_UNUSED_ABFF.S */
9892/* File: armv5te/unused.S */
9893    bl      common_abort
9894
9895
9896/* ------------------------------ */
9897    .balign 64
9898.L_OP_UNUSED_ACFF: /* 0x1ac */
9899/* File: armv5te/OP_UNUSED_ACFF.S */
9900/* File: armv5te/unused.S */
9901    bl      common_abort
9902
9903
9904/* ------------------------------ */
9905    .balign 64
9906.L_OP_UNUSED_ADFF: /* 0x1ad */
9907/* File: armv5te/OP_UNUSED_ADFF.S */
9908/* File: armv5te/unused.S */
9909    bl      common_abort
9910
9911
9912/* ------------------------------ */
9913    .balign 64
9914.L_OP_UNUSED_AEFF: /* 0x1ae */
9915/* File: armv5te/OP_UNUSED_AEFF.S */
9916/* File: armv5te/unused.S */
9917    bl      common_abort
9918
9919
9920/* ------------------------------ */
9921    .balign 64
9922.L_OP_UNUSED_AFFF: /* 0x1af */
9923/* File: armv5te/OP_UNUSED_AFFF.S */
9924/* File: armv5te/unused.S */
9925    bl      common_abort
9926
9927
9928/* ------------------------------ */
9929    .balign 64
9930.L_OP_UNUSED_B0FF: /* 0x1b0 */
9931/* File: armv5te/OP_UNUSED_B0FF.S */
9932/* File: armv5te/unused.S */
9933    bl      common_abort
9934
9935
9936/* ------------------------------ */
9937    .balign 64
9938.L_OP_UNUSED_B1FF: /* 0x1b1 */
9939/* File: armv5te/OP_UNUSED_B1FF.S */
9940/* File: armv5te/unused.S */
9941    bl      common_abort
9942
9943
9944/* ------------------------------ */
9945    .balign 64
9946.L_OP_UNUSED_B2FF: /* 0x1b2 */
9947/* File: armv5te/OP_UNUSED_B2FF.S */
9948/* File: armv5te/unused.S */
9949    bl      common_abort
9950
9951
9952/* ------------------------------ */
9953    .balign 64
9954.L_OP_UNUSED_B3FF: /* 0x1b3 */
9955/* File: armv5te/OP_UNUSED_B3FF.S */
9956/* File: armv5te/unused.S */
9957    bl      common_abort
9958
9959
9960/* ------------------------------ */
9961    .balign 64
9962.L_OP_UNUSED_B4FF: /* 0x1b4 */
9963/* File: armv5te/OP_UNUSED_B4FF.S */
9964/* File: armv5te/unused.S */
9965    bl      common_abort
9966
9967
9968/* ------------------------------ */
9969    .balign 64
9970.L_OP_UNUSED_B5FF: /* 0x1b5 */
9971/* File: armv5te/OP_UNUSED_B5FF.S */
9972/* File: armv5te/unused.S */
9973    bl      common_abort
9974
9975
9976/* ------------------------------ */
9977    .balign 64
9978.L_OP_UNUSED_B6FF: /* 0x1b6 */
9979/* File: armv5te/OP_UNUSED_B6FF.S */
9980/* File: armv5te/unused.S */
9981    bl      common_abort
9982
9983
9984/* ------------------------------ */
9985    .balign 64
9986.L_OP_UNUSED_B7FF: /* 0x1b7 */
9987/* File: armv5te/OP_UNUSED_B7FF.S */
9988/* File: armv5te/unused.S */
9989    bl      common_abort
9990
9991
9992/* ------------------------------ */
9993    .balign 64
9994.L_OP_UNUSED_B8FF: /* 0x1b8 */
9995/* File: armv5te/OP_UNUSED_B8FF.S */
9996/* File: armv5te/unused.S */
9997    bl      common_abort
9998
9999
10000/* ------------------------------ */
10001    .balign 64
10002.L_OP_UNUSED_B9FF: /* 0x1b9 */
10003/* File: armv5te/OP_UNUSED_B9FF.S */
10004/* File: armv5te/unused.S */
10005    bl      common_abort
10006
10007
10008/* ------------------------------ */
10009    .balign 64
10010.L_OP_UNUSED_BAFF: /* 0x1ba */
10011/* File: armv5te/OP_UNUSED_BAFF.S */
10012/* File: armv5te/unused.S */
10013    bl      common_abort
10014
10015
10016/* ------------------------------ */
10017    .balign 64
10018.L_OP_UNUSED_BBFF: /* 0x1bb */
10019/* File: armv5te/OP_UNUSED_BBFF.S */
10020/* File: armv5te/unused.S */
10021    bl      common_abort
10022
10023
10024/* ------------------------------ */
10025    .balign 64
10026.L_OP_UNUSED_BCFF: /* 0x1bc */
10027/* File: armv5te/OP_UNUSED_BCFF.S */
10028/* File: armv5te/unused.S */
10029    bl      common_abort
10030
10031
10032/* ------------------------------ */
10033    .balign 64
10034.L_OP_UNUSED_BDFF: /* 0x1bd */
10035/* File: armv5te/OP_UNUSED_BDFF.S */
10036/* File: armv5te/unused.S */
10037    bl      common_abort
10038
10039
10040/* ------------------------------ */
10041    .balign 64
10042.L_OP_UNUSED_BEFF: /* 0x1be */
10043/* File: armv5te/OP_UNUSED_BEFF.S */
10044/* File: armv5te/unused.S */
10045    bl      common_abort
10046
10047
10048/* ------------------------------ */
10049    .balign 64
10050.L_OP_UNUSED_BFFF: /* 0x1bf */
10051/* File: armv5te/OP_UNUSED_BFFF.S */
10052/* File: armv5te/unused.S */
10053    bl      common_abort
10054
10055
10056/* ------------------------------ */
10057    .balign 64
10058.L_OP_UNUSED_C0FF: /* 0x1c0 */
10059/* File: armv5te/OP_UNUSED_C0FF.S */
10060/* File: armv5te/unused.S */
10061    bl      common_abort
10062
10063
10064/* ------------------------------ */
10065    .balign 64
10066.L_OP_UNUSED_C1FF: /* 0x1c1 */
10067/* File: armv5te/OP_UNUSED_C1FF.S */
10068/* File: armv5te/unused.S */
10069    bl      common_abort
10070
10071
10072/* ------------------------------ */
10073    .balign 64
10074.L_OP_UNUSED_C2FF: /* 0x1c2 */
10075/* File: armv5te/OP_UNUSED_C2FF.S */
10076/* File: armv5te/unused.S */
10077    bl      common_abort
10078
10079
10080/* ------------------------------ */
10081    .balign 64
10082.L_OP_UNUSED_C3FF: /* 0x1c3 */
10083/* File: armv5te/OP_UNUSED_C3FF.S */
10084/* File: armv5te/unused.S */
10085    bl      common_abort
10086
10087
10088/* ------------------------------ */
10089    .balign 64
10090.L_OP_UNUSED_C4FF: /* 0x1c4 */
10091/* File: armv5te/OP_UNUSED_C4FF.S */
10092/* File: armv5te/unused.S */
10093    bl      common_abort
10094
10095
10096/* ------------------------------ */
10097    .balign 64
10098.L_OP_UNUSED_C5FF: /* 0x1c5 */
10099/* File: armv5te/OP_UNUSED_C5FF.S */
10100/* File: armv5te/unused.S */
10101    bl      common_abort
10102
10103
10104/* ------------------------------ */
10105    .balign 64
10106.L_OP_UNUSED_C6FF: /* 0x1c6 */
10107/* File: armv5te/OP_UNUSED_C6FF.S */
10108/* File: armv5te/unused.S */
10109    bl      common_abort
10110
10111
10112/* ------------------------------ */
10113    .balign 64
10114.L_OP_UNUSED_C7FF: /* 0x1c7 */
10115/* File: armv5te/OP_UNUSED_C7FF.S */
10116/* File: armv5te/unused.S */
10117    bl      common_abort
10118
10119
10120/* ------------------------------ */
10121    .balign 64
10122.L_OP_UNUSED_C8FF: /* 0x1c8 */
10123/* File: armv5te/OP_UNUSED_C8FF.S */
10124/* File: armv5te/unused.S */
10125    bl      common_abort
10126
10127
10128/* ------------------------------ */
10129    .balign 64
10130.L_OP_UNUSED_C9FF: /* 0x1c9 */
10131/* File: armv5te/OP_UNUSED_C9FF.S */
10132/* File: armv5te/unused.S */
10133    bl      common_abort
10134
10135
10136/* ------------------------------ */
10137    .balign 64
10138.L_OP_UNUSED_CAFF: /* 0x1ca */
10139/* File: armv5te/OP_UNUSED_CAFF.S */
10140/* File: armv5te/unused.S */
10141    bl      common_abort
10142
10143
10144/* ------------------------------ */
10145    .balign 64
10146.L_OP_UNUSED_CBFF: /* 0x1cb */
10147/* File: armv5te/OP_UNUSED_CBFF.S */
10148/* File: armv5te/unused.S */
10149    bl      common_abort
10150
10151
10152/* ------------------------------ */
10153    .balign 64
10154.L_OP_UNUSED_CCFF: /* 0x1cc */
10155/* File: armv5te/OP_UNUSED_CCFF.S */
10156/* File: armv5te/unused.S */
10157    bl      common_abort
10158
10159
10160/* ------------------------------ */
10161    .balign 64
10162.L_OP_UNUSED_CDFF: /* 0x1cd */
10163/* File: armv5te/OP_UNUSED_CDFF.S */
10164/* File: armv5te/unused.S */
10165    bl      common_abort
10166
10167
10168/* ------------------------------ */
10169    .balign 64
10170.L_OP_UNUSED_CEFF: /* 0x1ce */
10171/* File: armv5te/OP_UNUSED_CEFF.S */
10172/* File: armv5te/unused.S */
10173    bl      common_abort
10174
10175
10176/* ------------------------------ */
10177    .balign 64
10178.L_OP_UNUSED_CFFF: /* 0x1cf */
10179/* File: armv5te/OP_UNUSED_CFFF.S */
10180/* File: armv5te/unused.S */
10181    bl      common_abort
10182
10183
10184/* ------------------------------ */
10185    .balign 64
10186.L_OP_UNUSED_D0FF: /* 0x1d0 */
10187/* File: armv5te/OP_UNUSED_D0FF.S */
10188/* File: armv5te/unused.S */
10189    bl      common_abort
10190
10191
10192/* ------------------------------ */
10193    .balign 64
10194.L_OP_UNUSED_D1FF: /* 0x1d1 */
10195/* File: armv5te/OP_UNUSED_D1FF.S */
10196/* File: armv5te/unused.S */
10197    bl      common_abort
10198
10199
10200/* ------------------------------ */
10201    .balign 64
10202.L_OP_UNUSED_D2FF: /* 0x1d2 */
10203/* File: armv5te/OP_UNUSED_D2FF.S */
10204/* File: armv5te/unused.S */
10205    bl      common_abort
10206
10207
10208/* ------------------------------ */
10209    .balign 64
10210.L_OP_UNUSED_D3FF: /* 0x1d3 */
10211/* File: armv5te/OP_UNUSED_D3FF.S */
10212/* File: armv5te/unused.S */
10213    bl      common_abort
10214
10215
10216/* ------------------------------ */
10217    .balign 64
10218.L_OP_UNUSED_D4FF: /* 0x1d4 */
10219/* File: armv5te/OP_UNUSED_D4FF.S */
10220/* File: armv5te/unused.S */
10221    bl      common_abort
10222
10223
10224/* ------------------------------ */
10225    .balign 64
10226.L_OP_UNUSED_D5FF: /* 0x1d5 */
10227/* File: armv5te/OP_UNUSED_D5FF.S */
10228/* File: armv5te/unused.S */
10229    bl      common_abort
10230
10231
10232/* ------------------------------ */
10233    .balign 64
10234.L_OP_UNUSED_D6FF: /* 0x1d6 */
10235/* File: armv5te/OP_UNUSED_D6FF.S */
10236/* File: armv5te/unused.S */
10237    bl      common_abort
10238
10239
10240/* ------------------------------ */
10241    .balign 64
10242.L_OP_UNUSED_D7FF: /* 0x1d7 */
10243/* File: armv5te/OP_UNUSED_D7FF.S */
10244/* File: armv5te/unused.S */
10245    bl      common_abort
10246
10247
10248/* ------------------------------ */
10249    .balign 64
10250.L_OP_UNUSED_D8FF: /* 0x1d8 */
10251/* File: armv5te/OP_UNUSED_D8FF.S */
10252/* File: armv5te/unused.S */
10253    bl      common_abort
10254
10255
10256/* ------------------------------ */
10257    .balign 64
10258.L_OP_UNUSED_D9FF: /* 0x1d9 */
10259/* File: armv5te/OP_UNUSED_D9FF.S */
10260/* File: armv5te/unused.S */
10261    bl      common_abort
10262
10263
10264/* ------------------------------ */
10265    .balign 64
10266.L_OP_UNUSED_DAFF: /* 0x1da */
10267/* File: armv5te/OP_UNUSED_DAFF.S */
10268/* File: armv5te/unused.S */
10269    bl      common_abort
10270
10271
10272/* ------------------------------ */
10273    .balign 64
10274.L_OP_UNUSED_DBFF: /* 0x1db */
10275/* File: armv5te/OP_UNUSED_DBFF.S */
10276/* File: armv5te/unused.S */
10277    bl      common_abort
10278
10279
10280/* ------------------------------ */
10281    .balign 64
10282.L_OP_UNUSED_DCFF: /* 0x1dc */
10283/* File: armv5te/OP_UNUSED_DCFF.S */
10284/* File: armv5te/unused.S */
10285    bl      common_abort
10286
10287
10288/* ------------------------------ */
10289    .balign 64
10290.L_OP_UNUSED_DDFF: /* 0x1dd */
10291/* File: armv5te/OP_UNUSED_DDFF.S */
10292/* File: armv5te/unused.S */
10293    bl      common_abort
10294
10295
10296/* ------------------------------ */
10297    .balign 64
10298.L_OP_UNUSED_DEFF: /* 0x1de */
10299/* File: armv5te/OP_UNUSED_DEFF.S */
10300/* File: armv5te/unused.S */
10301    bl      common_abort
10302
10303
10304/* ------------------------------ */
10305    .balign 64
10306.L_OP_UNUSED_DFFF: /* 0x1df */
10307/* File: armv5te/OP_UNUSED_DFFF.S */
10308/* File: armv5te/unused.S */
10309    bl      common_abort
10310
10311
10312/* ------------------------------ */
10313    .balign 64
10314.L_OP_UNUSED_E0FF: /* 0x1e0 */
10315/* File: armv5te/OP_UNUSED_E0FF.S */
10316/* File: armv5te/unused.S */
10317    bl      common_abort
10318
10319
10320/* ------------------------------ */
10321    .balign 64
10322.L_OP_UNUSED_E1FF: /* 0x1e1 */
10323/* File: armv5te/OP_UNUSED_E1FF.S */
10324/* File: armv5te/unused.S */
10325    bl      common_abort
10326
10327
10328/* ------------------------------ */
10329    .balign 64
10330.L_OP_UNUSED_E2FF: /* 0x1e2 */
10331/* File: armv5te/OP_UNUSED_E2FF.S */
10332/* File: armv5te/unused.S */
10333    bl      common_abort
10334
10335
10336/* ------------------------------ */
10337    .balign 64
10338.L_OP_UNUSED_E3FF: /* 0x1e3 */
10339/* File: armv5te/OP_UNUSED_E3FF.S */
10340/* File: armv5te/unused.S */
10341    bl      common_abort
10342
10343
10344/* ------------------------------ */
10345    .balign 64
10346.L_OP_UNUSED_E4FF: /* 0x1e4 */
10347/* File: armv5te/OP_UNUSED_E4FF.S */
10348/* File: armv5te/unused.S */
10349    bl      common_abort
10350
10351
10352/* ------------------------------ */
10353    .balign 64
10354.L_OP_UNUSED_E5FF: /* 0x1e5 */
10355/* File: armv5te/OP_UNUSED_E5FF.S */
10356/* File: armv5te/unused.S */
10357    bl      common_abort
10358
10359
10360/* ------------------------------ */
10361    .balign 64
10362.L_OP_UNUSED_E6FF: /* 0x1e6 */
10363/* File: armv5te/OP_UNUSED_E6FF.S */
10364/* File: armv5te/unused.S */
10365    bl      common_abort
10366
10367
10368/* ------------------------------ */
10369    .balign 64
10370.L_OP_UNUSED_E7FF: /* 0x1e7 */
10371/* File: armv5te/OP_UNUSED_E7FF.S */
10372/* File: armv5te/unused.S */
10373    bl      common_abort
10374
10375
10376/* ------------------------------ */
10377    .balign 64
10378.L_OP_UNUSED_E8FF: /* 0x1e8 */
10379/* File: armv5te/OP_UNUSED_E8FF.S */
10380/* File: armv5te/unused.S */
10381    bl      common_abort
10382
10383
10384/* ------------------------------ */
10385    .balign 64
10386.L_OP_UNUSED_E9FF: /* 0x1e9 */
10387/* File: armv5te/OP_UNUSED_E9FF.S */
10388/* File: armv5te/unused.S */
10389    bl      common_abort
10390
10391
10392/* ------------------------------ */
10393    .balign 64
10394.L_OP_UNUSED_EAFF: /* 0x1ea */
10395/* File: armv5te/OP_UNUSED_EAFF.S */
10396/* File: armv5te/unused.S */
10397    bl      common_abort
10398
10399
10400/* ------------------------------ */
10401    .balign 64
10402.L_OP_UNUSED_EBFF: /* 0x1eb */
10403/* File: armv5te/OP_UNUSED_EBFF.S */
10404/* File: armv5te/unused.S */
10405    bl      common_abort
10406
10407
10408/* ------------------------------ */
10409    .balign 64
10410.L_OP_UNUSED_ECFF: /* 0x1ec */
10411/* File: armv5te/OP_UNUSED_ECFF.S */
10412/* File: armv5te/unused.S */
10413    bl      common_abort
10414
10415
10416/* ------------------------------ */
10417    .balign 64
10418.L_OP_UNUSED_EDFF: /* 0x1ed */
10419/* File: armv5te/OP_UNUSED_EDFF.S */
10420/* File: armv5te/unused.S */
10421    bl      common_abort
10422
10423
10424/* ------------------------------ */
10425    .balign 64
10426.L_OP_UNUSED_EEFF: /* 0x1ee */
10427/* File: armv5te/OP_UNUSED_EEFF.S */
10428/* File: armv5te/unused.S */
10429    bl      common_abort
10430
10431
10432/* ------------------------------ */
10433    .balign 64
10434.L_OP_UNUSED_EFFF: /* 0x1ef */
10435/* File: armv5te/OP_UNUSED_EFFF.S */
10436/* File: armv5te/unused.S */
10437    bl      common_abort
10438
10439
10440/* ------------------------------ */
10441    .balign 64
10442.L_OP_UNUSED_F0FF: /* 0x1f0 */
10443/* File: armv5te/OP_UNUSED_F0FF.S */
10444/* File: armv5te/unused.S */
10445    bl      common_abort
10446
10447
10448/* ------------------------------ */
10449    .balign 64
10450.L_OP_UNUSED_F1FF: /* 0x1f1 */
10451/* File: armv5te/OP_UNUSED_F1FF.S */
10452/* File: armv5te/unused.S */
10453    bl      common_abort
10454
10455
10456/* ------------------------------ */
10457    .balign 64
10458.L_OP_UNUSED_F2FF: /* 0x1f2 */
10459/* File: armv5te/OP_UNUSED_F2FF.S */
10460/* File: armv5te/unused.S */
10461    bl      common_abort
10462
10463
10464/* ------------------------------ */
10465    .balign 64
10466.L_OP_UNUSED_F3FF: /* 0x1f3 */
10467/* File: armv5te/OP_UNUSED_F3FF.S */
10468/* File: armv5te/unused.S */
10469    bl      common_abort
10470
10471
10472/* ------------------------------ */
10473    .balign 64
10474.L_OP_UNUSED_F4FF: /* 0x1f4 */
10475/* File: armv5te/OP_UNUSED_F4FF.S */
10476/* File: armv5te/unused.S */
10477    bl      common_abort
10478
10479
10480/* ------------------------------ */
10481    .balign 64
10482.L_OP_UNUSED_F5FF: /* 0x1f5 */
10483/* File: armv5te/OP_UNUSED_F5FF.S */
10484/* File: armv5te/unused.S */
10485    bl      common_abort
10486
10487
10488/* ------------------------------ */
10489    .balign 64
10490.L_OP_UNUSED_F6FF: /* 0x1f6 */
10491/* File: armv5te/OP_UNUSED_F6FF.S */
10492/* File: armv5te/unused.S */
10493    bl      common_abort
10494
10495
10496/* ------------------------------ */
10497    .balign 64
10498.L_OP_UNUSED_F7FF: /* 0x1f7 */
10499/* File: armv5te/OP_UNUSED_F7FF.S */
10500/* File: armv5te/unused.S */
10501    bl      common_abort
10502
10503
10504/* ------------------------------ */
10505    .balign 64
10506.L_OP_UNUSED_F8FF: /* 0x1f8 */
10507/* File: armv5te/OP_UNUSED_F8FF.S */
10508/* File: armv5te/unused.S */
10509    bl      common_abort
10510
10511
10512/* ------------------------------ */
10513    .balign 64
10514.L_OP_UNUSED_F9FF: /* 0x1f9 */
10515/* File: armv5te/OP_UNUSED_F9FF.S */
10516/* File: armv5te/unused.S */
10517    bl      common_abort
10518
10519
10520/* ------------------------------ */
10521    .balign 64
10522.L_OP_UNUSED_FAFF: /* 0x1fa */
10523/* File: armv5te/OP_UNUSED_FAFF.S */
10524/* File: armv5te/unused.S */
10525    bl      common_abort
10526
10527
10528/* ------------------------------ */
10529    .balign 64
10530.L_OP_UNUSED_FBFF: /* 0x1fb */
10531/* File: armv5te/OP_UNUSED_FBFF.S */
10532/* File: armv5te/unused.S */
10533    bl      common_abort
10534
10535
10536/* ------------------------------ */
10537    .balign 64
10538.L_OP_UNUSED_FCFF: /* 0x1fc */
10539/* File: armv5te/OP_UNUSED_FCFF.S */
10540/* File: armv5te/unused.S */
10541    bl      common_abort
10542
10543
10544/* ------------------------------ */
10545    .balign 64
10546.L_OP_UNUSED_FDFF: /* 0x1fd */
10547/* File: armv5te/OP_UNUSED_FDFF.S */
10548/* File: armv5te/unused.S */
10549    bl      common_abort
10550
10551
10552/* ------------------------------ */
10553    .balign 64
10554.L_OP_UNUSED_FEFF: /* 0x1fe */
10555/* File: armv5te/OP_UNUSED_FEFF.S */
10556/* File: armv5te/unused.S */
10557    bl      common_abort
10558
10559
10560/* ------------------------------ */
10561    .balign 64
10562.L_OP_THROW_VERIFICATION_ERROR_JUMBO: /* 0x1ff */
10563/* File: armv5te/OP_THROW_VERIFICATION_ERROR_JUMBO.S */
10564    /*
10565     * Handle a jumbo throw-verification-error instruction.  This throws an
10566     * exception for an error discovered during verification.  The
10567     * exception is indicated by BBBB, with some detail provided by AAAAAAAA.
10568     */
10569    /* exop BBBB, Class@AAAAAAAA */
10570    FETCH(r1, 1)                        @ r1<- aaaa (lo)
10571    FETCH(r2, 2)                        @ r2<- AAAA (hi)
10572    ldr     r0, [rSELF, #offThread_method]    @ r0<- self->method
10573    orr     r2, r1, r2, lsl #16         @ r2<- AAAAaaaa
10574    EXPORT_PC()                         @ export the PC
10575    FETCH(r1, 3)                        @ r1<- BBBB
10576    bl      dvmThrowVerificationError   @ always throws
10577    b       common_exceptionThrown      @ handle exception
10578
10579
10580    .balign 64
10581    .size   .L_OP_NOP, .-.L_OP_NOP
10582    .global dvmAsmInstructionEnd
10583dvmAsmInstructionEnd:
10584
10585/*
10586 * ===========================================================================
10587 *  Sister implementations
10588 * ===========================================================================
10589 */
10590    .global dvmAsmSisterStart
10591    .type   dvmAsmSisterStart, %function
10592    .text
10593    .balign 4
10594dvmAsmSisterStart:
10595
10596/* continuation for OP_CONST_STRING */
10597
10598    /*
10599     * Continuation if the String has not yet been resolved.
10600     *  r1: BBBB (String ref)
10601     *  r9: target register
10602     */
10603.LOP_CONST_STRING_resolve:
10604    EXPORT_PC()
10605    ldr     r0, [rSELF, #offThread_method] @ r0<- self->method
10606    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10607    bl      dvmResolveString            @ r0<- String reference
10608    cmp     r0, #0                      @ failed?
10609    beq     common_exceptionThrown      @ yup, handle the exception
10610    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10611    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10612    SET_VREG(r0, r9)                    @ vAA<- r0
10613    GOTO_OPCODE(ip)                     @ jump to next instruction
10614
10615/* continuation for OP_CONST_STRING_JUMBO */
10616
10617    /*
10618     * Continuation if the String has not yet been resolved.
10619     *  r1: BBBBBBBB (String ref)
10620     *  r9: target register
10621     */
10622.LOP_CONST_STRING_JUMBO_resolve:
10623    EXPORT_PC()
10624    ldr     r0, [rSELF, #offThread_method] @ r0<- self->method
10625    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10626    bl      dvmResolveString            @ r0<- String reference
10627    cmp     r0, #0                      @ failed?
10628    beq     common_exceptionThrown      @ yup, handle the exception
10629    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
10630    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10631    SET_VREG(r0, r9)                    @ vAA<- r0
10632    GOTO_OPCODE(ip)                     @ jump to next instruction
10633
10634/* continuation for OP_CONST_CLASS */
10635
10636    /*
10637     * Continuation if the Class has not yet been resolved.
10638     *  r1: BBBB (Class ref)
10639     *  r9: target register
10640     */
10641.LOP_CONST_CLASS_resolve:
10642    EXPORT_PC()
10643    ldr     r0, [rSELF, #offThread_method] @ r0<- self->method
10644    mov     r2, #1                      @ r2<- true
10645    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10646    bl      dvmResolveClass             @ r0<- Class reference
10647    cmp     r0, #0                      @ failed?
10648    beq     common_exceptionThrown      @ yup, handle the exception
10649    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10650    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10651    SET_VREG(r0, r9)                    @ vAA<- r0
10652    GOTO_OPCODE(ip)                     @ jump to next instruction
10653
10654/* continuation for OP_CHECK_CAST */
10655
10656    /*
10657     * Trivial test failed, need to perform full check.  This is common.
10658     *  r0 holds obj->clazz
10659     *  r1 holds desired class resolved from BBBB
10660     *  r9 holds object
10661     */
10662.LOP_CHECK_CAST_fullcheck:
10663    mov     r10, r1                     @ avoid ClassObject getting clobbered
10664    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
10665    cmp     r0, #0                      @ failed?
10666    bne     .LOP_CHECK_CAST_okay            @ no, success
10667
10668    @ A cast has failed.  We need to throw a ClassCastException.
10669    EXPORT_PC()                         @ about to throw
10670    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
10671    mov     r1, r10                     @ r1<- desired class
10672    bl      dvmThrowClassCastException
10673    b       common_exceptionThrown
10674
10675    /*
10676     * Resolution required.  This is the least-likely path.
10677     *
10678     *  r2 holds BBBB
10679     *  r9 holds object
10680     */
10681.LOP_CHECK_CAST_resolve:
10682    EXPORT_PC()                         @ resolve() could throw
10683    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
10684    mov     r1, r2                      @ r1<- BBBB
10685    mov     r2, #0                      @ r2<- false
10686    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10687    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10688    cmp     r0, #0                      @ got null?
10689    beq     common_exceptionThrown      @ yes, handle exception
10690    mov     r1, r0                      @ r1<- class resolved from BBB
10691    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
10692    b       .LOP_CHECK_CAST_resolved        @ pick up where we left off
10693
10694/* continuation for OP_INSTANCE_OF */
10695
10696    /*
10697     * Trivial test failed, need to perform full check.  This is common.
10698     *  r0 holds obj->clazz
10699     *  r1 holds class resolved from BBBB
10700     *  r9 holds A
10701     */
10702.LOP_INSTANCE_OF_fullcheck:
10703    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
10704    @ fall through to OP_INSTANCE_OF_store
10705
10706    /*
10707     * r0 holds boolean result
10708     * r9 holds A
10709     */
10710.LOP_INSTANCE_OF_store:
10711    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10712    SET_VREG(r0, r9)                    @ vA<- r0
10713    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10714    GOTO_OPCODE(ip)                     @ jump to next instruction
10715
10716    /*
10717     * Trivial test succeeded, save and bail.
10718     *  r9 holds A
10719     */
10720.LOP_INSTANCE_OF_trivial:
10721    mov     r0, #1                      @ indicate success
10722    @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper
10723    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10724    SET_VREG(r0, r9)                    @ vA<- r0
10725    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10726    GOTO_OPCODE(ip)                     @ jump to next instruction
10727
10728    /*
10729     * Resolution required.  This is the least-likely path.
10730     *
10731     *  r3 holds BBBB
10732     *  r9 holds A
10733     */
10734.LOP_INSTANCE_OF_resolve:
10735    EXPORT_PC()                         @ resolve() could throw
10736    ldr     r0, [rSELF, #offThread_method]    @ r0<- self->method
10737    mov     r1, r3                      @ r1<- BBBB
10738    mov     r2, #1                      @ r2<- true
10739    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10740    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10741    cmp     r0, #0                      @ got null?
10742    beq     common_exceptionThrown      @ yes, handle exception
10743    mov     r1, r0                      @ r1<- class resolved from BBB
10744    mov     r3, rINST, lsr #12          @ r3<- B
10745    GET_VREG(r0, r3)                    @ r0<- vB (object)
10746    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
10747    b       .LOP_INSTANCE_OF_resolved        @ pick up where we left off
10748
10749/* continuation for OP_NEW_INSTANCE */
10750
10751    .balign 32                          @ minimize cache lines
10752.LOP_NEW_INSTANCE_finish: @ r0=new object
10753    mov     r3, rINST, lsr #8           @ r3<- AA
10754    cmp     r0, #0                      @ failed?
10755    beq     common_exceptionThrown      @ yes, handle the exception
10756    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10757    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10758    SET_VREG(r0, r3)                    @ vAA<- r0
10759    GOTO_OPCODE(ip)                     @ jump to next instruction
10760
10761    /*
10762     * Class initialization required.
10763     *
10764     *  r0 holds class object
10765     */
10766.LOP_NEW_INSTANCE_needinit:
10767    mov     r9, r0                      @ save r0
10768    bl      dvmInitClass                @ initialize class
10769    cmp     r0, #0                      @ check boolean result
10770    mov     r0, r9                      @ restore r0
10771    bne     .LOP_NEW_INSTANCE_initialized     @ success, continue
10772    b       common_exceptionThrown      @ failed, deal with init exception
10773
10774    /*
10775     * Resolution required.  This is the least-likely path.
10776     *
10777     *  r1 holds BBBB
10778     */
10779.LOP_NEW_INSTANCE_resolve:
10780    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
10781    mov     r2, #0                      @ r2<- false
10782    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10783    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10784    cmp     r0, #0                      @ got null?
10785    bne     .LOP_NEW_INSTANCE_resolved        @ no, continue
10786    b       common_exceptionThrown      @ yes, handle exception
10787
10788.LstrInstantiationErrorPtr:
10789    .word   .LstrInstantiationError
10790
10791/* continuation for OP_NEW_ARRAY */
10792
10793
10794    /*
10795     * Resolve class.  (This is an uncommon case.)
10796     *
10797     *  r1 holds array length
10798     *  r2 holds class ref CCCC
10799     */
10800.LOP_NEW_ARRAY_resolve:
10801    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
10802    mov     r9, r1                      @ r9<- length (save)
10803    mov     r1, r2                      @ r1<- CCCC
10804    mov     r2, #0                      @ r2<- false
10805    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10806    bl      dvmResolveClass             @ r0<- call(clazz, ref)
10807    cmp     r0, #0                      @ got null?
10808    mov     r1, r9                      @ r1<- length (restore)
10809    beq     common_exceptionThrown      @ yes, handle exception
10810    @ fall through to OP_NEW_ARRAY_finish
10811
10812    /*
10813     * Finish allocation.
10814     *
10815     *  r0 holds class
10816     *  r1 holds array length
10817     */
10818.LOP_NEW_ARRAY_finish:
10819    mov     r2, #ALLOC_DONT_TRACK       @ don't track in local refs table
10820    bl      dvmAllocArrayByClass        @ r0<- call(clazz, length, flags)
10821    cmp     r0, #0                      @ failed?
10822    mov     r2, rINST, lsr #8           @ r2<- A+
10823    beq     common_exceptionThrown      @ yes, handle the exception
10824    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10825    and     r2, r2, #15                 @ r2<- A
10826    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10827    SET_VREG(r0, r2)                    @ vA<- r0
10828    GOTO_OPCODE(ip)                     @ jump to next instruction
10829
10830/* continuation for OP_FILLED_NEW_ARRAY */
10831
10832    /*
10833     * On entry:
10834     *  r0 holds array class
10835     *  r10 holds AA or BA
10836     */
10837.LOP_FILLED_NEW_ARRAY_continue:
10838    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
10839    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
10840    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
10841    .if     0
10842    mov     r1, r10                     @ r1<- AA (length)
10843    .else
10844    mov     r1, r10, lsr #4             @ r1<- B (length)
10845    .endif
10846    cmp     rINST, #'I'                 @ array of ints?
10847    cmpne   rINST, #'L'                 @ array of objects?
10848    cmpne   rINST, #'['                 @ array of arrays?
10849    mov     r9, r1                      @ save length in r9
10850    bne     .LOP_FILLED_NEW_ARRAY_notimpl         @ no, not handled yet
10851    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
10852    cmp     r0, #0                      @ null return?
10853    beq     common_exceptionThrown      @ alloc failed, handle exception
10854
10855    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
10856    str     r0, [rSELF, #offThread_retval]      @ retval.l <- new array
10857    str     rINST, [rSELF, #offThread_retval+4] @ retval.h <- type
10858    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
10859    subs    r9, r9, #1                  @ length--, check for neg
10860    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
10861    bmi     2f                          @ was zero, bail
10862
10863    @ copy values from registers into the array
10864    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
10865    .if     0
10866    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
108671:  ldr     r3, [r2], #4                @ r3<- *r2++
10868    subs    r9, r9, #1                  @ count--
10869    str     r3, [r0], #4                @ *contents++ = vX
10870    bpl     1b
10871    @ continue at 2
10872    .else
10873    cmp     r9, #4                      @ length was initially 5?
10874    and     r2, r10, #15                @ r2<- A
10875    bne     1f                          @ <= 4 args, branch
10876    GET_VREG(r3, r2)                    @ r3<- vA
10877    sub     r9, r9, #1                  @ count--
10878    str     r3, [r0, #16]               @ contents[4] = vA
108791:  and     r2, r1, #15                 @ r2<- F/E/D/C
10880    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
10881    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
10882    subs    r9, r9, #1                  @ count--
10883    str     r3, [r0], #4                @ *contents++ = vX
10884    bpl     1b
10885    @ continue at 2
10886    .endif
10887
108882:
10889    ldr     r0, [rSELF, #offThread_retval]     @ r0<- object
10890    ldr     r1, [rSELF, #offThread_retval+4]   @ r1<- type
10891    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
10892    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
10893    cmp     r1, #'I'                         @ Is int array?
10894    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
10895    GOTO_OPCODE(ip)                          @ execute it
10896
10897    /*
10898     * Throw an exception indicating that we have not implemented this
10899     * mode of filled-new-array.
10900     */
10901.LOP_FILLED_NEW_ARRAY_notimpl:
10902    ldr     r0, .L_strInternalError
10903    ldr     r1, .L_strFilledNewArrayNotImpl
10904    bl      dvmThrowException
10905    b       common_exceptionThrown
10906
10907    .if     (!0)                 @ define in one or the other, not both
10908.L_strFilledNewArrayNotImpl:
10909    .word   .LstrFilledNewArrayNotImpl
10910.L_strInternalError:
10911    .word   .LstrInternalError
10912    .endif
10913
10914/* continuation for OP_FILLED_NEW_ARRAY_RANGE */
10915
10916    /*
10917     * On entry:
10918     *  r0 holds array class
10919     *  r10 holds AA or BA
10920     */
10921.LOP_FILLED_NEW_ARRAY_RANGE_continue:
10922    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
10923    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
10924    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
10925    .if     1
10926    mov     r1, r10                     @ r1<- AA (length)
10927    .else
10928    mov     r1, r10, lsr #4             @ r1<- B (length)
10929    .endif
10930    cmp     rINST, #'I'                 @ array of ints?
10931    cmpne   rINST, #'L'                 @ array of objects?
10932    cmpne   rINST, #'['                 @ array of arrays?
10933    mov     r9, r1                      @ save length in r9
10934    bne     .LOP_FILLED_NEW_ARRAY_RANGE_notimpl         @ no, not handled yet
10935    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
10936    cmp     r0, #0                      @ null return?
10937    beq     common_exceptionThrown      @ alloc failed, handle exception
10938
10939    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
10940    str     r0, [rSELF, #offThread_retval]      @ retval.l <- new array
10941    str     rINST, [rSELF, #offThread_retval+4] @ retval.h <- type
10942    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
10943    subs    r9, r9, #1                  @ length--, check for neg
10944    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
10945    bmi     2f                          @ was zero, bail
10946
10947    @ copy values from registers into the array
10948    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
10949    .if     1
10950    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
109511:  ldr     r3, [r2], #4                @ r3<- *r2++
10952    subs    r9, r9, #1                  @ count--
10953    str     r3, [r0], #4                @ *contents++ = vX
10954    bpl     1b
10955    @ continue at 2
10956    .else
10957    cmp     r9, #4                      @ length was initially 5?
10958    and     r2, r10, #15                @ r2<- A
10959    bne     1f                          @ <= 4 args, branch
10960    GET_VREG(r3, r2)                    @ r3<- vA
10961    sub     r9, r9, #1                  @ count--
10962    str     r3, [r0, #16]               @ contents[4] = vA
109631:  and     r2, r1, #15                 @ r2<- F/E/D/C
10964    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
10965    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
10966    subs    r9, r9, #1                  @ count--
10967    str     r3, [r0], #4                @ *contents++ = vX
10968    bpl     1b
10969    @ continue at 2
10970    .endif
10971
109722:
10973    ldr     r0, [rSELF, #offThread_retval]     @ r0<- object
10974    ldr     r1, [rSELF, #offThread_retval+4]   @ r1<- type
10975    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
10976    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
10977    cmp     r1, #'I'                         @ Is int array?
10978    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
10979    GOTO_OPCODE(ip)                          @ execute it
10980
10981    /*
10982     * Throw an exception indicating that we have not implemented this
10983     * mode of filled-new-array.
10984     */
10985.LOP_FILLED_NEW_ARRAY_RANGE_notimpl:
10986    ldr     r0, .L_strInternalError
10987    ldr     r1, .L_strFilledNewArrayNotImpl
10988    bl      dvmThrowException
10989    b       common_exceptionThrown
10990
10991    .if     (!1)                 @ define in one or the other, not both
10992.L_strFilledNewArrayNotImpl:
10993    .word   .LstrFilledNewArrayNotImpl
10994.L_strInternalError:
10995    .word   .LstrInternalError
10996    .endif
10997
10998/* continuation for OP_CMPL_FLOAT */
10999.LOP_CMPL_FLOAT_finish:
11000    SET_VREG(r0, r9)                    @ vAA<- r0
11001    GOTO_OPCODE(ip)                     @ jump to next instruction
11002
11003/* continuation for OP_CMPG_FLOAT */
11004.LOP_CMPG_FLOAT_finish:
11005    SET_VREG(r0, r9)                    @ vAA<- r0
11006    GOTO_OPCODE(ip)                     @ jump to next instruction
11007
11008/* continuation for OP_CMPL_DOUBLE */
11009.LOP_CMPL_DOUBLE_finish:
11010    SET_VREG(r0, r9)                    @ vAA<- r0
11011    GOTO_OPCODE(ip)                     @ jump to next instruction
11012
11013/* continuation for OP_CMPG_DOUBLE */
11014.LOP_CMPG_DOUBLE_finish:
11015    SET_VREG(r0, r9)                    @ vAA<- r0
11016    GOTO_OPCODE(ip)                     @ jump to next instruction
11017
11018/* continuation for OP_CMP_LONG */
11019
11020.LOP_CMP_LONG_less:
11021    mvn     r1, #0                      @ r1<- -1
11022    @ Want to cond code the next mov so we can avoid branch, but don't see it;
11023    @ instead, we just replicate the tail end.
11024    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11025    SET_VREG(r1, r9)                    @ vAA<- r1
11026    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11027    GOTO_OPCODE(ip)                     @ jump to next instruction
11028
11029.LOP_CMP_LONG_greater:
11030    mov     r1, #1                      @ r1<- 1
11031    @ fall through to _finish
11032
11033.LOP_CMP_LONG_finish:
11034    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11035    SET_VREG(r1, r9)                    @ vAA<- r1
11036    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11037    GOTO_OPCODE(ip)                     @ jump to next instruction
11038
11039/* continuation for OP_AGET_WIDE */
11040
11041.LOP_AGET_WIDE_finish:
11042    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11043    ldrd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
11044    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
11045    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11046    stmia   r9, {r2-r3}                 @ vAA/vAA+1<- r2/r3
11047    GOTO_OPCODE(ip)                     @ jump to next instruction
11048
11049/* continuation for OP_APUT_WIDE */
11050
11051.LOP_APUT_WIDE_finish:
11052    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11053    ldmia   r9, {r2-r3}                 @ r2/r3<- vAA/vAA+1
11054    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11055    strd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
11056    GOTO_OPCODE(ip)                     @ jump to next instruction
11057
11058/* continuation for OP_APUT_OBJECT */
11059    /*
11060     * On entry:
11061     *  rINST = vBB (arrayObj)
11062     *  r9 = vAA (obj)
11063     *  r10 = offset into array (vBB + vCC * width)
11064     */
11065.LOP_APUT_OBJECT_finish:
11066    cmp     r9, #0                      @ storing null reference?
11067    beq     .LOP_APUT_OBJECT_skip_check      @ yes, skip type checks
11068    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
11069    ldr     r1, [rINST, #offObject_clazz]  @ r1<- arrayObj->clazz
11070    bl      dvmCanPutArrayElement       @ test object type vs. array type
11071    cmp     r0, #0                      @ okay?
11072    beq     .LOP_APUT_OBJECT_throw           @ no
11073    mov     r1, rINST                   @ r1<- arrayObj
11074    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11075    ldr     r2, [rSELF, #offThread_cardTable]     @ get biased CT base
11076    add     r10, #offArrayObject_contents   @ r0<- pointer to slot
11077    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11078    str     r9, [r10]                   @ vBB[vCC]<- vAA
11079    strb    r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head
11080    GOTO_OPCODE(ip)                     @ jump to next instruction
11081.LOP_APUT_OBJECT_skip_check:
11082    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11083    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11084    str     r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA
11085    GOTO_OPCODE(ip)                     @ jump to next instruction
11086.LOP_APUT_OBJECT_throw:
11087    @ The types don't match.  We need to throw an ArrayStoreException.
11088    ldr     r0, [r9, #offObject_clazz]
11089    ldr     r1, [rINST, #offObject_clazz]
11090    EXPORT_PC()
11091    bl      dvmThrowArrayStoreException
11092    b       common_exceptionThrown
11093
11094/* continuation for OP_IGET */
11095
11096    /*
11097     * Currently:
11098     *  r0 holds resolved field
11099     *  r9 holds object
11100     */
11101.LOP_IGET_finish:
11102    @bl      common_squeak0
11103    cmp     r9, #0                      @ check object for null
11104    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11105    beq     common_errNullObject        @ object was null
11106    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11107    @ no-op                             @ acquiring load
11108    mov     r2, rINST, lsr #8           @ r2<- A+
11109    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11110    and     r2, r2, #15                 @ r2<- A
11111    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11112    SET_VREG(r0, r2)                    @ fp[A]<- r0
11113    GOTO_OPCODE(ip)                     @ jump to next instruction
11114
11115/* continuation for OP_IGET_WIDE */
11116
11117    /*
11118     * Currently:
11119     *  r0 holds resolved field
11120     *  r9 holds object
11121     */
11122.LOP_IGET_WIDE_finish:
11123    cmp     r9, #0                      @ check object for null
11124    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11125    beq     common_errNullObject        @ object was null
11126    .if     0
11127    add     r0, r9, r3                  @ r0<- address of field
11128    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
11129    .else
11130    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
11131    .endif
11132    mov     r2, rINST, lsr #8           @ r2<- A+
11133    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11134    and     r2, r2, #15                 @ r2<- A
11135    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
11136    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11137    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
11138    GOTO_OPCODE(ip)                     @ jump to next instruction
11139
11140/* continuation for OP_IGET_OBJECT */
11141
11142    /*
11143     * Currently:
11144     *  r0 holds resolved field
11145     *  r9 holds object
11146     */
11147.LOP_IGET_OBJECT_finish:
11148    @bl      common_squeak0
11149    cmp     r9, #0                      @ check object for null
11150    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11151    beq     common_errNullObject        @ object was null
11152    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11153    @ no-op                             @ acquiring load
11154    mov     r2, rINST, lsr #8           @ r2<- A+
11155    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11156    and     r2, r2, #15                 @ r2<- A
11157    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11158    SET_VREG(r0, r2)                    @ fp[A]<- r0
11159    GOTO_OPCODE(ip)                     @ jump to next instruction
11160
11161/* continuation for OP_IGET_BOOLEAN */
11162
11163    /*
11164     * Currently:
11165     *  r0 holds resolved field
11166     *  r9 holds object
11167     */
11168.LOP_IGET_BOOLEAN_finish:
11169    @bl      common_squeak1
11170    cmp     r9, #0                      @ check object for null
11171    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11172    beq     common_errNullObject        @ object was null
11173    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11174    @ no-op                             @ acquiring load
11175    mov     r2, rINST, lsr #8           @ r2<- A+
11176    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11177    and     r2, r2, #15                 @ r2<- A
11178    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11179    SET_VREG(r0, r2)                    @ fp[A]<- r0
11180    GOTO_OPCODE(ip)                     @ jump to next instruction
11181
11182/* continuation for OP_IGET_BYTE */
11183
11184    /*
11185     * Currently:
11186     *  r0 holds resolved field
11187     *  r9 holds object
11188     */
11189.LOP_IGET_BYTE_finish:
11190    @bl      common_squeak2
11191    cmp     r9, #0                      @ check object for null
11192    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11193    beq     common_errNullObject        @ object was null
11194    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11195    @ no-op                             @ acquiring load
11196    mov     r2, rINST, lsr #8           @ r2<- A+
11197    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11198    and     r2, r2, #15                 @ r2<- A
11199    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11200    SET_VREG(r0, r2)                    @ fp[A]<- r0
11201    GOTO_OPCODE(ip)                     @ jump to next instruction
11202
11203/* continuation for OP_IGET_CHAR */
11204
11205    /*
11206     * Currently:
11207     *  r0 holds resolved field
11208     *  r9 holds object
11209     */
11210.LOP_IGET_CHAR_finish:
11211    @bl      common_squeak3
11212    cmp     r9, #0                      @ check object for null
11213    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11214    beq     common_errNullObject        @ object was null
11215    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11216    @ no-op                             @ acquiring load
11217    mov     r2, rINST, lsr #8           @ r2<- A+
11218    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11219    and     r2, r2, #15                 @ r2<- A
11220    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11221    SET_VREG(r0, r2)                    @ fp[A]<- r0
11222    GOTO_OPCODE(ip)                     @ jump to next instruction
11223
11224/* continuation for OP_IGET_SHORT */
11225
11226    /*
11227     * Currently:
11228     *  r0 holds resolved field
11229     *  r9 holds object
11230     */
11231.LOP_IGET_SHORT_finish:
11232    @bl      common_squeak4
11233    cmp     r9, #0                      @ check object for null
11234    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11235    beq     common_errNullObject        @ object was null
11236    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11237    @ no-op                             @ acquiring load
11238    mov     r2, rINST, lsr #8           @ r2<- A+
11239    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11240    and     r2, r2, #15                 @ r2<- A
11241    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11242    SET_VREG(r0, r2)                    @ fp[A]<- r0
11243    GOTO_OPCODE(ip)                     @ jump to next instruction
11244
11245/* continuation for OP_IPUT */
11246
11247    /*
11248     * Currently:
11249     *  r0 holds resolved field
11250     *  r9 holds object
11251     */
11252.LOP_IPUT_finish:
11253    @bl      common_squeak0
11254    mov     r1, rINST, lsr #8           @ r1<- A+
11255    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11256    and     r1, r1, #15                 @ r1<- A
11257    cmp     r9, #0                      @ check object for null
11258    GET_VREG(r0, r1)                    @ r0<- fp[A]
11259    beq     common_errNullObject        @ object was null
11260    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11261    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11262    @ no-op                             @ releasing store
11263    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11264    GOTO_OPCODE(ip)                     @ jump to next instruction
11265
11266/* continuation for OP_IPUT_WIDE */
11267
11268    /*
11269     * Currently:
11270     *  r0 holds resolved field
11271     *  r9 holds object
11272     */
11273.LOP_IPUT_WIDE_finish:
11274    mov     r2, rINST, lsr #8           @ r2<- A+
11275    cmp     r9, #0                      @ check object for null
11276    and     r2, r2, #15                 @ r2<- A
11277    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11278    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
11279    beq     common_errNullObject        @ object was null
11280    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11281    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
11282    GET_INST_OPCODE(r10)                @ extract opcode from rINST
11283    .if     0
11284    add     r2, r9, r3                  @ r2<- target address
11285    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
11286    .else
11287    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
11288    .endif
11289    GOTO_OPCODE(r10)                    @ jump to next instruction
11290
11291/* continuation for OP_IPUT_OBJECT */
11292
11293    /*
11294     * Currently:
11295     *  r0 holds resolved field
11296     *  r9 holds object
11297     */
11298.LOP_IPUT_OBJECT_finish:
11299    @bl      common_squeak0
11300    mov     r1, rINST, lsr #8           @ r1<- A+
11301    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11302    and     r1, r1, #15                 @ r1<- A
11303    cmp     r9, #0                      @ check object for null
11304    GET_VREG(r0, r1)                    @ r0<- fp[A]
11305    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
11306    beq     common_errNullObject        @ object was null
11307    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11308    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11309    @ no-op                             @ releasing store
11310    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
11311    cmp     r0, #0                      @ stored a null reference?
11312    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
11313    GOTO_OPCODE(ip)                     @ jump to next instruction
11314
11315/* continuation for OP_IPUT_BOOLEAN */
11316
11317    /*
11318     * Currently:
11319     *  r0 holds resolved field
11320     *  r9 holds object
11321     */
11322.LOP_IPUT_BOOLEAN_finish:
11323    @bl      common_squeak1
11324    mov     r1, rINST, lsr #8           @ r1<- A+
11325    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11326    and     r1, r1, #15                 @ r1<- A
11327    cmp     r9, #0                      @ check object for null
11328    GET_VREG(r0, r1)                    @ r0<- fp[A]
11329    beq     common_errNullObject        @ object was null
11330    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11331    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11332    @ no-op                             @ releasing store
11333    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11334    GOTO_OPCODE(ip)                     @ jump to next instruction
11335
11336/* continuation for OP_IPUT_BYTE */
11337
11338    /*
11339     * Currently:
11340     *  r0 holds resolved field
11341     *  r9 holds object
11342     */
11343.LOP_IPUT_BYTE_finish:
11344    @bl      common_squeak2
11345    mov     r1, rINST, lsr #8           @ r1<- A+
11346    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11347    and     r1, r1, #15                 @ r1<- A
11348    cmp     r9, #0                      @ check object for null
11349    GET_VREG(r0, r1)                    @ r0<- fp[A]
11350    beq     common_errNullObject        @ object was null
11351    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11352    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11353    @ no-op                             @ releasing store
11354    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11355    GOTO_OPCODE(ip)                     @ jump to next instruction
11356
11357/* continuation for OP_IPUT_CHAR */
11358
11359    /*
11360     * Currently:
11361     *  r0 holds resolved field
11362     *  r9 holds object
11363     */
11364.LOP_IPUT_CHAR_finish:
11365    @bl      common_squeak3
11366    mov     r1, rINST, lsr #8           @ r1<- A+
11367    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11368    and     r1, r1, #15                 @ r1<- A
11369    cmp     r9, #0                      @ check object for null
11370    GET_VREG(r0, r1)                    @ r0<- fp[A]
11371    beq     common_errNullObject        @ object was null
11372    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11373    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11374    @ no-op                             @ releasing store
11375    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11376    GOTO_OPCODE(ip)                     @ jump to next instruction
11377
11378/* continuation for OP_IPUT_SHORT */
11379
11380    /*
11381     * Currently:
11382     *  r0 holds resolved field
11383     *  r9 holds object
11384     */
11385.LOP_IPUT_SHORT_finish:
11386    @bl      common_squeak4
11387    mov     r1, rINST, lsr #8           @ r1<- A+
11388    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11389    and     r1, r1, #15                 @ r1<- A
11390    cmp     r9, #0                      @ check object for null
11391    GET_VREG(r0, r1)                    @ r0<- fp[A]
11392    beq     common_errNullObject        @ object was null
11393    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11394    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11395    @ no-op                             @ releasing store
11396    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11397    GOTO_OPCODE(ip)                     @ jump to next instruction
11398
11399/* continuation for OP_SGET */
11400
11401    /*
11402     * Continuation if the field has not yet been resolved.
11403     *  r1: BBBB field ref
11404     */
11405.LOP_SGET_resolve:
11406    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11407    EXPORT_PC()                         @ resolve() could throw, so export now
11408    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11409    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11410    cmp     r0, #0                      @ success?
11411    bne     .LOP_SGET_finish          @ yes, finish
11412    b       common_exceptionThrown      @ no, handle exception
11413
11414/* continuation for OP_SGET_WIDE */
11415
11416    /*
11417     * Continuation if the field has not yet been resolved.
11418     *  r1: BBBB field ref
11419     *
11420     * Returns StaticField pointer in r0.
11421     */
11422.LOP_SGET_WIDE_resolve:
11423    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11424    EXPORT_PC()                         @ resolve() could throw, so export now
11425    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11426    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11427    cmp     r0, #0                      @ success?
11428    bne     .LOP_SGET_WIDE_finish          @ yes, finish
11429    b       common_exceptionThrown      @ no, handle exception
11430
11431/* continuation for OP_SGET_OBJECT */
11432
11433    /*
11434     * Continuation if the field has not yet been resolved.
11435     *  r1: BBBB field ref
11436     */
11437.LOP_SGET_OBJECT_resolve:
11438    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11439    EXPORT_PC()                         @ resolve() could throw, so export now
11440    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11441    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11442    cmp     r0, #0                      @ success?
11443    bne     .LOP_SGET_OBJECT_finish          @ yes, finish
11444    b       common_exceptionThrown      @ no, handle exception
11445
11446/* continuation for OP_SGET_BOOLEAN */
11447
11448    /*
11449     * Continuation if the field has not yet been resolved.
11450     *  r1: BBBB field ref
11451     */
11452.LOP_SGET_BOOLEAN_resolve:
11453    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11454    EXPORT_PC()                         @ resolve() could throw, so export now
11455    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11456    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11457    cmp     r0, #0                      @ success?
11458    bne     .LOP_SGET_BOOLEAN_finish          @ yes, finish
11459    b       common_exceptionThrown      @ no, handle exception
11460
11461/* continuation for OP_SGET_BYTE */
11462
11463    /*
11464     * Continuation if the field has not yet been resolved.
11465     *  r1: BBBB field ref
11466     */
11467.LOP_SGET_BYTE_resolve:
11468    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11469    EXPORT_PC()                         @ resolve() could throw, so export now
11470    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11471    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11472    cmp     r0, #0                      @ success?
11473    bne     .LOP_SGET_BYTE_finish          @ yes, finish
11474    b       common_exceptionThrown      @ no, handle exception
11475
11476/* continuation for OP_SGET_CHAR */
11477
11478    /*
11479     * Continuation if the field has not yet been resolved.
11480     *  r1: BBBB field ref
11481     */
11482.LOP_SGET_CHAR_resolve:
11483    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11484    EXPORT_PC()                         @ resolve() could throw, so export now
11485    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11486    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11487    cmp     r0, #0                      @ success?
11488    bne     .LOP_SGET_CHAR_finish          @ yes, finish
11489    b       common_exceptionThrown      @ no, handle exception
11490
11491/* continuation for OP_SGET_SHORT */
11492
11493    /*
11494     * Continuation if the field has not yet been resolved.
11495     *  r1: BBBB field ref
11496     */
11497.LOP_SGET_SHORT_resolve:
11498    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11499    EXPORT_PC()                         @ resolve() could throw, so export now
11500    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11501    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11502    cmp     r0, #0                      @ success?
11503    bne     .LOP_SGET_SHORT_finish          @ yes, finish
11504    b       common_exceptionThrown      @ no, handle exception
11505
11506/* continuation for OP_SPUT */
11507
11508    /*
11509     * Continuation if the field has not yet been resolved.
11510     *  r1: BBBB field ref
11511     */
11512.LOP_SPUT_resolve:
11513    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11514    EXPORT_PC()                         @ resolve() could throw, so export now
11515    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11516    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11517    cmp     r0, #0                      @ success?
11518    bne     .LOP_SPUT_finish          @ yes, finish
11519    b       common_exceptionThrown      @ no, handle exception
11520
11521/* continuation for OP_SPUT_WIDE */
11522
11523    /*
11524     * Continuation if the field has not yet been resolved.
11525     *  r1: BBBB field ref
11526     *  r9: &fp[AA]
11527     *
11528     * Returns StaticField pointer in r2.
11529     */
11530.LOP_SPUT_WIDE_resolve:
11531    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11532    EXPORT_PC()                         @ resolve() could throw, so export now
11533    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11534    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11535    cmp     r0, #0                      @ success?
11536    mov     r2, r0                      @ copy to r2
11537    bne     .LOP_SPUT_WIDE_finish          @ yes, finish
11538    b       common_exceptionThrown      @ no, handle exception
11539
11540/* continuation for OP_SPUT_OBJECT */
11541.LOP_SPUT_OBJECT_finish:   @ field ptr in r0
11542    mov     r2, rINST, lsr #8           @ r2<- AA
11543    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11544    GET_VREG(r1, r2)                    @ r1<- fp[AA]
11545    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
11546    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
11547    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11548    @ no-op                             @ releasing store
11549    str     r1, [r0, #offStaticField_value]  @ field<- vAA
11550    cmp     r1, #0                      @ stored a null object?
11551    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
11552    GOTO_OPCODE(ip)                     @ jump to next instruction
11553
11554/* continuation for OP_SPUT_BOOLEAN */
11555
11556    /*
11557     * Continuation if the field has not yet been resolved.
11558     *  r1: BBBB field ref
11559     */
11560.LOP_SPUT_BOOLEAN_resolve:
11561    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11562    EXPORT_PC()                         @ resolve() could throw, so export now
11563    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11564    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11565    cmp     r0, #0                      @ success?
11566    bne     .LOP_SPUT_BOOLEAN_finish          @ yes, finish
11567    b       common_exceptionThrown      @ no, handle exception
11568
11569/* continuation for OP_SPUT_BYTE */
11570
11571    /*
11572     * Continuation if the field has not yet been resolved.
11573     *  r1: BBBB field ref
11574     */
11575.LOP_SPUT_BYTE_resolve:
11576    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11577    EXPORT_PC()                         @ resolve() could throw, so export now
11578    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11579    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11580    cmp     r0, #0                      @ success?
11581    bne     .LOP_SPUT_BYTE_finish          @ yes, finish
11582    b       common_exceptionThrown      @ no, handle exception
11583
11584/* continuation for OP_SPUT_CHAR */
11585
11586    /*
11587     * Continuation if the field has not yet been resolved.
11588     *  r1: BBBB field ref
11589     */
11590.LOP_SPUT_CHAR_resolve:
11591    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11592    EXPORT_PC()                         @ resolve() could throw, so export now
11593    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11594    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11595    cmp     r0, #0                      @ success?
11596    bne     .LOP_SPUT_CHAR_finish          @ yes, finish
11597    b       common_exceptionThrown      @ no, handle exception
11598
11599/* continuation for OP_SPUT_SHORT */
11600
11601    /*
11602     * Continuation if the field has not yet been resolved.
11603     *  r1: BBBB field ref
11604     */
11605.LOP_SPUT_SHORT_resolve:
11606    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11607    EXPORT_PC()                         @ resolve() could throw, so export now
11608    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11609    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11610    cmp     r0, #0                      @ success?
11611    bne     .LOP_SPUT_SHORT_finish          @ yes, finish
11612    b       common_exceptionThrown      @ no, handle exception
11613
11614/* continuation for OP_INVOKE_VIRTUAL */
11615
11616    /*
11617     * At this point:
11618     *  r0 = resolved base method
11619     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
11620     */
11621.LOP_INVOKE_VIRTUAL_continue:
11622    GET_VREG(r1, r10)                   @ r1<- "this" ptr
11623    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11624    cmp     r1, #0                      @ is "this" null?
11625    beq     common_errNullObject        @ null "this", throw exception
11626    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
11627    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
11628    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
11629    bl      common_invokeMethodNoRange @ continue on
11630
11631/* continuation for OP_INVOKE_SUPER */
11632
11633    /*
11634     * At this point:
11635     *  r0 = resolved base method
11636     *  r9 = method->clazz
11637     */
11638.LOP_INVOKE_SUPER_continue:
11639    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
11640    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11641    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
11642    EXPORT_PC()                         @ must export for invoke
11643    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
11644    bcs     .LOP_INVOKE_SUPER_nsm             @ method not present in superclass
11645    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
11646    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
11647    bl      common_invokeMethodNoRange @ continue on
11648
11649.LOP_INVOKE_SUPER_resolve:
11650    mov     r0, r9                      @ r0<- method->clazz
11651    mov     r2, #METHOD_VIRTUAL         @ resolver method type
11652    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11653    cmp     r0, #0                      @ got null?
11654    bne     .LOP_INVOKE_SUPER_continue        @ no, continue
11655    b       common_exceptionThrown      @ yes, handle exception
11656
11657    /*
11658     * Throw a NoSuchMethodError with the method name as the message.
11659     *  r0 = resolved base method
11660     */
11661.LOP_INVOKE_SUPER_nsm:
11662    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
11663    b       common_errNoSuchMethod
11664
11665/* continuation for OP_INVOKE_DIRECT */
11666
11667    /*
11668     * On entry:
11669     *  r1 = reference (BBBB or CCCC)
11670     *  r10 = "this" register
11671     */
11672.LOP_INVOKE_DIRECT_resolve:
11673    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
11674    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
11675    mov     r2, #METHOD_DIRECT          @ resolver method type
11676    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11677    cmp     r0, #0                      @ got null?
11678    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
11679    bne     .LOP_INVOKE_DIRECT_finish          @ no, continue
11680    b       common_exceptionThrown      @ yes, handle exception
11681
11682/* continuation for OP_INVOKE_VIRTUAL_RANGE */
11683
11684    /*
11685     * At this point:
11686     *  r0 = resolved base method
11687     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
11688     */
11689.LOP_INVOKE_VIRTUAL_RANGE_continue:
11690    GET_VREG(r1, r10)                   @ r1<- "this" ptr
11691    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11692    cmp     r1, #0                      @ is "this" null?
11693    beq     common_errNullObject        @ null "this", throw exception
11694    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
11695    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
11696    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
11697    bl      common_invokeMethodRange @ continue on
11698
11699/* continuation for OP_INVOKE_SUPER_RANGE */
11700
11701    /*
11702     * At this point:
11703     *  r0 = resolved base method
11704     *  r9 = method->clazz
11705     */
11706.LOP_INVOKE_SUPER_RANGE_continue:
11707    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
11708    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11709    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
11710    EXPORT_PC()                         @ must export for invoke
11711    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
11712    bcs     .LOP_INVOKE_SUPER_RANGE_nsm             @ method not present in superclass
11713    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
11714    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
11715    bl      common_invokeMethodRange @ continue on
11716
11717.LOP_INVOKE_SUPER_RANGE_resolve:
11718    mov     r0, r9                      @ r0<- method->clazz
11719    mov     r2, #METHOD_VIRTUAL         @ resolver method type
11720    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11721    cmp     r0, #0                      @ got null?
11722    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ no, continue
11723    b       common_exceptionThrown      @ yes, handle exception
11724
11725    /*
11726     * Throw a NoSuchMethodError with the method name as the message.
11727     *  r0 = resolved base method
11728     */
11729.LOP_INVOKE_SUPER_RANGE_nsm:
11730    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
11731    b       common_errNoSuchMethod
11732
11733/* continuation for OP_INVOKE_DIRECT_RANGE */
11734
11735    /*
11736     * On entry:
11737     *  r1 = reference (BBBB or CCCC)
11738     *  r10 = "this" register
11739     */
11740.LOP_INVOKE_DIRECT_RANGE_resolve:
11741    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
11742    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
11743    mov     r2, #METHOD_DIRECT          @ resolver method type
11744    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11745    cmp     r0, #0                      @ got null?
11746    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
11747    bne     .LOP_INVOKE_DIRECT_RANGE_finish          @ no, continue
11748    b       common_exceptionThrown      @ yes, handle exception
11749
11750/* continuation for OP_FLOAT_TO_LONG */
11751/*
11752 * Convert the float in r0 to a long in r0/r1.
11753 *
11754 * We have to clip values to long min/max per the specification.  The
11755 * expected common case is a "reasonable" value that converts directly
11756 * to modest integer.  The EABI convert function isn't doing this for us.
11757 */
11758f2l_doconv:
11759    stmfd   sp!, {r4, lr}
11760    mov     r1, #0x5f000000             @ (float)maxlong
11761    mov     r4, r0
11762    bl      __aeabi_fcmpge              @ is arg >= maxlong?
11763    cmp     r0, #0                      @ nonzero == yes
11764    mvnne   r0, #0                      @ return maxlong (7fffffff)
11765    mvnne   r1, #0x80000000
11766    ldmnefd sp!, {r4, pc}
11767
11768    mov     r0, r4                      @ recover arg
11769    mov     r1, #0xdf000000             @ (float)minlong
11770    bl      __aeabi_fcmple              @ is arg <= minlong?
11771    cmp     r0, #0                      @ nonzero == yes
11772    movne   r0, #0                      @ return minlong (80000000)
11773    movne   r1, #0x80000000
11774    ldmnefd sp!, {r4, pc}
11775
11776    mov     r0, r4                      @ recover arg
11777    mov     r1, r4
11778    bl      __aeabi_fcmpeq              @ is arg == self?
11779    cmp     r0, #0                      @ zero == no
11780    moveq   r1, #0                      @ return zero for NaN
11781    ldmeqfd sp!, {r4, pc}
11782
11783    mov     r0, r4                      @ recover arg
11784    bl      __aeabi_f2lz                @ convert float to long
11785    ldmfd   sp!, {r4, pc}
11786
11787/* continuation for OP_DOUBLE_TO_LONG */
11788/*
11789 * Convert the double in r0/r1 to a long in r0/r1.
11790 *
11791 * We have to clip values to long min/max per the specification.  The
11792 * expected common case is a "reasonable" value that converts directly
11793 * to modest integer.  The EABI convert function isn't doing this for us.
11794 */
11795d2l_doconv:
11796    stmfd   sp!, {r4, r5, lr}           @ save regs
11797    mov     r3, #0x43000000             @ maxlong, as a double (high word)
11798    add     r3, #0x00e00000             @  0x43e00000
11799    mov     r2, #0                      @ maxlong, as a double (low word)
11800    sub     sp, sp, #4                  @ align for EABI
11801    mov     r4, r0                      @ save a copy of r0
11802    mov     r5, r1                      @  and r1
11803    bl      __aeabi_dcmpge              @ is arg >= maxlong?
11804    cmp     r0, #0                      @ nonzero == yes
11805    mvnne   r0, #0                      @ return maxlong (7fffffffffffffff)
11806    mvnne   r1, #0x80000000
11807    bne     1f
11808
11809    mov     r0, r4                      @ recover arg
11810    mov     r1, r5
11811    mov     r3, #0xc3000000             @ minlong, as a double (high word)
11812    add     r3, #0x00e00000             @  0xc3e00000
11813    mov     r2, #0                      @ minlong, as a double (low word)
11814    bl      __aeabi_dcmple              @ is arg <= minlong?
11815    cmp     r0, #0                      @ nonzero == yes
11816    movne   r0, #0                      @ return minlong (8000000000000000)
11817    movne   r1, #0x80000000
11818    bne     1f
11819
11820    mov     r0, r4                      @ recover arg
11821    mov     r1, r5
11822    mov     r2, r4                      @ compare against self
11823    mov     r3, r5
11824    bl      __aeabi_dcmpeq              @ is arg == self?
11825    cmp     r0, #0                      @ zero == no
11826    moveq   r1, #0                      @ return zero for NaN
11827    beq     1f
11828
11829    mov     r0, r4                      @ recover arg
11830    mov     r1, r5
11831    bl      __aeabi_d2lz                @ convert double to long
11832
118331:
11834    add     sp, sp, #4
11835    ldmfd   sp!, {r4, r5, pc}
11836
11837/* continuation for OP_MUL_LONG */
11838
11839.LOP_MUL_LONG_finish:
11840    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11841    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
11842    GOTO_OPCODE(ip)                     @ jump to next instruction
11843
11844/* continuation for OP_SHL_LONG */
11845
11846.LOP_SHL_LONG_finish:
11847    mov     r0, r0, asl r2              @  r0<- r0 << r2
11848    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11849    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11850    GOTO_OPCODE(ip)                     @ jump to next instruction
11851
11852/* continuation for OP_SHR_LONG */
11853
11854.LOP_SHR_LONG_finish:
11855    mov     r1, r1, asr r2              @  r1<- r1 >> r2
11856    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11857    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11858    GOTO_OPCODE(ip)                     @ jump to next instruction
11859
11860/* continuation for OP_USHR_LONG */
11861
11862.LOP_USHR_LONG_finish:
11863    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
11864    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11865    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11866    GOTO_OPCODE(ip)                     @ jump to next instruction
11867
11868/* continuation for OP_SHL_LONG_2ADDR */
11869
11870.LOP_SHL_LONG_2ADDR_finish:
11871    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11872    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11873    GOTO_OPCODE(ip)                     @ jump to next instruction
11874
11875/* continuation for OP_SHR_LONG_2ADDR */
11876
11877.LOP_SHR_LONG_2ADDR_finish:
11878    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11879    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11880    GOTO_OPCODE(ip)                     @ jump to next instruction
11881
11882/* continuation for OP_USHR_LONG_2ADDR */
11883
11884.LOP_USHR_LONG_2ADDR_finish:
11885    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11886    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11887    GOTO_OPCODE(ip)                     @ jump to next instruction
11888
11889/* continuation for OP_IGET_VOLATILE */
11890
11891    /*
11892     * Currently:
11893     *  r0 holds resolved field
11894     *  r9 holds object
11895     */
11896.LOP_IGET_VOLATILE_finish:
11897    @bl      common_squeak0
11898    cmp     r9, #0                      @ check object for null
11899    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11900    beq     common_errNullObject        @ object was null
11901    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11902    SMP_DMB                            @ acquiring load
11903    mov     r2, rINST, lsr #8           @ r2<- A+
11904    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11905    and     r2, r2, #15                 @ r2<- A
11906    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11907    SET_VREG(r0, r2)                    @ fp[A]<- r0
11908    GOTO_OPCODE(ip)                     @ jump to next instruction
11909
11910/* continuation for OP_IPUT_VOLATILE */
11911
11912    /*
11913     * Currently:
11914     *  r0 holds resolved field
11915     *  r9 holds object
11916     */
11917.LOP_IPUT_VOLATILE_finish:
11918    @bl      common_squeak0
11919    mov     r1, rINST, lsr #8           @ r1<- A+
11920    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11921    and     r1, r1, #15                 @ r1<- A
11922    cmp     r9, #0                      @ check object for null
11923    GET_VREG(r0, r1)                    @ r0<- fp[A]
11924    beq     common_errNullObject        @ object was null
11925    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11926    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11927    SMP_DMB                            @ releasing store
11928    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11929    GOTO_OPCODE(ip)                     @ jump to next instruction
11930
11931/* continuation for OP_SGET_VOLATILE */
11932
11933    /*
11934     * Continuation if the field has not yet been resolved.
11935     *  r1: BBBB field ref
11936     */
11937.LOP_SGET_VOLATILE_resolve:
11938    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11939    EXPORT_PC()                         @ resolve() could throw, so export now
11940    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11941    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11942    cmp     r0, #0                      @ success?
11943    bne     .LOP_SGET_VOLATILE_finish          @ yes, finish
11944    b       common_exceptionThrown      @ no, handle exception
11945
11946/* continuation for OP_SPUT_VOLATILE */
11947
11948    /*
11949     * Continuation if the field has not yet been resolved.
11950     *  r1: BBBB field ref
11951     */
11952.LOP_SPUT_VOLATILE_resolve:
11953    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11954    EXPORT_PC()                         @ resolve() could throw, so export now
11955    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11956    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11957    cmp     r0, #0                      @ success?
11958    bne     .LOP_SPUT_VOLATILE_finish          @ yes, finish
11959    b       common_exceptionThrown      @ no, handle exception
11960
11961/* continuation for OP_IGET_OBJECT_VOLATILE */
11962
11963    /*
11964     * Currently:
11965     *  r0 holds resolved field
11966     *  r9 holds object
11967     */
11968.LOP_IGET_OBJECT_VOLATILE_finish:
11969    @bl      common_squeak0
11970    cmp     r9, #0                      @ check object for null
11971    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11972    beq     common_errNullObject        @ object was null
11973    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11974    SMP_DMB                            @ acquiring load
11975    mov     r2, rINST, lsr #8           @ r2<- A+
11976    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11977    and     r2, r2, #15                 @ r2<- A
11978    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11979    SET_VREG(r0, r2)                    @ fp[A]<- r0
11980    GOTO_OPCODE(ip)                     @ jump to next instruction
11981
11982/* continuation for OP_IGET_WIDE_VOLATILE */
11983
11984    /*
11985     * Currently:
11986     *  r0 holds resolved field
11987     *  r9 holds object
11988     */
11989.LOP_IGET_WIDE_VOLATILE_finish:
11990    cmp     r9, #0                      @ check object for null
11991    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11992    beq     common_errNullObject        @ object was null
11993    .if     1
11994    add     r0, r9, r3                  @ r0<- address of field
11995    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
11996    .else
11997    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
11998    .endif
11999    mov     r2, rINST, lsr #8           @ r2<- A+
12000    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12001    and     r2, r2, #15                 @ r2<- A
12002    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
12003    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12004    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
12005    GOTO_OPCODE(ip)                     @ jump to next instruction
12006
12007/* continuation for OP_IPUT_WIDE_VOLATILE */
12008
12009    /*
12010     * Currently:
12011     *  r0 holds resolved field
12012     *  r9 holds object
12013     */
12014.LOP_IPUT_WIDE_VOLATILE_finish:
12015    mov     r2, rINST, lsr #8           @ r2<- A+
12016    cmp     r9, #0                      @ check object for null
12017    and     r2, r2, #15                 @ r2<- A
12018    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12019    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
12020    beq     common_errNullObject        @ object was null
12021    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12022    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
12023    GET_INST_OPCODE(r10)                @ extract opcode from rINST
12024    .if     1
12025    add     r2, r9, r3                  @ r2<- target address
12026    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
12027    .else
12028    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
12029    .endif
12030    GOTO_OPCODE(r10)                    @ jump to next instruction
12031
12032/* continuation for OP_SGET_WIDE_VOLATILE */
12033
12034    /*
12035     * Continuation if the field has not yet been resolved.
12036     *  r1: BBBB field ref
12037     *
12038     * Returns StaticField pointer in r0.
12039     */
12040.LOP_SGET_WIDE_VOLATILE_resolve:
12041    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12042    EXPORT_PC()                         @ resolve() could throw, so export now
12043    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12044    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12045    cmp     r0, #0                      @ success?
12046    bne     .LOP_SGET_WIDE_VOLATILE_finish          @ yes, finish
12047    b       common_exceptionThrown      @ no, handle exception
12048
12049/* continuation for OP_SPUT_WIDE_VOLATILE */
12050
12051    /*
12052     * Continuation if the field has not yet been resolved.
12053     *  r1: BBBB field ref
12054     *  r9: &fp[AA]
12055     *
12056     * Returns StaticField pointer in r2.
12057     */
12058.LOP_SPUT_WIDE_VOLATILE_resolve:
12059    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12060    EXPORT_PC()                         @ resolve() could throw, so export now
12061    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12062    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12063    cmp     r0, #0                      @ success?
12064    mov     r2, r0                      @ copy to r2
12065    bne     .LOP_SPUT_WIDE_VOLATILE_finish          @ yes, finish
12066    b       common_exceptionThrown      @ no, handle exception
12067
12068/* continuation for OP_EXECUTE_INLINE */
12069
12070    /*
12071     * Extract args, call function.
12072     *  r0 = #of args (0-4)
12073     *  r10 = call index
12074     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
12075     *
12076     * Other ideas:
12077     * - Use a jump table from the main piece to jump directly into the
12078     *   AND/LDR pairs.  Costs a data load, saves a branch.
12079     * - Have five separate pieces that do the loading, so we can work the
12080     *   interleave a little better.  Increases code size.
12081     */
12082.LOP_EXECUTE_INLINE_continue:
12083    rsb     r0, r0, #4                  @ r0<- 4-r0
12084    FETCH(r9, 2)                        @ r9<- FEDC
12085    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
12086    bl      common_abort                @ (skipped due to ARM prefetch)
120874:  and     ip, r9, #0xf000             @ isolate F
12088    ldr     r3, [rFP, ip, lsr #10]      @ r3<- vF (shift right 12, left 2)
120893:  and     ip, r9, #0x0f00             @ isolate E
12090    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vE
120912:  and     ip, r9, #0x00f0             @ isolate D
12092    ldr     r1, [rFP, ip, lsr #2]       @ r1<- vD
120931:  and     ip, r9, #0x000f             @ isolate C
12094    ldr     r0, [rFP, ip, lsl #2]       @ r0<- vC
120950:
12096    ldr     r9, .LOP_EXECUTE_INLINE_table       @ table of InlineOperation
12097    ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
12098    @ (not reached)
12099
12100.LOP_EXECUTE_INLINE_table:
12101    .word   gDvmInlineOpsTable
12102
12103/* continuation for OP_EXECUTE_INLINE_RANGE */
12104
12105    /*
12106     * Extract args, call function.
12107     *  r0 = #of args (0-4)
12108     *  r10 = call index
12109     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
12110     */
12111.LOP_EXECUTE_INLINE_RANGE_continue:
12112    rsb     r0, r0, #4                  @ r0<- 4-r0
12113    FETCH(r9, 2)                        @ r9<- CCCC
12114    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
12115    bl      common_abort                @ (skipped due to ARM prefetch)
121164:  add     ip, r9, #3                  @ base+3
12117    GET_VREG(r3, ip)                    @ r3<- vBase[3]
121183:  add     ip, r9, #2                  @ base+2
12119    GET_VREG(r2, ip)                    @ r2<- vBase[2]
121202:  add     ip, r9, #1                  @ base+1
12121    GET_VREG(r1, ip)                    @ r1<- vBase[1]
121221:  add     ip, r9, #0                  @ (nop)
12123    GET_VREG(r0, ip)                    @ r0<- vBase[0]
121240:
12125    ldr     r9, .LOP_EXECUTE_INLINE_RANGE_table       @ table of InlineOperation
12126    ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
12127    @ (not reached)
12128
12129.LOP_EXECUTE_INLINE_RANGE_table:
12130    .word   gDvmInlineOpsTable
12131
12132/* continuation for OP_IPUT_OBJECT_VOLATILE */
12133
12134    /*
12135     * Currently:
12136     *  r0 holds resolved field
12137     *  r9 holds object
12138     */
12139.LOP_IPUT_OBJECT_VOLATILE_finish:
12140    @bl      common_squeak0
12141    mov     r1, rINST, lsr #8           @ r1<- A+
12142    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12143    and     r1, r1, #15                 @ r1<- A
12144    cmp     r9, #0                      @ check object for null
12145    GET_VREG(r0, r1)                    @ r0<- fp[A]
12146    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
12147    beq     common_errNullObject        @ object was null
12148    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12149    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12150    SMP_DMB                            @ releasing store
12151    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
12152    cmp     r0, #0                      @ stored a null reference?
12153    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
12154    GOTO_OPCODE(ip)                     @ jump to next instruction
12155
12156/* continuation for OP_SGET_OBJECT_VOLATILE */
12157
12158    /*
12159     * Continuation if the field has not yet been resolved.
12160     *  r1: BBBB field ref
12161     */
12162.LOP_SGET_OBJECT_VOLATILE_resolve:
12163    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12164    EXPORT_PC()                         @ resolve() could throw, so export now
12165    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12166    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12167    cmp     r0, #0                      @ success?
12168    bne     .LOP_SGET_OBJECT_VOLATILE_finish          @ yes, finish
12169    b       common_exceptionThrown      @ no, handle exception
12170
12171/* continuation for OP_SPUT_OBJECT_VOLATILE */
12172.LOP_SPUT_OBJECT_VOLATILE_finish:   @ field ptr in r0
12173    mov     r2, rINST, lsr #8           @ r2<- AA
12174    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12175    GET_VREG(r1, r2)                    @ r1<- fp[AA]
12176    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
12177    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
12178    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12179    SMP_DMB                            @ releasing store
12180    str     r1, [r0, #offStaticField_value]  @ field<- vAA
12181    cmp     r1, #0                      @ stored a null object?
12182    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
12183    GOTO_OPCODE(ip)                     @ jump to next instruction
12184
12185/* continuation for OP_CONST_CLASS_JUMBO */
12186
12187    /*
12188     * Continuation if the Class has not yet been resolved.
12189     *  r1: AAAAAAAA (Class ref)
12190     *  r9: target register
12191     */
12192.LOP_CONST_CLASS_JUMBO_resolve:
12193    EXPORT_PC()
12194    ldr     r0, [rSELF, #offThread_method] @ r0<- self->method
12195    mov     r2, #1                      @ r2<- true
12196    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
12197    bl      dvmResolveClass             @ r0<- Class reference
12198    cmp     r0, #0                      @ failed?
12199    beq     common_exceptionThrown      @ yup, handle the exception
12200    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12201    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12202    SET_VREG(r0, r9)                    @ vBBBB<- r0
12203    GOTO_OPCODE(ip)                     @ jump to next instruction
12204
12205/* continuation for OP_CHECK_CAST_JUMBO */
12206
12207    /*
12208     * Trivial test failed, need to perform full check.  This is common.
12209     *  r0 holds obj->clazz
12210     *  r1 holds desired class resolved from AAAAAAAA
12211     *  r9 holds object
12212     */
12213.LOP_CHECK_CAST_JUMBO_fullcheck:
12214    mov     r10, r1                     @ avoid ClassObject getting clobbered
12215    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
12216    cmp     r0, #0                      @ failed?
12217    bne     .LOP_CHECK_CAST_JUMBO_okay            @ no, success
12218
12219    @ A cast has failed.  We need to throw a ClassCastException.
12220    EXPORT_PC()                         @ about to throw
12221    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
12222    mov     r1, r10                     @ r1<- desired class
12223    bl      dvmThrowClassCastException
12224    b       common_exceptionThrown
12225
12226    /*
12227     * Advance PC and get the next opcode.
12228     */
12229.LOP_CHECK_CAST_JUMBO_okay:
12230    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12231    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12232    GOTO_OPCODE(ip)                     @ jump to next instruction
12233
12234    /*
12235     * Resolution required.  This is the least-likely path.
12236     *
12237     *  r2 holds AAAAAAAA
12238     *  r9 holds object
12239     */
12240.LOP_CHECK_CAST_JUMBO_resolve:
12241    EXPORT_PC()                         @ resolve() could throw
12242    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
12243    mov     r1, r2                      @ r1<- AAAAAAAA
12244    mov     r2, #0                      @ r2<- false
12245    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12246    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12247    cmp     r0, #0                      @ got null?
12248    beq     common_exceptionThrown      @ yes, handle exception
12249    mov     r1, r0                      @ r1<- class resolved from AAAAAAAA
12250    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
12251    b       .LOP_CHECK_CAST_JUMBO_resolved        @ pick up where we left off
12252
12253/* continuation for OP_INSTANCE_OF_JUMBO */
12254
12255    /*
12256     * Class resolved, determine type of check necessary.  This is common.
12257     *  r0 holds obj->clazz
12258     *  r1 holds class resolved from AAAAAAAA
12259     *  r9 holds BBBB
12260     */
12261.LOP_INSTANCE_OF_JUMBO_resolved:
12262    cmp     r0, r1                      @ same class (trivial success)?
12263    beq     .LOP_INSTANCE_OF_JUMBO_trivial         @ yes, trivial finish
12264    @ fall through to OP_INSTANCE_OF_JUMBO_fullcheck
12265
12266    /*
12267     * Trivial test failed, need to perform full check.  This is common.
12268     *  r0 holds obj->clazz
12269     *  r1 holds class resolved from AAAAAAAA
12270     *  r9 holds BBBB
12271     */
12272.LOP_INSTANCE_OF_JUMBO_fullcheck:
12273    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
12274    @ fall through to OP_INSTANCE_OF_JUMBO_store
12275
12276    /*
12277     * r0 holds boolean result
12278     * r9 holds BBBB
12279     */
12280.LOP_INSTANCE_OF_JUMBO_store:
12281    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12282    SET_VREG(r0, r9)                    @ vBBBB<- r0
12283    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12284    GOTO_OPCODE(ip)                     @ jump to next instruction
12285
12286    /*
12287     * Trivial test succeeded, save and bail.
12288     *  r9 holds BBBB
12289     */
12290.LOP_INSTANCE_OF_JUMBO_trivial:
12291    mov     r0, #1                      @ indicate success
12292    @ could b OP_INSTANCE_OF_JUMBO_store, but copying is faster and cheaper
12293    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12294    SET_VREG(r0, r9)                    @ vBBBB<- r0
12295    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12296    GOTO_OPCODE(ip)                     @ jump to next instruction
12297
12298    /*
12299     * Resolution required.  This is the least-likely path.
12300     *
12301     *  r3 holds AAAAAAAA
12302     *  r9 holds BBBB
12303     */
12304
12305.LOP_INSTANCE_OF_JUMBO_resolve:
12306    EXPORT_PC()                         @ resolve() could throw
12307    ldr     r0, [rSELF, #offThread_method]    @ r0<- self->method
12308    mov     r1, r3                      @ r1<- AAAAAAAA
12309    mov     r2, #1                      @ r2<- true
12310    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
12311    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12312    cmp     r0, #0                      @ got null?
12313    beq     common_exceptionThrown      @ yes, handle exception
12314    FETCH(r3, 4)                        @ r3<- vCCCC
12315    mov     r1, r0                      @ r1<- class resolved from AAAAAAAA
12316    GET_VREG(r0, r3)                    @ r0<- vCCCC (object)
12317    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
12318    b       .LOP_INSTANCE_OF_JUMBO_resolved        @ pick up where we left off
12319
12320/* continuation for OP_NEW_INSTANCE_JUMBO */
12321
12322    .balign 32                          @ minimize cache lines
12323.LOP_NEW_INSTANCE_JUMBO_finish: @ r0=new object
12324    FETCH(r3, 3)                        @ r3<- BBBB
12325    cmp     r0, #0                      @ failed?
12326    beq     common_exceptionThrown      @ yes, handle the exception
12327    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12328    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12329    SET_VREG(r0, r3)                    @ vBBBB<- r0
12330    GOTO_OPCODE(ip)                     @ jump to next instruction
12331
12332    /*
12333     * Class initialization required.
12334     *
12335     *  r0 holds class object
12336     */
12337.LOP_NEW_INSTANCE_JUMBO_needinit:
12338    mov     r9, r0                      @ save r0
12339    bl      dvmInitClass                @ initialize class
12340    cmp     r0, #0                      @ check boolean result
12341    mov     r0, r9                      @ restore r0
12342    bne     .LOP_NEW_INSTANCE_JUMBO_initialized     @ success, continue
12343    b       common_exceptionThrown      @ failed, deal with init exception
12344
12345    /*
12346     * Resolution required.  This is the least-likely path.
12347     *
12348     *  r1 holds AAAAAAAA
12349     */
12350.LOP_NEW_INSTANCE_JUMBO_resolve:
12351    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
12352    mov     r2, #0                      @ r2<- false
12353    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12354    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12355    cmp     r0, #0                      @ got null?
12356    bne     .LOP_NEW_INSTANCE_JUMBO_resolved        @ no, continue
12357    b       common_exceptionThrown      @ yes, handle exception
12358
12359/* continuation for OP_NEW_ARRAY_JUMBO */
12360
12361
12362    /*
12363     * Resolve class.  (This is an uncommon case.)
12364     *
12365     *  r1 holds array length
12366     *  r2 holds class ref AAAAAAAA
12367     */
12368.LOP_NEW_ARRAY_JUMBO_resolve:
12369    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
12370    mov     r9, r1                      @ r9<- length (save)
12371    mov     r1, r2                      @ r1<- AAAAAAAA
12372    mov     r2, #0                      @ r2<- false
12373    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12374    bl      dvmResolveClass             @ r0<- call(clazz, ref)
12375    cmp     r0, #0                      @ got null?
12376    mov     r1, r9                      @ r1<- length (restore)
12377    beq     common_exceptionThrown      @ yes, handle exception
12378    @ fall through to OP_NEW_ARRAY_JUMBO_finish
12379
12380    /*
12381     * Finish allocation.
12382     *
12383     *  r0 holds class
12384     *  r1 holds array length
12385     */
12386.LOP_NEW_ARRAY_JUMBO_finish:
12387    mov     r2, #ALLOC_DONT_TRACK       @ don't track in local refs table
12388    bl      dvmAllocArrayByClass        @ r0<- call(clazz, length, flags)
12389    cmp     r0, #0                      @ failed?
12390    FETCH(r2, 3)                        @ r2<- vBBBB
12391    beq     common_exceptionThrown      @ yes, handle the exception
12392    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12393    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12394    SET_VREG(r0, r2)                    @ vBBBB<- r0
12395    GOTO_OPCODE(ip)                     @ jump to next instruction
12396
12397/* continuation for OP_FILLED_NEW_ARRAY_JUMBO */
12398
12399    /*
12400     * On entry:
12401     *  r0 holds array class
12402     */
12403.LOP_FILLED_NEW_ARRAY_JUMBO_continue:
12404    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
12405    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
12406    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
12407    FETCH(r1, 3)                        @ r1<- BBBB (length)
12408    cmp     rINST, #'I'                 @ array of ints?
12409    cmpne   rINST, #'L'                 @ array of objects?
12410    cmpne   rINST, #'['                 @ array of arrays?
12411    mov     r9, r1                      @ save length in r9
12412    bne     .LOP_FILLED_NEW_ARRAY_JUMBO_notimpl         @ no, not handled yet
12413    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
12414    cmp     r0, #0                      @ null return?
12415    beq     common_exceptionThrown      @ alloc failed, handle exception
12416
12417    FETCH(r1, 4)                        @ r1<- CCCC
12418    str     r0, [rSELF, #offThread_retval]      @ retval.l <- new array
12419    str     rINST, [rSELF, #offThread_retval+4] @ retval.h <- type
12420    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
12421    subs    r9, r9, #1                  @ length--, check for neg
12422    FETCH_ADVANCE_INST(5)               @ advance to next instr, load rINST
12423    bmi     2f                          @ was zero, bail
12424
12425    @ copy values from registers into the array
12426    @ r0=array, r1=CCCC, r9=BBBB (length)
12427    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
124281:  ldr     r3, [r2], #4                @ r3<- *r2++
12429    subs    r9, r9, #1                  @ count--
12430    str     r3, [r0], #4                @ *contents++ = vX
12431    bpl     1b
12432
124332:  ldr     r0, [rSELF, #offThread_retval]     @ r0<- object
12434    ldr     r1, [rSELF, #offThread_retval+4]   @ r1<- type
12435    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
12436    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
12437    cmp     r1, #'I'                         @ Is int array?
12438    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
12439    GOTO_OPCODE(ip)                          @ execute it
12440
12441    /*
12442     * Throw an exception indicating that we have not implemented this
12443     * mode of filled-new-array.
12444     */
12445.LOP_FILLED_NEW_ARRAY_JUMBO_notimpl:
12446    ldr     r0, .L_strInternalError
12447    ldr     r1, .L_strFilledNewArrayNotImpl
12448    bl      dvmThrowException
12449    b       common_exceptionThrown
12450
12451/* continuation for OP_IGET_JUMBO */
12452
12453    /*
12454     * Currently:
12455     *  r0 holds resolved field
12456     *  r9 holds object
12457     */
12458.LOP_IGET_JUMBO_resolved:
12459    cmp     r0, #0                      @ resolution unsuccessful?
12460    beq     common_exceptionThrown      @ yes, throw exception
12461    @ fall through to OP_IGET_JUMBO_finish
12462
12463    /*
12464     * Currently:
12465     *  r0 holds resolved field
12466     *  r9 holds object
12467     */
12468.LOP_IGET_JUMBO_finish:
12469    @bl      common_squeak0
12470    cmp     r9, #0                      @ check object for null
12471    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12472    beq     common_errNullObject        @ object was null
12473    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12474    @ no-op                             @ acquiring load
12475    FETCH(r2, 3)                        @ r2<- BBBB
12476    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12477    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12478    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12479    GOTO_OPCODE(ip)                     @ jump to next instruction
12480
12481/* continuation for OP_IGET_WIDE_JUMBO */
12482
12483    /*
12484     * Currently:
12485     *  r0 holds resolved field
12486     *  r9 holds object
12487     */
12488.LOP_IGET_WIDE_JUMBO_resolved:
12489    cmp     r0, #0                      @ resolution unsuccessful?
12490    beq     common_exceptionThrown      @ yes, throw exception
12491    @ fall through to OP_IGET_WIDE_JUMBO_finish
12492
12493    /*
12494     * Currently:
12495     *  r0 holds resolved field
12496     *  r9 holds object
12497     */
12498.LOP_IGET_WIDE_JUMBO_finish:
12499    cmp     r9, #0                      @ check object for null
12500    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12501    beq     common_errNullObject        @ object was null
12502    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
12503    FETCH(r2, 3)                        @ r2<- BBBB
12504    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12505    add     r3, rFP, r2, lsl #2         @ r3<- &fp[BBBB]
12506    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12507    stmia   r3, {r0-r1}                 @ fp[BBBB]<- r0/r1
12508    GOTO_OPCODE(ip)                     @ jump to next instruction
12509
12510/* continuation for OP_IGET_OBJECT_JUMBO */
12511
12512    /*
12513     * Currently:
12514     *  r0 holds resolved field
12515     *  r9 holds object
12516     */
12517.LOP_IGET_OBJECT_JUMBO_resolved:
12518    cmp     r0, #0                      @ resolution unsuccessful?
12519    beq     common_exceptionThrown      @ yes, throw exception
12520    @ fall through to OP_IGET_OBJECT_JUMBO_finish
12521
12522    /*
12523     * Currently:
12524     *  r0 holds resolved field
12525     *  r9 holds object
12526     */
12527.LOP_IGET_OBJECT_JUMBO_finish:
12528    @bl      common_squeak0
12529    cmp     r9, #0                      @ check object for null
12530    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12531    beq     common_errNullObject        @ object was null
12532    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12533    @ no-op                             @ acquiring load
12534    FETCH(r2, 3)                        @ r2<- BBBB
12535    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12536    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12537    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12538    GOTO_OPCODE(ip)                     @ jump to next instruction
12539
12540/* continuation for OP_IGET_BOOLEAN_JUMBO */
12541
12542    /*
12543     * Currently:
12544     *  r0 holds resolved field
12545     *  r9 holds object
12546     */
12547.LOP_IGET_BOOLEAN_JUMBO_resolved:
12548    cmp     r0, #0                      @ resolution unsuccessful?
12549    beq     common_exceptionThrown      @ yes, throw exception
12550    @ fall through to OP_IGET_BOOLEAN_JUMBO_finish
12551
12552    /*
12553     * Currently:
12554     *  r0 holds resolved field
12555     *  r9 holds object
12556     */
12557.LOP_IGET_BOOLEAN_JUMBO_finish:
12558    @bl      common_squeak1
12559    cmp     r9, #0                      @ check object for null
12560    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12561    beq     common_errNullObject        @ object was null
12562    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12563    @ no-op                             @ acquiring load
12564    FETCH(r2, 3)                        @ r2<- BBBB
12565    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12566    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12567    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12568    GOTO_OPCODE(ip)                     @ jump to next instruction
12569
12570/* continuation for OP_IGET_BYTE_JUMBO */
12571
12572    /*
12573     * Currently:
12574     *  r0 holds resolved field
12575     *  r9 holds object
12576     */
12577.LOP_IGET_BYTE_JUMBO_resolved:
12578    cmp     r0, #0                      @ resolution unsuccessful?
12579    beq     common_exceptionThrown      @ yes, throw exception
12580    @ fall through to OP_IGET_BYTE_JUMBO_finish
12581
12582    /*
12583     * Currently:
12584     *  r0 holds resolved field
12585     *  r9 holds object
12586     */
12587.LOP_IGET_BYTE_JUMBO_finish:
12588    @bl      common_squeak2
12589    cmp     r9, #0                      @ check object for null
12590    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12591    beq     common_errNullObject        @ object was null
12592    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12593    @ no-op                             @ acquiring load
12594    FETCH(r2, 3)                        @ r2<- BBBB
12595    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12596    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12597    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12598    GOTO_OPCODE(ip)                     @ jump to next instruction
12599
12600/* continuation for OP_IGET_CHAR_JUMBO */
12601
12602    /*
12603     * Currently:
12604     *  r0 holds resolved field
12605     *  r9 holds object
12606     */
12607.LOP_IGET_CHAR_JUMBO_resolved:
12608    cmp     r0, #0                      @ resolution unsuccessful?
12609    beq     common_exceptionThrown      @ yes, throw exception
12610    @ fall through to OP_IGET_CHAR_JUMBO_finish
12611
12612    /*
12613     * Currently:
12614     *  r0 holds resolved field
12615     *  r9 holds object
12616     */
12617.LOP_IGET_CHAR_JUMBO_finish:
12618    @bl      common_squeak3
12619    cmp     r9, #0                      @ check object for null
12620    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12621    beq     common_errNullObject        @ object was null
12622    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12623    @ no-op                             @ acquiring load
12624    FETCH(r2, 3)                        @ r2<- BBBB
12625    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12626    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12627    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12628    GOTO_OPCODE(ip)                     @ jump to next instruction
12629
12630/* continuation for OP_IGET_SHORT_JUMBO */
12631
12632    /*
12633     * Currently:
12634     *  r0 holds resolved field
12635     *  r9 holds object
12636     */
12637.LOP_IGET_SHORT_JUMBO_resolved:
12638    cmp     r0, #0                      @ resolution unsuccessful?
12639    beq     common_exceptionThrown      @ yes, throw exception
12640    @ fall through to OP_IGET_SHORT_JUMBO_finish
12641
12642    /*
12643     * Currently:
12644     *  r0 holds resolved field
12645     *  r9 holds object
12646     */
12647.LOP_IGET_SHORT_JUMBO_finish:
12648    @bl      common_squeak4
12649    cmp     r9, #0                      @ check object for null
12650    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12651    beq     common_errNullObject        @ object was null
12652    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12653    @ no-op                             @ acquiring load
12654    FETCH(r2, 3)                        @ r2<- BBBB
12655    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12656    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12657    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12658    GOTO_OPCODE(ip)                     @ jump to next instruction
12659
12660/* continuation for OP_IPUT_JUMBO */
12661
12662    /*
12663     * Currently:
12664     *  r0 holds resolved field
12665     *  r9 holds object
12666     */
12667.LOP_IPUT_JUMBO_resolved:
12668     cmp     r0, #0                     @ resolution unsuccessful?
12669     beq     common_exceptionThrown     @ yes, throw exception
12670     @ fall through to OP_IPUT_JUMBO_finish
12671
12672    /*
12673     * Currently:
12674     *  r0 holds resolved field
12675     *  r9 holds object
12676     */
12677.LOP_IPUT_JUMBO_finish:
12678    @bl      common_squeak0
12679    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12680    FETCH(r1, 3)                        @ r1<- BBBB
12681    cmp     r9, #0                      @ check object for null
12682    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12683    beq     common_errNullObject        @ object was null
12684    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12685    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12686    @ no-op                             @ releasing store
12687    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12688    GOTO_OPCODE(ip)                     @ jump to next instruction
12689
12690/* continuation for OP_IPUT_WIDE_JUMBO */
12691
12692    /*
12693     * Currently:
12694     *  r0 holds resolved field
12695     *  r9 holds object
12696     */
12697.LOP_IPUT_WIDE_JUMBO_resolved:
12698     cmp     r0, #0                     @ resolution unsuccessful?
12699     beq     common_exceptionThrown     @ yes, throw exception
12700     @ fall through to OP_IPUT_WIDE_JUMBO_finish
12701
12702    /*
12703     * Currently:
12704     *  r0 holds resolved field
12705     *  r9 holds object
12706     */
12707.LOP_IPUT_WIDE_JUMBO_finish:
12708    cmp     r9, #0                      @ check object for null
12709    FETCH(r2, 3)                        @ r1<- BBBB
12710    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12711    add     r2, rFP, r2, lsl #2         @ r3<- &fp[BBBB]
12712    beq     common_errNullObject        @ object was null
12713    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12714    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[BBBB]
12715    GET_INST_OPCODE(r10)                @ extract opcode from rINST
12716    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
12717    GOTO_OPCODE(r10)                    @ jump to next instruction
12718
12719/* continuation for OP_IPUT_OBJECT_JUMBO */
12720
12721    /*
12722     * Currently:
12723     *  r0 holds resolved field
12724     *  r9 holds object
12725     */
12726.LOP_IPUT_OBJECT_JUMBO_resolved:
12727     cmp     r0, #0                     @ resolution unsuccessful?
12728     beq     common_exceptionThrown     @ yes, throw exception
12729     @ fall through to OP_IPUT_OBJECT_JUMBO_finish
12730
12731    /*
12732     * Currently:
12733     *  r0 holds resolved field
12734     *  r9 holds object
12735     */
12736.LOP_IPUT_OBJECT_JUMBO_finish:
12737    @bl      common_squeak0
12738    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12739    FETCH(r1, 3)                        @ r1<- BBBB
12740    cmp     r9, #0                      @ check object for null
12741    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12742    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
12743    beq     common_errNullObject        @ object was null
12744    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12745    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12746    @ no-op                             @ releasing store
12747    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
12748    cmp     r0, #0                      @ stored a null reference?
12749    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
12750    GOTO_OPCODE(ip)                     @ jump to next instruction
12751
12752/* continuation for OP_IPUT_BOOLEAN_JUMBO */
12753
12754    /*
12755     * Currently:
12756     *  r0 holds resolved field
12757     *  r9 holds object
12758     */
12759.LOP_IPUT_BOOLEAN_JUMBO_resolved:
12760     cmp     r0, #0                     @ resolution unsuccessful?
12761     beq     common_exceptionThrown     @ yes, throw exception
12762     @ fall through to OP_IPUT_BOOLEAN_JUMBO_finish
12763
12764    /*
12765     * Currently:
12766     *  r0 holds resolved field
12767     *  r9 holds object
12768     */
12769.LOP_IPUT_BOOLEAN_JUMBO_finish:
12770    @bl      common_squeak1
12771    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12772    FETCH(r1, 3)                        @ r1<- BBBB
12773    cmp     r9, #0                      @ check object for null
12774    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12775    beq     common_errNullObject        @ object was null
12776    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12777    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12778    @ no-op                             @ releasing store
12779    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12780    GOTO_OPCODE(ip)                     @ jump to next instruction
12781
12782/* continuation for OP_IPUT_BYTE_JUMBO */
12783
12784    /*
12785     * Currently:
12786     *  r0 holds resolved field
12787     *  r9 holds object
12788     */
12789.LOP_IPUT_BYTE_JUMBO_resolved:
12790     cmp     r0, #0                     @ resolution unsuccessful?
12791     beq     common_exceptionThrown     @ yes, throw exception
12792     @ fall through to OP_IPUT_BYTE_JUMBO_finish
12793
12794    /*
12795     * Currently:
12796     *  r0 holds resolved field
12797     *  r9 holds object
12798     */
12799.LOP_IPUT_BYTE_JUMBO_finish:
12800    @bl      common_squeak2
12801    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12802    FETCH(r1, 3)                        @ r1<- BBBB
12803    cmp     r9, #0                      @ check object for null
12804    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12805    beq     common_errNullObject        @ object was null
12806    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12807    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12808    @ no-op                             @ releasing store
12809    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12810    GOTO_OPCODE(ip)                     @ jump to next instruction
12811
12812/* continuation for OP_IPUT_CHAR_JUMBO */
12813
12814    /*
12815     * Currently:
12816     *  r0 holds resolved field
12817     *  r9 holds object
12818     */
12819.LOP_IPUT_CHAR_JUMBO_resolved:
12820     cmp     r0, #0                     @ resolution unsuccessful?
12821     beq     common_exceptionThrown     @ yes, throw exception
12822     @ fall through to OP_IPUT_CHAR_JUMBO_finish
12823
12824    /*
12825     * Currently:
12826     *  r0 holds resolved field
12827     *  r9 holds object
12828     */
12829.LOP_IPUT_CHAR_JUMBO_finish:
12830    @bl      common_squeak3
12831    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12832    FETCH(r1, 3)                        @ r1<- BBBB
12833    cmp     r9, #0                      @ check object for null
12834    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12835    beq     common_errNullObject        @ object was null
12836    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12837    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12838    @ no-op                             @ releasing store
12839    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12840    GOTO_OPCODE(ip)                     @ jump to next instruction
12841
12842/* continuation for OP_IPUT_SHORT_JUMBO */
12843
12844    /*
12845     * Currently:
12846     *  r0 holds resolved field
12847     *  r9 holds object
12848     */
12849.LOP_IPUT_SHORT_JUMBO_resolved:
12850     cmp     r0, #0                     @ resolution unsuccessful?
12851     beq     common_exceptionThrown     @ yes, throw exception
12852     @ fall through to OP_IPUT_SHORT_JUMBO_finish
12853
12854    /*
12855     * Currently:
12856     *  r0 holds resolved field
12857     *  r9 holds object
12858     */
12859.LOP_IPUT_SHORT_JUMBO_finish:
12860    @bl      common_squeak4
12861    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12862    FETCH(r1, 3)                        @ r1<- BBBB
12863    cmp     r9, #0                      @ check object for null
12864    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12865    beq     common_errNullObject        @ object was null
12866    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12867    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12868    @ no-op                             @ releasing store
12869    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12870    GOTO_OPCODE(ip)                     @ jump to next instruction
12871
12872/* continuation for OP_SGET_JUMBO */
12873
12874    /*
12875     * Continuation if the field has not yet been resolved.
12876     *  r1: AAAAAAAA field ref
12877     */
12878.LOP_SGET_JUMBO_resolve:
12879    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12880    EXPORT_PC()                         @ resolve() could throw, so export now
12881    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12882    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12883    cmp     r0, #0                      @ success?
12884    bne     .LOP_SGET_JUMBO_finish          @ yes, finish
12885    b       common_exceptionThrown      @ no, handle exception
12886
12887/* continuation for OP_SGET_WIDE_JUMBO */
12888
12889    /*
12890     * Continuation if the field has not yet been resolved.
12891     *  r1: BBBB field ref
12892     *
12893     * Returns StaticField pointer in r0.
12894     */
12895.LOP_SGET_WIDE_JUMBO_resolve:
12896    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12897    EXPORT_PC()                         @ resolve() could throw, so export now
12898    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12899    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12900    cmp     r0, #0                      @ success?
12901    bne     .LOP_SGET_WIDE_JUMBO_finish          @ yes, finish
12902    b       common_exceptionThrown      @ no, handle exception
12903
12904/* continuation for OP_SGET_OBJECT_JUMBO */
12905
12906    /*
12907     * Continuation if the field has not yet been resolved.
12908     *  r1: AAAAAAAA field ref
12909     */
12910.LOP_SGET_OBJECT_JUMBO_resolve:
12911    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12912    EXPORT_PC()                         @ resolve() could throw, so export now
12913    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12914    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12915    cmp     r0, #0                      @ success?
12916    bne     .LOP_SGET_OBJECT_JUMBO_finish          @ yes, finish
12917    b       common_exceptionThrown      @ no, handle exception
12918
12919/* continuation for OP_SGET_BOOLEAN_JUMBO */
12920
12921    /*
12922     * Continuation if the field has not yet been resolved.
12923     *  r1: AAAAAAAA field ref
12924     */
12925.LOP_SGET_BOOLEAN_JUMBO_resolve:
12926    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12927    EXPORT_PC()                         @ resolve() could throw, so export now
12928    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12929    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12930    cmp     r0, #0                      @ success?
12931    bne     .LOP_SGET_BOOLEAN_JUMBO_finish          @ yes, finish
12932    b       common_exceptionThrown      @ no, handle exception
12933
12934/* continuation for OP_SGET_BYTE_JUMBO */
12935
12936    /*
12937     * Continuation if the field has not yet been resolved.
12938     *  r1: AAAAAAAA field ref
12939     */
12940.LOP_SGET_BYTE_JUMBO_resolve:
12941    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12942    EXPORT_PC()                         @ resolve() could throw, so export now
12943    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12944    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12945    cmp     r0, #0                      @ success?
12946    bne     .LOP_SGET_BYTE_JUMBO_finish          @ yes, finish
12947    b       common_exceptionThrown      @ no, handle exception
12948
12949/* continuation for OP_SGET_CHAR_JUMBO */
12950
12951    /*
12952     * Continuation if the field has not yet been resolved.
12953     *  r1: AAAAAAAA field ref
12954     */
12955.LOP_SGET_CHAR_JUMBO_resolve:
12956    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12957    EXPORT_PC()                         @ resolve() could throw, so export now
12958    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12959    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12960    cmp     r0, #0                      @ success?
12961    bne     .LOP_SGET_CHAR_JUMBO_finish          @ yes, finish
12962    b       common_exceptionThrown      @ no, handle exception
12963
12964/* continuation for OP_SGET_SHORT_JUMBO */
12965
12966    /*
12967     * Continuation if the field has not yet been resolved.
12968     *  r1: AAAAAAAA field ref
12969     */
12970.LOP_SGET_SHORT_JUMBO_resolve:
12971    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12972    EXPORT_PC()                         @ resolve() could throw, so export now
12973    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12974    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12975    cmp     r0, #0                      @ success?
12976    bne     .LOP_SGET_SHORT_JUMBO_finish          @ yes, finish
12977    b       common_exceptionThrown      @ no, handle exception
12978
12979/* continuation for OP_SPUT_JUMBO */
12980
12981    /*
12982     * Continuation if the field has not yet been resolved.
12983     *  r1: AAAAAAAA field ref
12984     */
12985.LOP_SPUT_JUMBO_resolve:
12986    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12987    EXPORT_PC()                         @ resolve() could throw, so export now
12988    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12989    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12990    cmp     r0, #0                      @ success?
12991    bne     .LOP_SPUT_JUMBO_finish          @ yes, finish
12992    b       common_exceptionThrown      @ no, handle exception
12993
12994/* continuation for OP_SPUT_WIDE_JUMBO */
12995
12996    /*
12997     * Continuation if the field has not yet been resolved.
12998     *  r1: BBBB field ref
12999     *  r9: &fp[AA]
13000     *
13001     * Returns StaticField pointer in r2.
13002     */
13003.LOP_SPUT_WIDE_JUMBO_resolve:
13004    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
13005    EXPORT_PC()                         @ resolve() could throw, so export now
13006    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13007    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13008    cmp     r0, #0                      @ success?
13009    mov     r2, r0                      @ copy to r2
13010    bne     .LOP_SPUT_WIDE_JUMBO_finish          @ yes, finish
13011    b       common_exceptionThrown      @ no, handle exception
13012
13013/* continuation for OP_SPUT_OBJECT_JUMBO */
13014
13015.LOP_SPUT_OBJECT_JUMBO_finish:   @ field ptr in r0
13016    FETCH(r2, 3)                        @ r2<- BBBB
13017    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
13018    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
13019    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
13020    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
13021    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13022    @ no-op                             @ releasing store
13023    str     r1, [r0, #offStaticField_value]  @ field<- vBBBB
13024    cmp     r1, #0                      @ stored a null object?
13025    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
13026    GOTO_OPCODE(ip)                     @ jump to next instruction
13027
13028/* continuation for OP_SPUT_BOOLEAN_JUMBO */
13029
13030    /*
13031     * Continuation if the field has not yet been resolved.
13032     *  r1: AAAAAAAA field ref
13033     */
13034.LOP_SPUT_BOOLEAN_JUMBO_resolve:
13035    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
13036    EXPORT_PC()                         @ resolve() could throw, so export now
13037    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13038    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13039    cmp     r0, #0                      @ success?
13040    bne     .LOP_SPUT_BOOLEAN_JUMBO_finish          @ yes, finish
13041    b       common_exceptionThrown      @ no, handle exception
13042
13043/* continuation for OP_SPUT_BYTE_JUMBO */
13044
13045    /*
13046     * Continuation if the field has not yet been resolved.
13047     *  r1: AAAAAAAA field ref
13048     */
13049.LOP_SPUT_BYTE_JUMBO_resolve:
13050    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
13051    EXPORT_PC()                         @ resolve() could throw, so export now
13052    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13053    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13054    cmp     r0, #0                      @ success?
13055    bne     .LOP_SPUT_BYTE_JUMBO_finish          @ yes, finish
13056    b       common_exceptionThrown      @ no, handle exception
13057
13058/* continuation for OP_SPUT_CHAR_JUMBO */
13059
13060    /*
13061     * Continuation if the field has not yet been resolved.
13062     *  r1: AAAAAAAA field ref
13063     */
13064.LOP_SPUT_CHAR_JUMBO_resolve:
13065    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
13066    EXPORT_PC()                         @ resolve() could throw, so export now
13067    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13068    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13069    cmp     r0, #0                      @ success?
13070    bne     .LOP_SPUT_CHAR_JUMBO_finish          @ yes, finish
13071    b       common_exceptionThrown      @ no, handle exception
13072
13073/* continuation for OP_SPUT_SHORT_JUMBO */
13074
13075    /*
13076     * Continuation if the field has not yet been resolved.
13077     *  r1: AAAAAAAA field ref
13078     */
13079.LOP_SPUT_SHORT_JUMBO_resolve:
13080    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
13081    EXPORT_PC()                         @ resolve() could throw, so export now
13082    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13083    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13084    cmp     r0, #0                      @ success?
13085    bne     .LOP_SPUT_SHORT_JUMBO_finish          @ yes, finish
13086    b       common_exceptionThrown      @ no, handle exception
13087
13088/* continuation for OP_INVOKE_VIRTUAL_JUMBO */
13089
13090    /*
13091     * At this point:
13092     *  r0 = resolved base method
13093     */
13094.LOP_INVOKE_VIRTUAL_JUMBO_continue:
13095    FETCH(r10, 4)                       @ r10<- CCCC
13096    GET_VREG(r1, r10)                   @ r1<- "this" ptr
13097    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
13098    cmp     r1, #0                      @ is "this" null?
13099    beq     common_errNullObject        @ null "this", throw exception
13100    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
13101    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
13102    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
13103    bl      common_invokeMethodJumbo    @ continue on
13104
13105/* continuation for OP_INVOKE_SUPER_JUMBO */
13106
13107    /*
13108     * At this point:
13109     *  r0 = resolved base method
13110     *  r9 = method->clazz
13111     */
13112.LOP_INVOKE_SUPER_JUMBO_continue:
13113    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
13114    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
13115    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
13116    EXPORT_PC()                         @ must export for invoke
13117    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
13118    bcs     .LOP_INVOKE_SUPER_JUMBO_nsm             @ method not present in superclass
13119    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
13120    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
13121    bl      common_invokeMethodJumbo    @ continue on
13122
13123.LOP_INVOKE_SUPER_JUMBO_resolve:
13124    mov     r0, r9                      @ r0<- method->clazz
13125    mov     r2, #METHOD_VIRTUAL         @ resolver method type
13126    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
13127    cmp     r0, #0                      @ got null?
13128    bne     .LOP_INVOKE_SUPER_JUMBO_continue        @ no, continue
13129    b       common_exceptionThrown      @ yes, handle exception
13130
13131    /*
13132     * Throw a NoSuchMethodError with the method name as the message.
13133     *  r0 = resolved base method
13134     */
13135.LOP_INVOKE_SUPER_JUMBO_nsm:
13136    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
13137    b       common_errNoSuchMethod
13138
13139/* continuation for OP_INVOKE_DIRECT_JUMBO */
13140
13141    /*
13142     * On entry:
13143     *  r1 = reference (CCCC)
13144     *  r10 = "this" register
13145     */
13146.LOP_INVOKE_DIRECT_JUMBO_resolve:
13147    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
13148    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
13149    mov     r2, #METHOD_DIRECT          @ resolver method type
13150    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
13151    cmp     r0, #0                      @ got null?
13152    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
13153    bne     .LOP_INVOKE_DIRECT_JUMBO_finish          @ no, continue
13154    b       common_exceptionThrown      @ yes, handle exception
13155
13156    .size   dvmAsmSisterStart, .-dvmAsmSisterStart
13157    .global dvmAsmSisterEnd
13158dvmAsmSisterEnd:
13159
13160/* File: armv5te/footer.S */
13161
13162/*
13163 * ===========================================================================
13164 *  Common subroutines and data
13165 * ===========================================================================
13166 */
13167
13168
13169
13170    .text
13171    .align  2
13172
13173#if defined(WITH_JIT)
13174#if defined(WITH_SELF_VERIFICATION)
13175    .global dvmJitToInterpPunt
13176dvmJitToInterpPunt:
13177    mov    r2,#kSVSPunt                 @ r2<- interpreter entry point
13178    mov    r3, #0
13179    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
13180    b      jitSVShadowRunEnd            @ doesn't return
13181
13182    .global dvmJitToInterpSingleStep
13183dvmJitToInterpSingleStep:
13184    str    lr,[rSELF,#offThread_jitResumeNPC]
13185    str    r1,[rSELF,#offThread_jitResumeDPC]
13186    mov    r2,#kSVSSingleStep           @ r2<- interpreter entry point
13187    b      jitSVShadowRunEnd            @ doesn't return
13188
13189    .global dvmJitToInterpNoChainNoProfile
13190dvmJitToInterpNoChainNoProfile:
13191    mov    r0,rPC                       @ pass our target PC
13192    mov    r2,#kSVSNoProfile            @ r2<- interpreter entry point
13193    mov    r3, #0                       @ 0 means !inJitCodeCache
13194    str    r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land
13195    b      jitSVShadowRunEnd            @ doesn't return
13196
13197    .global dvmJitToInterpTraceSelectNoChain
13198dvmJitToInterpTraceSelectNoChain:
13199    mov    r0,rPC                       @ pass our target PC
13200    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
13201    mov    r3, #0                       @ 0 means !inJitCodeCache
13202    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
13203    b      jitSVShadowRunEnd            @ doesn't return
13204
13205    .global dvmJitToInterpTraceSelect
13206dvmJitToInterpTraceSelect:
13207    ldr    r0,[lr, #-1]                 @ pass our target PC
13208    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
13209    mov    r3, #0                       @ 0 means !inJitCodeCache
13210    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
13211    b      jitSVShadowRunEnd            @ doesn't return
13212
13213    .global dvmJitToInterpBackwardBranch
13214dvmJitToInterpBackwardBranch:
13215    ldr    r0,[lr, #-1]                 @ pass our target PC
13216    mov    r2,#kSVSBackwardBranch       @ r2<- interpreter entry point
13217    mov    r3, #0                       @ 0 means !inJitCodeCache
13218    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
13219    b      jitSVShadowRunEnd            @ doesn't return
13220
13221    .global dvmJitToInterpNormal
13222dvmJitToInterpNormal:
13223    ldr    r0,[lr, #-1]                 @ pass our target PC
13224    mov    r2,#kSVSNormal               @ r2<- interpreter entry point
13225    mov    r3, #0                       @ 0 means !inJitCodeCache
13226    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
13227    b      jitSVShadowRunEnd            @ doesn't return
13228
13229    .global dvmJitToInterpNoChain
13230dvmJitToInterpNoChain:
13231    mov    r0,rPC                       @ pass our target PC
13232    mov    r2,#kSVSNoChain              @ r2<- interpreter entry point
13233    mov    r3, #0                       @ 0 means !inJitCodeCache
13234    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
13235    b      jitSVShadowRunEnd            @ doesn't return
13236#else
13237/*
13238 * Return from the translation cache to the interpreter when the compiler is
13239 * having issues translating/executing a Dalvik instruction. We have to skip
13240 * the code cache lookup otherwise it is possible to indefinitely bouce
13241 * between the interpreter and the code cache if the instruction that fails
13242 * to be compiled happens to be at a trace start.
13243 */
13244    .global dvmJitToInterpPunt
13245dvmJitToInterpPunt:
13246    mov    rPC, r0
13247#if defined(WITH_JIT_TUNING)
13248    mov    r0,lr
13249    bl     dvmBumpPunt;
13250#endif
13251    EXPORT_PC()
13252    mov    r0, #0
13253    str    r0, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
13254    adrl   rIBASE, dvmAsmInstructionStart
13255    FETCH_INST()
13256    GET_INST_OPCODE(ip)
13257    GOTO_OPCODE(ip)
13258
13259/*
13260 * Return to the interpreter to handle a single instruction.
13261 * On entry:
13262 *    r0 <= PC
13263 *    r1 <= PC of resume instruction
13264 *    lr <= resume point in translation
13265 */
13266    .global dvmJitToInterpSingleStep
13267dvmJitToInterpSingleStep:
13268    str    lr,[rSELF,#offThread_jitResumeNPC]
13269    str    r1,[rSELF,#offThread_jitResumeDPC]
13270    mov    r1,#kInterpEntryInstr
13271    @ enum is 4 byte in aapcs-EABI
13272    str    r1, [rSELF, #offThread_entryPoint]
13273    mov    rPC,r0
13274    EXPORT_PC()
13275
13276    adrl   rIBASE, dvmAsmInstructionStart
13277    mov    r2,#kJitSingleStep     @ Ask for single step and then revert
13278    str    r2,[rSELF,#offThread_jitState]
13279    mov    r1,#1                  @ set changeInterp to bail to debug interp
13280    b      common_gotoBail
13281
13282/*
13283 * Return from the translation cache and immediately request
13284 * a translation for the exit target.  Commonly used for callees.
13285 */
13286    .global dvmJitToInterpTraceSelectNoChain
13287dvmJitToInterpTraceSelectNoChain:
13288#if defined(WITH_JIT_TUNING)
13289    bl     dvmBumpNoChain
13290#endif
13291    mov    r0,rPC
13292    bl     dvmJitGetTraceAddr       @ Is there a translation?
13293    str    r0, [rSELF, #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    add    rINST,lr,#-5            @ save start of chain branch
13309    add    rINST, #-4              @  .. which is 9 bytes back
13310    mov    r0,rPC
13311    bl     dvmJitGetTraceAddr      @ Is there a translation?
13312    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13313    cmp    r0,#0
13314    beq    2f
13315    mov    r1,rINST
13316    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
13317    mov    r1, rPC                  @ arg1 of translation may need this
13318    mov    lr, #0                   @ in case target is HANDLER_INTERPRET
13319    cmp    r0,#0                    @ successful chain?
13320    bxne   r0                       @ continue native execution
13321    b      toInterpreter            @ didn't chain - resume with interpreter
13322
13323/* No translation, so request one if profiling isn't disabled*/
133242:
13325    adrl   rIBASE, dvmAsmInstructionStart
13326    GET_JIT_PROF_TABLE(r0)
13327    FETCH_INST()
13328    cmp    r0, #0
13329    movne  r2,#kJitTSelectRequestHot   @ ask for trace selection
13330    bne    common_selectTrace
13331    GET_INST_OPCODE(ip)
13332    GOTO_OPCODE(ip)
13333
13334/*
13335 * Return from the translation cache to the interpreter.
13336 * The return was done with a BLX from thumb mode, and
13337 * the following 32-bit word contains the target rPC value.
13338 * Note that lr (r14) will have its low-order bit set to denote
13339 * its thumb-mode origin.
13340 *
13341 * We'll need to stash our lr origin away, recover the new
13342 * target and then check to see if there is a translation available
13343 * for our new target.  If so, we do a translation chain and
13344 * go back to native execution.  Otherwise, it's back to the
13345 * interpreter (after treating this entry as a potential
13346 * trace start).
13347 */
13348    .global dvmJitToInterpNormal
13349dvmJitToInterpNormal:
13350    ldr    rPC,[lr, #-1]           @ get our target PC
13351    add    rINST,lr,#-5            @ save start of chain branch
13352    add    rINST,#-4               @ .. which is 9 bytes back
13353#if defined(WITH_JIT_TUNING)
13354    bl     dvmBumpNormal
13355#endif
13356    mov    r0,rPC
13357    bl     dvmJitGetTraceAddr      @ Is there a translation?
13358    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13359    cmp    r0,#0
13360    beq    toInterpreter            @ go if not, otherwise do chain
13361    mov    r1,rINST
13362    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
13363    mov    r1, rPC                  @ arg1 of translation may need this
13364    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13365    cmp    r0,#0                    @ successful chain?
13366    bxne   r0                       @ continue native execution
13367    b      toInterpreter            @ didn't chain - resume with interpreter
13368
13369/*
13370 * Return from the translation cache to the interpreter to do method invocation.
13371 * Check if translation exists for the callee, but don't chain to it.
13372 */
13373    .global dvmJitToInterpNoChainNoProfile
13374dvmJitToInterpNoChainNoProfile:
13375#if defined(WITH_JIT_TUNING)
13376    bl     dvmBumpNoChain
13377#endif
13378    mov    r0,rPC
13379    bl     dvmJitGetTraceAddr       @ Is there a translation?
13380    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13381    mov    r1, rPC                  @ arg1 of translation may need this
13382    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13383    cmp    r0,#0
13384    bxne   r0                       @ continue native execution if so
13385    EXPORT_PC()
13386    adrl   rIBASE, dvmAsmInstructionStart
13387    FETCH_INST()
13388    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13389    GOTO_OPCODE(ip)                     @ jump to next instruction
13390
13391/*
13392 * Return from the translation cache to the interpreter to do method invocation.
13393 * Check if translation exists for the callee, but don't chain to it.
13394 */
13395    .global dvmJitToInterpNoChain
13396dvmJitToInterpNoChain:
13397#if defined(WITH_JIT_TUNING)
13398    bl     dvmBumpNoChain
13399#endif
13400    mov    r0,rPC
13401    bl     dvmJitGetTraceAddr       @ Is there a translation?
13402    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13403    mov    r1, rPC                  @ arg1 of translation may need this
13404    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13405    cmp    r0,#0
13406    bxne   r0                       @ continue native execution if so
13407#endif
13408
13409/*
13410 * No translation, restore interpreter regs and start interpreting.
13411 * rSELF & rFP were preserved in the translated code, and rPC has
13412 * already been restored by the time we get here.  We'll need to set
13413 * up rIBASE & rINST, and load the address of the JitTable into r0.
13414 */
13415toInterpreter:
13416    EXPORT_PC()
13417    adrl   rIBASE, dvmAsmInstructionStart
13418    FETCH_INST()
13419    GET_JIT_PROF_TABLE(r0)
13420    @ NOTE: intended fallthrough
13421
13422/*
13423 * Common code to update potential trace start counter, and initiate
13424 * a trace-build if appropriate.  On entry, rPC should point to the
13425 * next instruction to execute, and rINST should be already loaded with
13426 * the next opcode word, and r0 holds a pointer to the jit profile
13427 * table (pJitProfTable).
13428 */
13429common_testUpdateProfile:
13430    cmp     r0,#0
13431    GET_INST_OPCODE(ip)
13432    GOTO_OPCODE_IFEQ(ip)       @ if not profiling, fallthrough otherwise */
13433
13434common_updateProfile:
13435    eor     r3,rPC,rPC,lsr #12 @ cheap, but fast hash function
13436    lsl     r3,r3,#(32 - JIT_PROF_SIZE_LOG_2)          @ shift out excess bits
13437    ldrb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter
13438    GET_INST_OPCODE(ip)
13439    subs    r1,r1,#1           @ decrement counter
13440    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it
13441    GOTO_OPCODE_IFNE(ip)       @ if not threshold, fallthrough otherwise */
13442
13443/*
13444 * Here, we switch to the debug interpreter to request
13445 * trace selection.  First, though, check to see if there
13446 * is already a native translation in place (and, if so,
13447 * jump to it now).
13448 */
13449
13450    GET_JIT_THRESHOLD(r1)
13451    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter
13452    EXPORT_PC()
13453    mov     r0,rPC
13454    bl      dvmJitGetTraceAddr          @ r0<- dvmJitGetTraceAddr(rPC)
13455    str     r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13456    mov     r1, rPC                     @ arg1 of translation may need this
13457    mov     lr, #0                      @  in case target is HANDLER_INTERPRET
13458    cmp     r0,#0
13459#if !defined(WITH_SELF_VERIFICATION)
13460    bxne    r0                          @ jump to the translation
13461    mov     r2,#kJitTSelectRequest      @ ask for trace selection
13462    @ fall-through to common_selectTrace
13463#else
13464    moveq   r2,#kJitTSelectRequest      @ ask for trace selection
13465    beq     common_selectTrace
13466    /*
13467     * At this point, we have a target translation.  However, if
13468     * that translation is actually the interpret-only pseudo-translation
13469     * we want to treat it the same as no translation.
13470     */
13471    mov     r10, r0                     @ save target
13472    bl      dvmCompilerGetInterpretTemplate
13473    cmp     r0, r10                     @ special case?
13474    bne     jitSVShadowRunStart         @ set up self verification shadow space
13475    @ Need to clear the inJitCodeCache flag
13476    mov    r3, #0                       @ 0 means not in the JIT code cache
13477    str    r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land
13478    GET_INST_OPCODE(ip)
13479    GOTO_OPCODE(ip)
13480    /* no return */
13481#endif
13482
13483/*
13484 * On entry:
13485 *  r2 is jit state, e.g. kJitTSelectRequest or kJitTSelectRequestHot
13486 */
13487common_selectTrace:
13488
13489    str     r2,[rSELF,#offThread_jitState]
13490    mov     r2,#kInterpEntryInstr       @ normal entry reason
13491    str     r2,[rSELF,#offThread_entryPoint]
13492    mov     r1,#1                       @ set changeInterp
13493    b       common_gotoBail
13494
13495#if defined(WITH_SELF_VERIFICATION)
13496/*
13497 * Save PC and registers to shadow memory for self verification mode
13498 * before jumping to native translation.
13499 * On entry:
13500 *    rPC, rFP, rSELF: the values that they should contain
13501 *    r10: the address of the target translation.
13502 */
13503jitSVShadowRunStart:
13504    mov     r0,rPC                      @ r0<- program counter
13505    mov     r1,rFP                      @ r1<- frame pointer
13506    mov     r2,rSELF                    @ r2<- self (Thread) pointer
13507    mov     r3,r10                      @ r3<- target translation
13508    bl      dvmSelfVerificationSaveState @ save registers to shadow space
13509    ldr     rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space
13510    bx      r10                         @ jump to the translation
13511
13512/*
13513 * Restore PC, registers, and interpreter state to original values
13514 * before jumping back to the interpreter.
13515 */
13516jitSVShadowRunEnd:
13517    mov    r1,rFP                        @ pass ending fp
13518    mov    r3,rSELF                      @ pass self ptr for convenience
13519    bl     dvmSelfVerificationRestoreState @ restore pc and fp values
13520    ldr    rPC,[rSELF,#offThread_pc]     @ restore PC
13521    ldr    rFP,[rSELF,#offThread_fp]     @ restore FP
13522    ldr    r1,[r0,#offShadowSpace_svState] @ get self verification state
13523    cmp    r1,#0                         @ check for punt condition
13524    beq    1f
13525    mov    r2,#kJitSelfVerification      @ ask for self verification
13526    str    r2,[rSELF,#offThread_jitState]
13527    mov    r2,#kInterpEntryInstr         @ normal entry reason
13528    str    r2,[rSELF,#offThread_entryPoint]
13529    mov    r1,#1                         @ set changeInterp
13530    b      common_gotoBail
13531
135321:                                       @ exit to interpreter without check
13533    EXPORT_PC()
13534    adrl   rIBASE, dvmAsmInstructionStart
13535    FETCH_INST()
13536    GET_INST_OPCODE(ip)
13537    GOTO_OPCODE(ip)
13538#endif
13539
13540#endif
13541
13542/*
13543 * Common code when a backward branch is taken.
13544 *
13545 * TODO: we could avoid a branch by just setting r0 and falling through
13546 * into the common_periodicChecks code, and having a test on r0 at the
13547 * end determine if we should return to the caller or update & branch to
13548 * the next instr.
13549 *
13550 * On entry:
13551 *  r9 is PC adjustment *in bytes*
13552 */
13553common_backwardBranch:
13554    mov     r0, #kInterpEntryInstr
13555    bl      common_periodicChecks
13556#if defined(WITH_JIT)
13557    GET_JIT_PROF_TABLE(r0)
13558    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
13559    cmp     r0,#0
13560    bne     common_updateProfile
13561    GET_INST_OPCODE(ip)
13562    GOTO_OPCODE(ip)
13563#else
13564    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
13565    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13566    GOTO_OPCODE(ip)                     @ jump to next instruction
13567#endif
13568
13569
13570/*
13571 * Need to see if the thread needs to be suspended or debugger/profiler
13572 * activity has begun.  If so, we suspend the thread or side-exit to
13573 * the debug interpreter as appropriate.
13574 *
13575 * The common case is no activity on any of these, so we want to figure
13576 * that out quickly.  If something is up, we can then sort out what.
13577 *
13578 * We want to be fast if the VM was built without debugger or profiler
13579 * support, but we also need to recognize that the system is usually
13580 * shipped with both of these enabled.
13581 *
13582 * TODO: reduce this so we're just checking a single location.
13583 *
13584 * On entry:
13585 *  r0 is reentry type, e.g. kInterpEntryInstr (for debugger/profiling)
13586 *  r9 is trampoline PC adjustment *in bytes*
13587 */
13588common_periodicChecks:
13589/* TUNING - make this a direct load when interpBreak moved to Thread */
13590    ldr     r1, [rSELF, #offThread_pInterpBreak] @ r3<- &interpBreak
13591    /* speculatively thread-specific suspend count */
13592    ldr     ip, [rSELF, #offThread_suspendCount]
13593    ldr     r1, [r1]                                @ r1<- interpBreak
13594    cmp     r1, #0                                  @ anything unusual?
13595    bxeq    lr                                      @ return if not
13596    /*
13597     * One or more interesting events have happened.  Figure out what.
13598     *
13599     * r0 still holds the reentry type.
13600     */
13601    cmp     ip, #0                      @ want suspend?
13602    beq     3f                          @ no, must be something else
13603
13604    stmfd   sp!, {r0, lr}               @ preserve r0 and lr
13605#if defined(WITH_JIT)
13606    /*
13607     * Refresh the Jit's cached copy of profile table pointer.  This pointer
13608     * doubles as the Jit's on/off switch.
13609     */
13610    ldr     r3, [rSELF, #offThread_ppJitProfTable] @ r3<-&gDvmJit.pJitProfTable
13611    mov     r0, rSELF                  @ r0<- self
13612    ldr     r3, [r3] @ r3 <- pJitProfTable
13613    EXPORT_PC()                         @ need for precise GC
13614    str     r3, [rSELF, #offThread_pJitProfTable] @ refresh Jit's on/off switch
13615#else
13616    mov     r0, rSELF                   @ r0<- self
13617    EXPORT_PC()                         @ need for precise GC
13618#endif
13619    bl      dvmCheckSuspendPending      @ do full check, suspend if necessary
13620    ldmfd   sp!, {r0, lr}               @ restore r0 and lr
13621
13622    /*
13623     * Reload the interpBreak flags - they may have changed while we
13624     * were suspended.
13625     */
13626/* TUNING - direct load when InterpBreak moved to Thread */
13627    ldr     r1, [rSELF, #offThread_pInterpBreak]   @ r1<- &interpBreak
13628    ldr     r1, [r1]                    @ r1<- interpBreak
136293:
13630    /*
13631     * TODO: this code is too fragile.  Need a general mechanism
13632     * to identify what actions to take by submode.  Some profiling modes
13633     * (instruction count) need to single-step, while method tracing
13634     * may not.  Debugging with breakpoints can run unfettered, but
13635     * source-level single-stepping requires Dalvik singlestepping.
13636     * GC may require a one-shot action and then full-speed resumption.
13637     */
13638    ands    r1, #(kSubModeDebuggerActive | kSubModeEmulatorTrace | kSubModeInstCounting)
13639    bxeq    lr                          @ nothing to do, return
13640
13641    @ debugger/profiler enabled, bail out; self->entryPoint was set above
13642    str     r0, [rSELF, #offThread_entryPoint]  @ store r0, need for debug/prof
13643    add     rPC, rPC, r9                @ update rPC
13644    mov     r1, #1                      @ "want switch" = true
13645    b       common_gotoBail             @ side exit
13646
13647
13648/*
13649 * The equivalent of "goto bail", this calls through the "bail handler".
13650 *
13651 * State registers will be saved to the "thread" area before bailing.
13652 *
13653 * On entry:
13654 *  r1 is "bool changeInterp", indicating if we want to switch to the
13655 *     other interpreter or just bail all the way out
13656 */
13657common_gotoBail:
13658    SAVE_PC_FP_TO_SELF()                @ export state to "thread"
13659    mov     r0, rSELF                   @ r0<- self ptr
13660    b       dvmMterpStdBail             @ call(self, changeInterp)
13661
13662    @add     r1, r1, #1                  @ using (boolean+1)
13663    @add     r0, rSELF, #offThread_jmpBuf @ r0<- &self->jmpBuf
13664    @bl      _longjmp                    @ does not return
13665    @bl      common_abort
13666
13667
13668/*
13669 * Common code for jumbo method invocation.
13670 * NOTE: this adjusts rPC to account for the difference in instruction width.
13671 * As a result, the savedPc in the stack frame will not be wholly accurate. So
13672 * long as that is only used for source file line number calculations, we're
13673 * okay.
13674 *
13675 * On entry:
13676 *  r0 is "Method* methodToCall", the method we're trying to call
13677 */
13678common_invokeMethodJumbo:
13679.LinvokeNewJumbo:
13680    @ prepare to copy args to "outs" area of current frame
13681    add     rPC, rPC, #4                @ adjust pc to make return consistent
13682    FETCH(r2, 1)                        @ r2<- BBBB (arg count)
13683    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13684    cmp     r2, #0                      @ no args?
13685    beq     .LinvokeArgsDone            @ if no args, skip the rest
13686    FETCH(r1, 2)                        @ r1<- CCCC
13687    b       .LinvokeRangeArgs           @ handle args like invoke range
13688
13689/*
13690 * Common code for method invocation with range.
13691 *
13692 * On entry:
13693 *  r0 is "Method* methodToCall", the method we're trying to call
13694 */
13695common_invokeMethodRange:
13696.LinvokeNewRange:
13697    @ prepare to copy args to "outs" area of current frame
13698    movs    r2, rINST, lsr #8           @ r2<- AA (arg count) -- test for zero
13699    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13700    beq     .LinvokeArgsDone            @ if no args, skip the rest
13701    FETCH(r1, 2)                        @ r1<- CCCC
13702
13703.LinvokeRangeArgs:
13704    @ r0=methodToCall, r1=CCCC, r2=count, r10=outs
13705    @ (very few methods have > 10 args; could unroll for common cases)
13706    add     r3, rFP, r1, lsl #2         @ r3<- &fp[CCCC]
13707    sub     r10, r10, r2, lsl #2        @ r10<- "outs" area, for call args
137081:  ldr     r1, [r3], #4                @ val = *fp++
13709    subs    r2, r2, #1                  @ count--
13710    str     r1, [r10], #4               @ *outs++ = val
13711    bne     1b                          @ ...while count != 0
13712    b       .LinvokeArgsDone
13713
13714/*
13715 * Common code for method invocation without range.
13716 *
13717 * On entry:
13718 *  r0 is "Method* methodToCall", the method we're trying to call
13719 */
13720common_invokeMethodNoRange:
13721.LinvokeNewNoRange:
13722    @ prepare to copy args to "outs" area of current frame
13723    movs    r2, rINST, lsr #12          @ r2<- B (arg count) -- test for zero
13724    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13725    FETCH(r1, 2)                        @ r1<- GFED (load here to hide latency)
13726    beq     .LinvokeArgsDone
13727
13728    @ r0=methodToCall, r1=GFED, r2=count, r10=outs
13729.LinvokeNonRange:
13730    rsb     r2, r2, #5                  @ r2<- 5-r2
13731    add     pc, pc, r2, lsl #4          @ computed goto, 4 instrs each
13732    bl      common_abort                @ (skipped due to ARM prefetch)
137335:  and     ip, rINST, #0x0f00          @ isolate A
13734    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vA (shift right 8, left 2)
13735    mov     r0, r0                      @ nop
13736    str     r2, [r10, #-4]!             @ *--outs = vA
137374:  and     ip, r1, #0xf000             @ isolate G
13738    ldr     r2, [rFP, ip, lsr #10]      @ r2<- vG (shift right 12, left 2)
13739    mov     r0, r0                      @ nop
13740    str     r2, [r10, #-4]!             @ *--outs = vG
137413:  and     ip, r1, #0x0f00             @ isolate F
13742    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vF
13743    mov     r0, r0                      @ nop
13744    str     r2, [r10, #-4]!             @ *--outs = vF
137452:  and     ip, r1, #0x00f0             @ isolate E
13746    ldr     r2, [rFP, ip, lsr #2]       @ r2<- vE
13747    mov     r0, r0                      @ nop
13748    str     r2, [r10, #-4]!             @ *--outs = vE
137491:  and     ip, r1, #0x000f             @ isolate D
13750    ldr     r2, [rFP, ip, lsl #2]       @ r2<- vD
13751    mov     r0, r0                      @ nop
13752    str     r2, [r10, #-4]!             @ *--outs = vD
137530:  @ fall through to .LinvokeArgsDone
13754
13755.LinvokeArgsDone: @ r0=methodToCall
13756    ldrh    r9, [r0, #offMethod_registersSize]  @ r9<- methodToCall->regsSize
13757    ldrh    r3, [r0, #offMethod_outsSize]  @ r3<- methodToCall->outsSize
13758    ldr     r2, [r0, #offMethod_insns]  @ r2<- method->insns
13759    ldr     rINST, [r0, #offMethod_clazz]  @ rINST<- method->clazz
13760    @ find space for the new stack frame, check for overflow
13761    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- stack save area
13762    sub     r1, r1, r9, lsl #2          @ r1<- newFp (old savearea - regsSize)
13763    SAVEAREA_FROM_FP(r10, r1)           @ r10<- newSaveArea
13764@    bl      common_dumpRegs
13765    ldr     r9, [rSELF, #offThread_interpStackEnd]    @ r9<- interpStackEnd
13766    sub     r3, r10, r3, lsl #2         @ r3<- bottom (newsave - outsSize)
13767    cmp     r3, r9                      @ bottom < interpStackEnd?
13768    ldr     lr, [rSELF, #offThread_pInterpBreak]
13769    ldr     r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags
13770    blo     .LstackOverflow             @ yes, this frame will overflow stack
13771
13772    @ set up newSaveArea
13773    ldr     lr, [lr]                    @ lr<- active submodes
13774#ifdef EASY_GDB
13775    SAVEAREA_FROM_FP(ip, rFP)           @ ip<- stack save area
13776    str     ip, [r10, #offStackSaveArea_prevSave]
13777#endif
13778    str     rFP, [r10, #offStackSaveArea_prevFrame]
13779    str     rPC, [r10, #offStackSaveArea_savedPc]
13780#if defined(WITH_JIT)
13781    mov     r9, #0
13782    str     r9, [r10, #offStackSaveArea_returnAddr]
13783#endif
13784    ands    lr, #kSubModeMethodTrace    @ method tracing?
13785    beq     1f                          @ skip if not
13786    stmfd   sp!, {r0-r3}                @ preserve r0-r3
13787    mov     r1, r6
13788    @ r0=methodToCall, r1=rSELF
13789    bl      dvmFastMethodTraceEnter
13790    ldmfd   sp!, {r0-r3}                @ restore r0-r3
137911:
13792    str     r0, [r10, #offStackSaveArea_method]
13793    tst     r3, #ACC_NATIVE
13794    bne     .LinvokeNative
13795
13796    /*
13797    stmfd   sp!, {r0-r3}
13798    bl      common_printNewline
13799    mov     r0, rFP
13800    mov     r1, #0
13801    bl      dvmDumpFp
13802    ldmfd   sp!, {r0-r3}
13803    stmfd   sp!, {r0-r3}
13804    mov     r0, r1
13805    mov     r1, r10
13806    bl      dvmDumpFp
13807    bl      common_printNewline
13808    ldmfd   sp!, {r0-r3}
13809    */
13810
13811    ldrh    r9, [r2]                        @ r9 <- load INST from new PC
13812    ldr     r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
13813    mov     rPC, r2                         @ publish new rPC
13814
13815    @ Update state values for the new method
13816    @ r0=methodToCall, r1=newFp, r3=newMethodClass, r9=newINST
13817    str     r0, [rSELF, #offThread_method]    @ self->method = methodToCall
13818    str     r3, [rSELF, #offThread_methodClassDex] @ self->methodClassDex = ...
13819#if defined(WITH_JIT)
13820    GET_JIT_PROF_TABLE(r0)
13821    mov     rFP, r1                         @ fp = newFp
13822    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
13823    mov     rINST, r9                       @ publish new rINST
13824    str     r1, [rSELF, #offThread_curFrame]   @ self->curFrame = newFp
13825    cmp     r0,#0
13826    bne     common_updateProfile
13827    GOTO_OPCODE(ip)                         @ jump to next instruction
13828#else
13829    mov     rFP, r1                         @ fp = newFp
13830    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
13831    mov     rINST, r9                       @ publish new rINST
13832    str     r1, [rSELF, #offThread_curFrame]   @ self->curFrame = newFp
13833    GOTO_OPCODE(ip)                         @ jump to next instruction
13834#endif
13835
13836.LinvokeNative:
13837    @ Prep for the native call
13838    @ r0=methodToCall, r1=newFp, r10=newSaveArea
13839    ldr     lr, [rSELF, #offThread_pInterpBreak]
13840    ldr     r9, [rSELF, #offThread_jniLocal_topCookie]@r9<-thread->localRef->...
13841    str     r1, [rSELF, #offThread_curFrame]   @ self->curFrame = newFp
13842    str     r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top
13843    ldr     lr, [lr]                    @ lr<- active submodes
13844
13845    mov     r2, r0                      @ r2<- methodToCall
13846    mov     r0, r1                      @ r0<- newFp (points to args)
13847    add     r1, rSELF, #offThread_retval  @ r1<- &retval
13848    mov     r3, rSELF                   @ arg3<- self
13849
13850#ifdef ASSIST_DEBUGGER
13851    /* insert fake function header to help gdb find the stack frame */
13852    b       .Lskip
13853    .type   dalvik_mterp, %function
13854dalvik_mterp:
13855    .fnstart
13856    MTERP_ENTRY1
13857    MTERP_ENTRY2
13858.Lskip:
13859#endif
13860
13861    ands    lr, #kSubModeMethodTrace    @ method tracing?
13862    beq     110f                        @ hop if not
13863    @ r2=JNIMethod, r6=rSELF
13864    stmfd   sp!, {r2,r6}
13865
13866    mov     lr, pc                      @ set return addr
13867    ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
13868
13869    @ r0=JNIMethod, r1=rSELF
13870    ldmfd   sp!, {r0-r1}
13871    bl      dvmFastNativeMethodTraceExit
13872    b       220f
13873110:
13874    mov     lr, pc                      @ set return addr
13875    ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
13876220:
13877#if defined(WITH_JIT)
13878    ldr     r3, [rSELF, #offThread_ppJitProfTable] @ Refresh Jit's on/off status
13879#endif
13880
13881    @ native return; r10=newSaveArea
13882    @ equivalent to dvmPopJniLocals
13883    ldr     r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top
13884    ldr     r1, [rSELF, #offThread_exception] @ check for exception
13885#if defined(WITH_JIT)
13886    ldr     r3, [r3]                    @ r3 <- gDvmJit.pProfTable
13887#endif
13888    str     rFP, [rSELF, #offThread_curFrame]  @ self->curFrame = fp
13889    cmp     r1, #0                      @ null?
13890    str     r0, [rSELF, #offThread_jniLocal_topCookie] @ new top <- old top
13891#if defined(WITH_JIT)
13892    str     r3, [rSELF, #offThread_pJitProfTable] @ refresh cached on/off switch
13893#endif
13894    bne     common_exceptionThrown      @ no, handle exception
13895
13896    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
13897    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13898    GOTO_OPCODE(ip)                     @ jump to next instruction
13899
13900.LstackOverflow:    @ r0=methodToCall
13901    mov     r1, r0                      @ r1<- methodToCall
13902    mov     r0, rSELF                   @ r0<- self
13903    bl      dvmHandleStackOverflow
13904    b       common_exceptionThrown
13905#ifdef ASSIST_DEBUGGER
13906    .fnend
13907    .size   dalvik_mterp, .-dalvik_mterp
13908#endif
13909
13910
13911    /*
13912     * Common code for method invocation, calling through "glue code".
13913     *
13914     * TODO: now that we have range and non-range invoke handlers, this
13915     *       needs to be split into two.  Maybe just create entry points
13916     *       that set r9 and jump here?
13917     *
13918     * On entry:
13919     *  r0 is "Method* methodToCall", the method we're trying to call
13920     *  r9 is "bool methodCallRange", indicating if this is a /range variant
13921     */
13922     .if    0
13923.LinvokeOld:
13924    sub     sp, sp, #8                  @ space for args + pad
13925    FETCH(ip, 2)                        @ ip<- FEDC or CCCC
13926    mov     r2, r0                      @ A2<- methodToCall
13927    mov     r0, rSELF                   @ A0<- self
13928    SAVE_PC_FP_TO_SELF()                @ export state to "self"
13929    mov     r1, r9                      @ A1<- methodCallRange
13930    mov     r3, rINST, lsr #8           @ A3<- AA
13931    str     ip, [sp, #0]                @ A4<- ip
13932    bl      dvmMterp_invokeMethod       @ call the C invokeMethod
13933    add     sp, sp, #8                  @ remove arg area
13934    b       common_resumeAfterGlueCall  @ continue to next instruction
13935    .endif
13936
13937
13938
13939/*
13940 * Common code for handling a return instruction.
13941 *
13942 * This does not return.
13943 */
13944common_returnFromMethod:
13945.LreturnNew:
13946    mov     r0, #kInterpEntryReturn
13947    mov     r9, #0
13948    bl      common_periodicChecks
13949
13950    ldr     lr, [rSELF, #offThread_pInterpBreak]
13951    SAVEAREA_FROM_FP(r0, rFP)
13952    ldr     lr, [lr]                    @ lr<- active submodes
13953    ldr     r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc
13954    ands    lr, #kSubModeMethodTrace    @ method tracing?
13955    beq     333f
13956    stmfd   sp!, {r0-r3}                @ preserve r0-r3
13957    mov     r0, r6
13958    @ r0=rSELF
13959    bl      dvmFastJavaMethodTraceExit
13960    ldmfd   sp!, {r0-r3}                @ restore r0-r3
13961333:
13962    ldr     rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame
13963    ldr     r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)]
13964                                        @ r2<- method we're returning to
13965    cmp     r2, #0                      @ is this a break frame?
13966#if defined(WORKAROUND_CORTEX_A9_745320)
13967    /* Don't use conditional loads if the HW defect exists */
13968    beq     101f
13969    ldr     r10, [r2, #offMethod_clazz] @ r10<- method->clazz
13970101:
13971#else
13972    ldrne   r10, [r2, #offMethod_clazz] @ r10<- method->clazz
13973#endif
13974    mov     r1, #0                      @ "want switch" = false
13975    beq     common_gotoBail             @ break frame, bail out completely
13976
13977    PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST
13978    str     r2, [rSELF, #offThread_method]@ self->method = newSave->method
13979    ldr     r1, [r10, #offClassObject_pDvmDex]   @ r1<- method->clazz->pDvmDex
13980    str     rFP, [rSELF, #offThread_curFrame]  @ self->curFrame = fp
13981#if defined(WITH_JIT)
13982    ldr     r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr
13983    mov     rPC, r9                     @ publish new rPC
13984    str     r1, [rSELF, #offThread_methodClassDex]
13985    str     r10, [rSELF, #offThread_inJitCodeCache]  @ may return to JIT'ed land
13986    cmp     r10, #0                      @ caller is compiled code
13987    blxne   r10
13988    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13989    GOTO_OPCODE(ip)                     @ jump to next instruction
13990#else
13991    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13992    mov     rPC, r9                     @ publish new rPC
13993    str     r1, [rSELF, #offThread_methodClassDex]
13994    GOTO_OPCODE(ip)                     @ jump to next instruction
13995#endif
13996
13997    /*
13998     * Return handling, calls through "glue code".
13999     */
14000     .if    0
14001.LreturnOld:
14002    SAVE_PC_FP_TO_SELF()                @ export state
14003    mov     r0, rSELF                   @ arg to function
14004    bl      dvmMterp_returnFromMethod
14005    b       common_resumeAfterGlueCall
14006    .endif
14007
14008
14009/*
14010 * Somebody has thrown an exception.  Handle it.
14011 *
14012 * If the exception processing code returns to us (instead of falling
14013 * out of the interpreter), continue with whatever the next instruction
14014 * now happens to be.
14015 *
14016 * This does not return.
14017 */
14018     .global dvmMterpCommonExceptionThrown
14019dvmMterpCommonExceptionThrown:
14020common_exceptionThrown:
14021.LexceptionNew:
14022    mov     r0, #kInterpEntryThrow
14023    mov     r9, #0
14024    bl      common_periodicChecks
14025
14026    ldr     r9, [rSELF, #offThread_exception] @ r9<- self->exception
14027    mov     r1, rSELF                   @ r1<- self
14028    mov     r0, r9                      @ r0<- exception
14029    bl      dvmAddTrackedAlloc          @ don't let the exception be GCed
14030    mov     r3, #0                      @ r3<- NULL
14031    str     r3, [rSELF, #offThread_exception] @ self->exception = NULL
14032
14033    /* set up args and a local for "&fp" */
14034    /* (str sp, [sp, #-4]!  would be perfect here, but is discouraged) */
14035    str     rFP, [sp, #-4]!             @ *--sp = fp
14036    mov     ip, sp                      @ ip<- &fp
14037    mov     r3, #0                      @ r3<- false
14038    str     ip, [sp, #-4]!              @ *--sp = &fp
14039    ldr     r1, [rSELF, #offThread_method] @ r1<- self->method
14040    mov     r0, rSELF                   @ r0<- self
14041    ldr     r1, [r1, #offMethod_insns]  @ r1<- method->insns
14042    mov     r2, r9                      @ r2<- exception
14043    sub     r1, rPC, r1                 @ r1<- pc - method->insns
14044    mov     r1, r1, asr #1              @ r1<- offset in code units
14045
14046    /* call, r0 gets catchRelPc (a code-unit offset) */
14047    bl      dvmFindCatchBlock           @ call(self, relPc, exc, scan?, &fp)
14048
14049    /* fix earlier stack overflow if necessary; may trash rFP */
14050    ldrb    r1, [rSELF, #offThread_stackOverflowed]
14051    cmp     r1, #0                      @ did we overflow earlier?
14052    beq     1f                          @ no, skip ahead
14053    mov     rFP, r0                     @ save relPc result in rFP
14054    mov     r0, rSELF                   @ r0<- self
14055    mov     r1, r9                      @ r1<- exception
14056    bl      dvmCleanupStackOverflow     @ call(self)
14057    mov     r0, rFP                     @ restore result
140581:
14059
14060    /* update frame pointer and check result from dvmFindCatchBlock */
14061    ldr     rFP, [sp, #4]               @ retrieve the updated rFP
14062    cmp     r0, #0                      @ is catchRelPc < 0?
14063    add     sp, sp, #8                  @ restore stack
14064    bmi     .LnotCaughtLocally
14065
14066    /* adjust locals to match self->curFrame and updated PC */
14067    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- new save area
14068    ldr     r1, [r1, #offStackSaveArea_method] @ r1<- new method
14069    str     r1, [rSELF, #offThread_method]  @ self->method = new method
14070    ldr     r2, [r1, #offMethod_clazz]      @ r2<- method->clazz
14071    ldr     r3, [r1, #offMethod_insns]      @ r3<- method->insns
14072    ldr     r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex
14073    add     rPC, r3, r0, asl #1             @ rPC<- method->insns + catchRelPc
14074    str     r2, [rSELF, #offThread_methodClassDex] @ self->pDvmDex = meth...
14075
14076    /* release the tracked alloc on the exception */
14077    mov     r0, r9                      @ r0<- exception
14078    mov     r1, rSELF                   @ r1<- self
14079    bl      dvmReleaseTrackedAlloc      @ release the exception
14080
14081    /* restore the exception if the handler wants it */
14082    FETCH_INST()                        @ load rINST from rPC
14083    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14084    cmp     ip, #OP_MOVE_EXCEPTION      @ is it "move-exception"?
14085    streq   r9, [rSELF, #offThread_exception] @ yes, restore the exception
14086    GOTO_OPCODE(ip)                     @ jump to next instruction
14087
14088.LnotCaughtLocally: @ r9=exception
14089    /* fix stack overflow if necessary */
14090    ldrb    r1, [rSELF, #offThread_stackOverflowed]
14091    cmp     r1, #0                      @ did we overflow earlier?
14092    movne   r0, rSELF                   @ if yes: r0<- self
14093    movne   r1, r9                      @ if yes: r1<- exception
14094    blne    dvmCleanupStackOverflow     @ if yes: call(self)
14095
14096    @ may want to show "not caught locally" debug messages here
14097#if DVM_SHOW_EXCEPTION >= 2
14098    /* call __android_log_print(prio, tag, format, ...) */
14099    /* "Exception %s from %s:%d not caught locally" */
14100    @ dvmLineNumFromPC(method, pc - method->insns)
14101    ldr     r0, [rSELF, #offThread_method]
14102    ldr     r1, [r0, #offMethod_insns]
14103    sub     r1, rPC, r1
14104    asr     r1, r1, #1
14105    bl      dvmLineNumFromPC
14106    str     r0, [sp, #-4]!
14107    @ dvmGetMethodSourceFile(method)
14108    ldr     r0, [rSELF, #offThread_method]
14109    bl      dvmGetMethodSourceFile
14110    str     r0, [sp, #-4]!
14111    @ exception->clazz->descriptor
14112    ldr     r3, [r9, #offObject_clazz]
14113    ldr     r3, [r3, #offClassObject_descriptor]
14114    @
14115    ldr     r2, strExceptionNotCaughtLocally
14116    ldr     r1, strLogTag
14117    mov     r0, #3                      @ LOG_DEBUG
14118    bl      __android_log_print
14119#endif
14120    str     r9, [rSELF, #offThread_exception] @ restore exception
14121    mov     r0, r9                      @ r0<- exception
14122    mov     r1, rSELF                   @ r1<- self
14123    bl      dvmReleaseTrackedAlloc      @ release the exception
14124    mov     r1, #0                      @ "want switch" = false
14125    b       common_gotoBail             @ bail out
14126
14127
14128    /*
14129     * Exception handling, calls through "glue code".
14130     */
14131    .if     0
14132.LexceptionOld:
14133    SAVE_PC_FP_TO_SELF()                @ export state
14134    mov     r0, rSELF                   @ arg to function
14135    bl      dvmMterp_exceptionThrown
14136    b       common_resumeAfterGlueCall
14137    .endif
14138
14139
14140/*
14141 * After returning from a "glued" function, pull out the updated
14142 * values and start executing at the next instruction.
14143 */
14144common_resumeAfterGlueCall:
14145    LOAD_PC_FP_FROM_SELF()              @ pull rPC and rFP out of thread
14146    FETCH_INST()                        @ load rINST from rPC
14147    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14148    GOTO_OPCODE(ip)                     @ jump to next instruction
14149
14150/*
14151 * Invalid array index. Note that our calling convention is strange; we use r1
14152 * and r3 because those just happen to be the registers all our callers are
14153 * using. We shuffle them here before calling the C function.
14154 * r1: index
14155 * r3: size
14156 */
14157common_errArrayIndex:
14158    EXPORT_PC()
14159    mov     r0, r1
14160    mov     r1, r3
14161    bl      dvmThrowArrayIndexOutOfBoundsException
14162    b       common_exceptionThrown
14163
14164/*
14165 * Integer divide or mod by zero.
14166 */
14167common_errDivideByZero:
14168    EXPORT_PC()
14169    ldr     r0, strArithmeticException
14170    ldr     r1, strDivideByZero
14171    bl      dvmThrowException
14172    b       common_exceptionThrown
14173
14174/*
14175 * Attempt to allocate an array with a negative size.
14176 * On entry: length in r1
14177 */
14178common_errNegativeArraySize:
14179    EXPORT_PC()
14180    mov     r0, r1                                @ arg0 <- len
14181    bl      dvmThrowNegativeArraySizeException    @ (len)
14182    b       common_exceptionThrown
14183
14184/*
14185 * Invocation of a non-existent method.
14186 */
14187common_errNoSuchMethod:
14188    EXPORT_PC()
14189    ldr     r0, strNoSuchMethodError
14190    mov     r1, #0
14191    bl      dvmThrowException
14192    b       common_exceptionThrown
14193
14194/*
14195 * We encountered a null object when we weren't expecting one.  We
14196 * export the PC, throw a NullPointerException, and goto the exception
14197 * processing code.
14198 */
14199common_errNullObject:
14200    EXPORT_PC()
14201    ldr     r0, strNullPointerException
14202    mov     r1, #0
14203    bl      dvmThrowException
14204    b       common_exceptionThrown
14205
14206/*
14207 * For debugging, cause an immediate fault.  The source address will
14208 * be in lr (use a bl instruction to jump here).
14209 */
14210common_abort:
14211    ldr     pc, .LdeadFood
14212.LdeadFood:
14213    .word   0xdeadf00d
14214
14215/*
14216 * Spit out a "we were here", preserving all registers.  (The attempt
14217 * to save ip won't work, but we need to save an even number of
14218 * registers for EABI 64-bit stack alignment.)
14219 */
14220    .macro  SQUEAK num
14221common_squeak\num:
14222    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14223    ldr     r0, strSqueak
14224    mov     r1, #\num
14225    bl      printf
14226    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14227    bx      lr
14228    .endm
14229
14230    SQUEAK  0
14231    SQUEAK  1
14232    SQUEAK  2
14233    SQUEAK  3
14234    SQUEAK  4
14235    SQUEAK  5
14236
14237/*
14238 * Spit out the number in r0, preserving registers.
14239 */
14240common_printNum:
14241    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14242    mov     r1, r0
14243    ldr     r0, strSqueak
14244    bl      printf
14245    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14246    bx      lr
14247
14248/*
14249 * Print a newline, preserving registers.
14250 */
14251common_printNewline:
14252    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14253    ldr     r0, strNewline
14254    bl      printf
14255    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14256    bx      lr
14257
14258    /*
14259     * Print the 32-bit quantity in r0 as a hex value, preserving registers.
14260     */
14261common_printHex:
14262    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14263    mov     r1, r0
14264    ldr     r0, strPrintHex
14265    bl      printf
14266    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14267    bx      lr
14268
14269/*
14270 * Print the 64-bit quantity in r0-r1, preserving registers.
14271 */
14272common_printLong:
14273    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14274    mov     r3, r1
14275    mov     r2, r0
14276    ldr     r0, strPrintLong
14277    bl      printf
14278    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14279    bx      lr
14280
14281/*
14282 * Print full method info.  Pass the Method* in r0.  Preserves regs.
14283 */
14284common_printMethod:
14285    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14286    bl      dvmMterpPrintMethod
14287    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14288    bx      lr
14289
14290/*
14291 * Call a C helper function that dumps regs and possibly some
14292 * additional info.  Requires the C function to be compiled in.
14293 */
14294    .if     0
14295common_dumpRegs:
14296    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14297    bl      dvmMterpDumpArmRegs
14298    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14299    bx      lr
14300    .endif
14301
14302#if 0
14303/*
14304 * Experiment on VFP mode.
14305 *
14306 * uint32_t setFPSCR(uint32_t val, uint32_t mask)
14307 *
14308 * Updates the bits specified by "mask", setting them to the values in "val".
14309 */
14310setFPSCR:
14311    and     r0, r0, r1                  @ make sure no stray bits are set
14312    fmrx    r2, fpscr                   @ get VFP reg
14313    mvn     r1, r1                      @ bit-invert mask
14314    and     r2, r2, r1                  @ clear masked bits
14315    orr     r2, r2, r0                  @ set specified bits
14316    fmxr    fpscr, r2                   @ set VFP reg
14317    mov     r0, r2                      @ return new value
14318    bx      lr
14319
14320    .align  2
14321    .global dvmConfigureFP
14322    .type   dvmConfigureFP, %function
14323dvmConfigureFP:
14324    stmfd   sp!, {ip, lr}
14325    /* 0x03000000 sets DN/FZ */
14326    /* 0x00009f00 clears the six exception enable flags */
14327    bl      common_squeak0
14328    mov     r0, #0x03000000             @ r0<- 0x03000000
14329    add     r1, r0, #0x9f00             @ r1<- 0x03009f00
14330    bl      setFPSCR
14331    ldmfd   sp!, {ip, pc}
14332#endif
14333
14334
14335/*
14336 * String references, must be close to the code that uses them.
14337 */
14338    .align  2
14339strArithmeticException:
14340    .word   .LstrArithmeticException
14341strDivideByZero:
14342    .word   .LstrDivideByZero
14343strNoSuchMethodError:
14344    .word   .LstrNoSuchMethodError
14345strNullPointerException:
14346    .word   .LstrNullPointerException
14347
14348strLogTag:
14349    .word   .LstrLogTag
14350strExceptionNotCaughtLocally:
14351    .word   .LstrExceptionNotCaughtLocally
14352
14353strNewline:
14354    .word   .LstrNewline
14355strSqueak:
14356    .word   .LstrSqueak
14357strPrintHex:
14358    .word   .LstrPrintHex
14359strPrintLong:
14360    .word   .LstrPrintLong
14361
14362/*
14363 * Zero-terminated ASCII string data.
14364 *
14365 * On ARM we have two choices: do like gcc does, and LDR from a .word
14366 * with the address, or use an ADR pseudo-op to get the address
14367 * directly.  ADR saves 4 bytes and an indirection, but it's using a
14368 * PC-relative addressing mode and hence has a limited range, which
14369 * makes it not work well with mergeable string sections.
14370 */
14371    .section .rodata.str1.4,"aMS",%progbits,1
14372
14373.LstrBadEntryPoint:
14374    .asciz  "Bad entry point %d\n"
14375.LstrArithmeticException:
14376    .asciz  "Ljava/lang/ArithmeticException;"
14377.LstrDivideByZero:
14378    .asciz  "divide by zero"
14379.LstrFilledNewArrayNotImpl:
14380    .asciz  "filled-new-array only implemented for objects and 'int'"
14381.LstrInternalError:
14382    .asciz  "Ljava/lang/InternalError;"
14383.LstrInstantiationError:
14384    .asciz  "Ljava/lang/InstantiationError;"
14385.LstrNoSuchMethodError:
14386    .asciz  "Ljava/lang/NoSuchMethodError;"
14387.LstrNullPointerException:
14388    .asciz  "Ljava/lang/NullPointerException;"
14389
14390.LstrLogTag:
14391    .asciz  "mterp"
14392.LstrExceptionNotCaughtLocally:
14393    .asciz  "Exception %s from %s:%d not caught locally\n"
14394
14395.LstrNewline:
14396    .asciz  "\n"
14397.LstrSqueak:
14398    .asciz  "<%d>"
14399.LstrPrintHex:
14400    .asciz  "<0x%x>"
14401.LstrPrintLong:
14402    .asciz  "<%lld>"
14403
14404