InterpAsm-armv7-a.S revision 8cb0d098d79af61546e275f633325794f4587602
1/*
2 * This file was generated automatically by gen-mterp.py for 'armv7-a'.
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: armv7-a/platform.S */
210/*
211 * ===========================================================================
212 *  CPU-version-specific defines
213 * ===========================================================================
214 */
215
216#if !defined(ANDROID_SMP)
217# error "Must define ANDROID_SMP"
218#endif
219
220/*
221 * Macro for data memory barrier.
222 */
223.macro  SMP_DMB
224#if ANDROID_SMP != 0
225    dmb
226#else
227    /* not SMP */
228#endif
229.endm
230
231/*
232 * Macro for data memory barrier (store/store variant).
233 */
234.macro  SMP_DMB_ST
235#if ANDROID_SMP != 0
236    dmb     st
237#else
238    /* not SMP */
239#endif
240.endm
241
242/* File: armv5te/entry.S */
243/*
244 * Copyright (C) 2008 The Android Open Source Project
245 *
246 * Licensed under the Apache License, Version 2.0 (the "License");
247 * you may not use this file except in compliance with the License.
248 * You may obtain a copy of the License at
249 *
250 *      http://www.apache.org/licenses/LICENSE-2.0
251 *
252 * Unless required by applicable law or agreed to in writing, software
253 * distributed under the License is distributed on an "AS IS" BASIS,
254 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
255 * See the License for the specific language governing permissions and
256 * limitations under the License.
257 */
258/*
259 * Interpreter entry point.
260 */
261
262/*
263 * We don't have formal stack frames, so gdb scans upward in the code
264 * to find the start of the function (a label with the %function type),
265 * and then looks at the next few instructions to figure out what
266 * got pushed onto the stack.  From this it figures out how to restore
267 * the registers, including PC, for the previous stack frame.  If gdb
268 * sees a non-function label, it stops scanning, so either we need to
269 * have nothing but assembler-local labels between the entry point and
270 * the break, or we need to fake it out.
271 *
272 * When this is defined, we add some stuff to make gdb less confused.
273 */
274#define ASSIST_DEBUGGER 1
275
276    .text
277    .align  2
278    .global dvmMterpStdRun
279    .type   dvmMterpStdRun, %function
280
281/*
282 * On entry:
283 *  r0  Thread* self
284 *
285 * This function returns a boolean "changeInterp" value.  The return comes
286 * via a call to dvmMterpStdBail().
287 */
288dvmMterpStdRun:
289#define MTERP_ENTRY1 \
290    .save {r4-r10,fp,lr}; \
291    stmfd   sp!, {r4-r10,fp,lr}         @ save 9 regs
292#define MTERP_ENTRY2 \
293    .pad    #4; \
294    sub     sp, sp, #4                  @ align 64
295
296    .fnstart
297    MTERP_ENTRY1
298    MTERP_ENTRY2
299
300    /* save stack pointer, add magic word for debuggerd */
301    str     sp, [r0, #offThread_bailPtr]  @ save SP for eventual return
302
303    /* set up "named" registers, figure out entry point */
304    mov     rSELF, r0                   @ set rSELF
305    ldr     r1, [r0, #offThread_entryPoint]   @ enum is 4 bytes in aapcs-EABI
306    LOAD_PC_FP_FROM_SELF()              @ load rPC and rFP from "thread"
307    adr     rIBASE, dvmAsmInstructionStart  @ set rIBASE
308    cmp     r1, #kInterpEntryInstr      @ usual case?
309    bne     .Lnot_instr                 @ no, handle it
310
311#if defined(WITH_JIT)
312.LentryInstr:
313    /* Entry is always a possible trace start */
314    GET_JIT_PROF_TABLE(r0)
315    FETCH_INST()
316    mov     r1, #0                      @ prepare the value for the new state
317    str     r1, [rSELF, #offThread_inJitCodeCache] @ back to the interp land
318    cmp     r0,#0                       @ is profiling disabled?
319#if !defined(WITH_SELF_VERIFICATION)
320    bne     common_updateProfile        @ profiling is enabled
321#else
322    ldr     r2, [rSELF, #offThread_shadowSpace] @ to find out the jit exit state
323    beq     1f                          @ profiling is disabled
324    ldr     r3, [r2, #offShadowSpace_jitExitState]  @ jit exit state
325    cmp     r3, #kSVSTraceSelect        @ hot trace following?
326    moveq   r2,#kJitTSelectRequestHot   @ ask for trace selection
327    beq     common_selectTrace          @ go build the trace
328    cmp     r3, #kSVSNoProfile          @ don't profile the next instruction?
329    beq     1f                          @ intrepret the next instruction
330    b       common_updateProfile        @ collect profiles
331#endif
3321:
333    GET_INST_OPCODE(ip)
334    GOTO_OPCODE(ip)
335#else
336    /* start executing the instruction at rPC */
337    FETCH_INST()                        @ load rINST from rPC
338    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
339    GOTO_OPCODE(ip)                     @ jump to next instruction
340#endif
341
342.Lnot_instr:
343    cmp     r1, #kInterpEntryReturn     @ were we returning from a method?
344    beq     common_returnFromMethod
345
346.Lnot_return:
347    cmp     r1, #kInterpEntryThrow      @ were we throwing an exception?
348    beq     common_exceptionThrown
349
350#if defined(WITH_JIT)
351.Lnot_throw:
352    ldr     r10,[rSELF, #offThread_jitResumeNPC]
353    ldr     r2,[rSELF, #offThread_jitResumeDPC]
354    cmp     r1, #kInterpEntryResume     @ resuming after Jit single-step?
355    bne     .Lbad_arg
356    cmp     rPC,r2
357    bne     .LentryInstr                @ must have branched, don't resume
358#if defined(WITH_SELF_VERIFICATION)
359    @ self->entryPoint will be set in dvmSelfVerificationSaveState
360    b       jitSVShadowRunStart         @ re-enter the translation after the
361                                        @ single-stepped instruction
362    @noreturn
363#endif
364    mov     r1, #kInterpEntryInstr
365    str     r1, [rSELF, #offThread_entryPoint]
366    bx      r10                         @ re-enter the translation
367#endif
368
369.Lbad_arg:
370    ldr     r0, strBadEntryPoint
371    @ r1 holds value of entryPoint
372    bl      printf
373    bl      dvmAbort
374    .fnend
375    .size   dvmMterpStdRun, .-dvmMterpStdRun
376
377
378    .global dvmMterpStdBail
379    .type   dvmMterpStdBail, %function
380
381/*
382 * Restore the stack pointer and PC from the save point established on entry.
383 * This is essentially the same as a longjmp, but should be cheaper.  The
384 * last instruction causes us to return to whoever called dvmMterpStdRun.
385 *
386 * We pushed some registers on the stack in dvmMterpStdRun, then saved
387 * SP and LR.  Here we restore SP, restore the registers, and then restore
388 * LR to PC.
389 *
390 * On entry:
391 *  r0  Thread* self
392 *  r1  bool changeInterp
393 */
394dvmMterpStdBail:
395    ldr     sp, [r0, #offThread_bailPtr]      @ sp<- saved SP
396    mov     r0, r1                          @ return the changeInterp value
397    add     sp, sp, #4                      @ un-align 64
398    ldmfd   sp!, {r4-r10,fp,pc}             @ restore 9 regs and return
399
400
401/*
402 * String references.
403 */
404strBadEntryPoint:
405    .word   .LstrBadEntryPoint
406
407
408    .global dvmAsmInstructionStart
409    .type   dvmAsmInstructionStart, %function
410dvmAsmInstructionStart = .L_OP_NOP
411    .text
412
413/* ------------------------------ */
414    .balign 64
415.L_OP_NOP: /* 0x00 */
416/* File: armv5te/OP_NOP.S */
417    FETCH_ADVANCE_INST(1)               @ advance to next instr, load rINST
418    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
419    GOTO_OPCODE(ip)                     @ execute it
420
421#ifdef ASSIST_DEBUGGER
422    /* insert fake function header to help gdb find the stack frame */
423    .type   dalvik_inst, %function
424dalvik_inst:
425    .fnstart
426    MTERP_ENTRY1
427    MTERP_ENTRY2
428    .fnend
429#endif
430
431/* ------------------------------ */
432    .balign 64
433.L_OP_MOVE: /* 0x01 */
434/* File: armv6t2/OP_MOVE.S */
435    /* for move, move-object, long-to-int */
436    /* op vA, vB */
437    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
438    ubfx    r0, rINST, #8, #4           @ r0<- A from 11:8
439    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
440    GET_VREG(r2, r1)                    @ r2<- fp[B]
441    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
442    SET_VREG(r2, r0)                    @ fp[A]<- r2
443    GOTO_OPCODE(ip)                     @ execute next instruction
444
445/* ------------------------------ */
446    .balign 64
447.L_OP_MOVE_FROM16: /* 0x02 */
448/* File: armv5te/OP_MOVE_FROM16.S */
449    /* for: move/from16, move-object/from16 */
450    /* op vAA, vBBBB */
451    FETCH(r1, 1)                        @ r1<- BBBB
452    mov     r0, rINST, lsr #8           @ r0<- AA
453    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
454    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
455    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
456    SET_VREG(r2, r0)                    @ fp[AA]<- r2
457    GOTO_OPCODE(ip)                     @ jump to next instruction
458
459/* ------------------------------ */
460    .balign 64
461.L_OP_MOVE_16: /* 0x03 */
462/* File: armv5te/OP_MOVE_16.S */
463    /* for: move/16, move-object/16 */
464    /* op vAAAA, vBBBB */
465    FETCH(r1, 2)                        @ r1<- BBBB
466    FETCH(r0, 1)                        @ r0<- AAAA
467    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
468    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
469    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
470    SET_VREG(r2, r0)                    @ fp[AAAA]<- r2
471    GOTO_OPCODE(ip)                     @ jump to next instruction
472
473/* ------------------------------ */
474    .balign 64
475.L_OP_MOVE_WIDE: /* 0x04 */
476/* File: armv6t2/OP_MOVE_WIDE.S */
477    /* move-wide vA, vB */
478    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
479    mov     r3, rINST, lsr #12          @ r3<- B
480    ubfx    r2, rINST, #8, #4           @ r2<- A
481    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
482    add     r2, rFP, r2, lsl #2         @ r2<- &fp[A]
483    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[B]
484    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
485    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
486    stmia   r2, {r0-r1}                 @ fp[A]<- r0/r1
487    GOTO_OPCODE(ip)                     @ jump to next instruction
488
489/* ------------------------------ */
490    .balign 64
491.L_OP_MOVE_WIDE_FROM16: /* 0x05 */
492/* File: armv5te/OP_MOVE_WIDE_FROM16.S */
493    /* move-wide/from16 vAA, vBBBB */
494    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
495    FETCH(r3, 1)                        @ r3<- BBBB
496    mov     r2, rINST, lsr #8           @ r2<- AA
497    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BBBB]
498    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
499    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[BBBB]
500    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
501    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
502    stmia   r2, {r0-r1}                 @ fp[AA]<- r0/r1
503    GOTO_OPCODE(ip)                     @ jump to next instruction
504
505/* ------------------------------ */
506    .balign 64
507.L_OP_MOVE_WIDE_16: /* 0x06 */
508/* File: armv5te/OP_MOVE_WIDE_16.S */
509    /* move-wide/16 vAAAA, vBBBB */
510    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
511    FETCH(r3, 2)                        @ r3<- BBBB
512    FETCH(r2, 1)                        @ r2<- AAAA
513    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BBBB]
514    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AAAA]
515    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[BBBB]
516    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
517    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
518    stmia   r2, {r0-r1}                 @ fp[AAAA]<- r0/r1
519    GOTO_OPCODE(ip)                     @ jump to next instruction
520
521/* ------------------------------ */
522    .balign 64
523.L_OP_MOVE_OBJECT: /* 0x07 */
524/* File: armv5te/OP_MOVE_OBJECT.S */
525/* File: armv5te/OP_MOVE.S */
526    /* for move, move-object, long-to-int */
527    /* op vA, vB */
528    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
529    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
530    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
531    GET_VREG(r2, r1)                    @ r2<- fp[B]
532    and     r0, r0, #15
533    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
534    SET_VREG(r2, r0)                    @ fp[A]<- r2
535    GOTO_OPCODE(ip)                     @ execute next instruction
536
537
538/* ------------------------------ */
539    .balign 64
540.L_OP_MOVE_OBJECT_FROM16: /* 0x08 */
541/* File: armv5te/OP_MOVE_OBJECT_FROM16.S */
542/* File: armv5te/OP_MOVE_FROM16.S */
543    /* for: move/from16, move-object/from16 */
544    /* op vAA, vBBBB */
545    FETCH(r1, 1)                        @ r1<- BBBB
546    mov     r0, rINST, lsr #8           @ r0<- AA
547    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
548    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
549    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
550    SET_VREG(r2, r0)                    @ fp[AA]<- r2
551    GOTO_OPCODE(ip)                     @ jump to next instruction
552
553
554/* ------------------------------ */
555    .balign 64
556.L_OP_MOVE_OBJECT_16: /* 0x09 */
557/* File: armv5te/OP_MOVE_OBJECT_16.S */
558/* File: armv5te/OP_MOVE_16.S */
559    /* for: move/16, move-object/16 */
560    /* op vAAAA, vBBBB */
561    FETCH(r1, 2)                        @ r1<- BBBB
562    FETCH(r0, 1)                        @ r0<- AAAA
563    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
564    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
565    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
566    SET_VREG(r2, r0)                    @ fp[AAAA]<- r2
567    GOTO_OPCODE(ip)                     @ jump to next instruction
568
569
570/* ------------------------------ */
571    .balign 64
572.L_OP_MOVE_RESULT: /* 0x0a */
573/* File: armv5te/OP_MOVE_RESULT.S */
574    /* for: move-result, move-result-object */
575    /* op vAA */
576    mov     r2, rINST, lsr #8           @ r2<- AA
577    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
578    ldr     r0, [rSELF, #offThread_retval]    @ r0<- self->retval.i
579    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
580    SET_VREG(r0, r2)                    @ fp[AA]<- r0
581    GOTO_OPCODE(ip)                     @ jump to next instruction
582
583/* ------------------------------ */
584    .balign 64
585.L_OP_MOVE_RESULT_WIDE: /* 0x0b */
586/* File: armv5te/OP_MOVE_RESULT_WIDE.S */
587    /* move-result-wide vAA */
588    mov     r2, rINST, lsr #8           @ r2<- AA
589    add     r3, rSELF, #offThread_retval  @ r3<- &self->retval
590    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
591    ldmia   r3, {r0-r1}                 @ r0/r1<- retval.j
592    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
593    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
594    stmia   r2, {r0-r1}                 @ fp[AA]<- r0/r1
595    GOTO_OPCODE(ip)                     @ jump to next instruction
596
597/* ------------------------------ */
598    .balign 64
599.L_OP_MOVE_RESULT_OBJECT: /* 0x0c */
600/* File: armv5te/OP_MOVE_RESULT_OBJECT.S */
601/* File: armv5te/OP_MOVE_RESULT.S */
602    /* for: move-result, move-result-object */
603    /* op vAA */
604    mov     r2, rINST, lsr #8           @ r2<- AA
605    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
606    ldr     r0, [rSELF, #offThread_retval]    @ r0<- self->retval.i
607    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
608    SET_VREG(r0, r2)                    @ fp[AA]<- r0
609    GOTO_OPCODE(ip)                     @ jump to next instruction
610
611
612/* ------------------------------ */
613    .balign 64
614.L_OP_MOVE_EXCEPTION: /* 0x0d */
615/* File: armv5te/OP_MOVE_EXCEPTION.S */
616    /* move-exception vAA */
617    mov     r2, rINST, lsr #8           @ r2<- AA
618    ldr     r3, [rSELF, #offThread_exception]  @ r3<- dvmGetException bypass
619    mov     r1, #0                      @ r1<- 0
620    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
621    SET_VREG(r3, r2)                    @ fp[AA]<- exception obj
622    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
623    str     r1, [rSELF, #offThread_exception]  @ dvmClearException bypass
624    GOTO_OPCODE(ip)                     @ jump to next instruction
625
626/* ------------------------------ */
627    .balign 64
628.L_OP_RETURN_VOID: /* 0x0e */
629/* File: armv5te/OP_RETURN_VOID.S */
630    b       common_returnFromMethod
631
632/* ------------------------------ */
633    .balign 64
634.L_OP_RETURN: /* 0x0f */
635/* File: armv5te/OP_RETURN.S */
636    /*
637     * Return a 32-bit value.  Copies the return value into the "thread"
638     * structure, then jumps to the return handler.
639     *
640     * for: return, return-object
641     */
642    /* op vAA */
643    mov     r2, rINST, lsr #8           @ r2<- AA
644    GET_VREG(r0, r2)                    @ r0<- vAA
645    str     r0, [rSELF, #offThread_retval] @ retval.i <- vAA
646    b       common_returnFromMethod
647
648/* ------------------------------ */
649    .balign 64
650.L_OP_RETURN_WIDE: /* 0x10 */
651/* File: armv5te/OP_RETURN_WIDE.S */
652    /*
653     * Return a 64-bit value.  Copies the return value into the "thread"
654     * structure, then jumps to the return handler.
655     */
656    /* return-wide vAA */
657    mov     r2, rINST, lsr #8           @ r2<- AA
658    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
659    add     r3, rSELF, #offThread_retval  @ r3<- &self->retval
660    ldmia   r2, {r0-r1}                 @ r0/r1 <- vAA/vAA+1
661    stmia   r3, {r0-r1}                 @ retval<- r0/r1
662    b       common_returnFromMethod
663
664/* ------------------------------ */
665    .balign 64
666.L_OP_RETURN_OBJECT: /* 0x11 */
667/* File: armv5te/OP_RETURN_OBJECT.S */
668/* File: armv5te/OP_RETURN.S */
669    /*
670     * Return a 32-bit value.  Copies the return value into the "thread"
671     * structure, then jumps to the return handler.
672     *
673     * for: return, return-object
674     */
675    /* op vAA */
676    mov     r2, rINST, lsr #8           @ r2<- AA
677    GET_VREG(r0, r2)                    @ r0<- vAA
678    str     r0, [rSELF, #offThread_retval] @ retval.i <- vAA
679    b       common_returnFromMethod
680
681
682/* ------------------------------ */
683    .balign 64
684.L_OP_CONST_4: /* 0x12 */
685/* File: armv6t2/OP_CONST_4.S */
686    /* const/4 vA, #+B */
687    mov     r1, rINST, lsl #16          @ r1<- Bxxx0000
688    ubfx    r0, rINST, #8, #4           @ r0<- A
689    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
690    mov     r1, r1, asr #28             @ r1<- sssssssB (sign-extended)
691    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
692    SET_VREG(r1, r0)                    @ fp[A]<- r1
693    GOTO_OPCODE(ip)                     @ execute next instruction
694
695/* ------------------------------ */
696    .balign 64
697.L_OP_CONST_16: /* 0x13 */
698/* File: armv5te/OP_CONST_16.S */
699    /* const/16 vAA, #+BBBB */
700    FETCH_S(r0, 1)                      @ r0<- ssssBBBB (sign-extended)
701    mov     r3, rINST, lsr #8           @ r3<- AA
702    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
703    SET_VREG(r0, r3)                    @ vAA<- r0
704    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
705    GOTO_OPCODE(ip)                     @ jump to next instruction
706
707/* ------------------------------ */
708    .balign 64
709.L_OP_CONST: /* 0x14 */
710/* File: armv5te/OP_CONST.S */
711    /* const vAA, #+BBBBbbbb */
712    mov     r3, rINST, lsr #8           @ r3<- AA
713    FETCH(r0, 1)                        @ r0<- bbbb (low)
714    FETCH(r1, 2)                        @ r1<- BBBB (high)
715    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
716    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
717    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
718    SET_VREG(r0, r3)                    @ vAA<- r0
719    GOTO_OPCODE(ip)                     @ jump to next instruction
720
721/* ------------------------------ */
722    .balign 64
723.L_OP_CONST_HIGH16: /* 0x15 */
724/* File: armv5te/OP_CONST_HIGH16.S */
725    /* const/high16 vAA, #+BBBB0000 */
726    FETCH(r0, 1)                        @ r0<- 0000BBBB (zero-extended)
727    mov     r3, rINST, lsr #8           @ r3<- AA
728    mov     r0, r0, lsl #16             @ r0<- BBBB0000
729    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
730    SET_VREG(r0, r3)                    @ vAA<- r0
731    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
732    GOTO_OPCODE(ip)                     @ jump to next instruction
733
734/* ------------------------------ */
735    .balign 64
736.L_OP_CONST_WIDE_16: /* 0x16 */
737/* File: armv5te/OP_CONST_WIDE_16.S */
738    /* const-wide/16 vAA, #+BBBB */
739    FETCH_S(r0, 1)                      @ r0<- ssssBBBB (sign-extended)
740    mov     r3, rINST, lsr #8           @ r3<- AA
741    mov     r1, r0, asr #31             @ r1<- ssssssss
742    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
743    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
744    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
745    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
746    GOTO_OPCODE(ip)                     @ jump to next instruction
747
748/* ------------------------------ */
749    .balign 64
750.L_OP_CONST_WIDE_32: /* 0x17 */
751/* File: armv5te/OP_CONST_WIDE_32.S */
752    /* const-wide/32 vAA, #+BBBBbbbb */
753    FETCH(r0, 1)                        @ r0<- 0000bbbb (low)
754    mov     r3, rINST, lsr #8           @ r3<- AA
755    FETCH_S(r2, 2)                      @ r2<- ssssBBBB (high)
756    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
757    orr     r0, r0, r2, lsl #16         @ r0<- BBBBbbbb
758    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
759    mov     r1, r0, asr #31             @ r1<- ssssssss
760    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
761    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
762    GOTO_OPCODE(ip)                     @ jump to next instruction
763
764/* ------------------------------ */
765    .balign 64
766.L_OP_CONST_WIDE: /* 0x18 */
767/* File: armv5te/OP_CONST_WIDE.S */
768    /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
769    FETCH(r0, 1)                        @ r0<- bbbb (low)
770    FETCH(r1, 2)                        @ r1<- BBBB (low middle)
771    FETCH(r2, 3)                        @ r2<- hhhh (high middle)
772    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb (low word)
773    FETCH(r3, 4)                        @ r3<- HHHH (high)
774    mov     r9, rINST, lsr #8           @ r9<- AA
775    orr     r1, r2, r3, lsl #16         @ r1<- HHHHhhhh (high word)
776    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
777    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
778    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
779    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
780    GOTO_OPCODE(ip)                     @ jump to next instruction
781
782/* ------------------------------ */
783    .balign 64
784.L_OP_CONST_WIDE_HIGH16: /* 0x19 */
785/* File: armv5te/OP_CONST_WIDE_HIGH16.S */
786    /* const-wide/high16 vAA, #+BBBB000000000000 */
787    FETCH(r1, 1)                        @ r1<- 0000BBBB (zero-extended)
788    mov     r3, rINST, lsr #8           @ r3<- AA
789    mov     r0, #0                      @ r0<- 00000000
790    mov     r1, r1, lsl #16             @ r1<- BBBB0000
791    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
792    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
793    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
794    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
795    GOTO_OPCODE(ip)                     @ jump to next instruction
796
797/* ------------------------------ */
798    .balign 64
799.L_OP_CONST_STRING: /* 0x1a */
800/* File: armv5te/OP_CONST_STRING.S */
801    /* const/string vAA, String@BBBB */
802    FETCH(r1, 1)                        @ r1<- BBBB
803    ldr     r2, [rSELF, #offThread_methodClassDex]  @ r2<- self->methodClassDex
804    mov     r9, rINST, lsr #8           @ r9<- AA
805    ldr     r2, [r2, #offDvmDex_pResStrings]   @ r2<- dvmDex->pResStrings
806    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResStrings[BBBB]
807    cmp     r0, #0                      @ not yet resolved?
808    beq     .LOP_CONST_STRING_resolve
809    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
810    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
811    SET_VREG(r0, r9)                    @ vAA<- r0
812    GOTO_OPCODE(ip)                     @ jump to next instruction
813
814/* ------------------------------ */
815    .balign 64
816.L_OP_CONST_STRING_JUMBO: /* 0x1b */
817/* File: armv5te/OP_CONST_STRING_JUMBO.S */
818    /* const/string vAA, String@BBBBBBBB */
819    FETCH(r0, 1)                        @ r0<- bbbb (low)
820    FETCH(r1, 2)                        @ r1<- BBBB (high)
821    ldr     r2, [rSELF, #offThread_methodClassDex]  @ r2<- self->methodClassDex
822    mov     r9, rINST, lsr #8           @ r9<- AA
823    ldr     r2, [r2, #offDvmDex_pResStrings]   @ r2<- dvmDex->pResStrings
824    orr     r1, r0, r1, lsl #16         @ r1<- BBBBbbbb
825    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResStrings[BBBB]
826    cmp     r0, #0
827    beq     .LOP_CONST_STRING_JUMBO_resolve
828    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
829    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
830    SET_VREG(r0, r9)                    @ vAA<- r0
831    GOTO_OPCODE(ip)                     @ jump to next instruction
832
833/* ------------------------------ */
834    .balign 64
835.L_OP_CONST_CLASS: /* 0x1c */
836/* File: armv5te/OP_CONST_CLASS.S */
837    /* const/class vAA, Class@BBBB */
838    FETCH(r1, 1)                        @ r1<- BBBB
839    ldr     r2, [rSELF, #offThread_methodClassDex]  @ r2<- self->methodClassDex
840    mov     r9, rINST, lsr #8           @ r9<- AA
841    ldr     r2, [r2, #offDvmDex_pResClasses]   @ r2<- dvmDex->pResClasses
842    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResClasses[BBBB]
843    cmp     r0, #0                      @ not yet resolved?
844    beq     .LOP_CONST_CLASS_resolve
845    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
846    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
847    SET_VREG(r0, r9)                    @ vAA<- r0
848    GOTO_OPCODE(ip)                     @ jump to next instruction
849
850/* ------------------------------ */
851    .balign 64
852.L_OP_MONITOR_ENTER: /* 0x1d */
853/* File: armv5te/OP_MONITOR_ENTER.S */
854    /*
855     * Synchronize on an object.
856     */
857    /* monitor-enter vAA */
858    mov     r2, rINST, lsr #8           @ r2<- AA
859    GET_VREG(r1, r2)                    @ r1<- vAA (object)
860    mov     r0, rSELF                   @ r0<- self
861    cmp     r1, #0                      @ null object?
862    EXPORT_PC()                         @ need for precise GC
863    beq     common_errNullObject        @ null object, throw an exception
864    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
865    bl      dvmLockObject               @ call(self, obj)
866    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
867    GOTO_OPCODE(ip)                     @ jump to next instruction
868
869/* ------------------------------ */
870    .balign 64
871.L_OP_MONITOR_EXIT: /* 0x1e */
872/* File: armv5te/OP_MONITOR_EXIT.S */
873    /*
874     * Unlock an object.
875     *
876     * Exceptions that occur when unlocking a monitor need to appear as
877     * if they happened at the following instruction.  See the Dalvik
878     * instruction spec.
879     */
880    /* monitor-exit vAA */
881    mov     r2, rINST, lsr #8           @ r2<- AA
882    EXPORT_PC()                         @ before fetch: export the PC
883    GET_VREG(r1, r2)                    @ r1<- vAA (object)
884    cmp     r1, #0                      @ null object?
885    beq     1f                          @ yes
886    mov     r0, rSELF                   @ r0<- self
887    bl      dvmUnlockObject             @ r0<- success for unlock(self, obj)
888    cmp     r0, #0                      @ failed?
889    FETCH_ADVANCE_INST(1)               @ before throw: advance rPC, load rINST
890    beq     common_exceptionThrown      @ yes, exception is pending
891    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
892    GOTO_OPCODE(ip)                     @ jump to next instruction
8931:
894    FETCH_ADVANCE_INST(1)               @ advance before throw
895    b      common_errNullObject
896
897/* ------------------------------ */
898    .balign 64
899.L_OP_CHECK_CAST: /* 0x1f */
900/* File: armv5te/OP_CHECK_CAST.S */
901    /*
902     * Check to see if a cast from one class to another is allowed.
903     */
904    /* check-cast vAA, class@BBBB */
905    mov     r3, rINST, lsr #8           @ r3<- AA
906    FETCH(r2, 1)                        @ r2<- BBBB
907    GET_VREG(r9, r3)                    @ r9<- object
908    ldr     r0, [rSELF, #offThread_methodClassDex]    @ r0<- pDvmDex
909    cmp     r9, #0                      @ is object null?
910    ldr     r0, [r0, #offDvmDex_pResClasses]    @ r0<- pDvmDex->pResClasses
911    beq     .LOP_CHECK_CAST_okay            @ null obj, cast always succeeds
912    ldr     r1, [r0, r2, lsl #2]        @ r1<- resolved class
913    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
914    cmp     r1, #0                      @ have we resolved this before?
915    beq     .LOP_CHECK_CAST_resolve         @ not resolved, do it now
916.LOP_CHECK_CAST_resolved:
917    cmp     r0, r1                      @ same class (trivial success)?
918    bne     .LOP_CHECK_CAST_fullcheck       @ no, do full check
919.LOP_CHECK_CAST_okay:
920    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
921    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
922    GOTO_OPCODE(ip)                     @ jump to next instruction
923
924/* ------------------------------ */
925    .balign 64
926.L_OP_INSTANCE_OF: /* 0x20 */
927/* File: armv5te/OP_INSTANCE_OF.S */
928    /*
929     * Check to see if an object reference is an instance of a class.
930     *
931     * Most common situation is a non-null object, being compared against
932     * an already-resolved class.
933     */
934    /* instance-of vA, vB, class@CCCC */
935    mov     r3, rINST, lsr #12          @ r3<- B
936    mov     r9, rINST, lsr #8           @ r9<- A+
937    GET_VREG(r0, r3)                    @ r0<- vB (object)
938    and     r9, r9, #15                 @ r9<- A
939    cmp     r0, #0                      @ is object null?
940    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- pDvmDex
941    beq     .LOP_INSTANCE_OF_store           @ null obj, not an instance, store r0
942    FETCH(r3, 1)                        @ r3<- CCCC
943    ldr     r2, [r2, #offDvmDex_pResClasses]    @ r2<- pDvmDex->pResClasses
944    ldr     r1, [r2, r3, lsl #2]        @ r1<- resolved class
945    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
946    cmp     r1, #0                      @ have we resolved this before?
947    beq     .LOP_INSTANCE_OF_resolve         @ not resolved, do it now
948.LOP_INSTANCE_OF_resolved: @ r0=obj->clazz, r1=resolved class
949    cmp     r0, r1                      @ same class (trivial success)?
950    beq     .LOP_INSTANCE_OF_trivial         @ yes, trivial finish
951    b       .LOP_INSTANCE_OF_fullcheck       @ no, do full check
952
953/* ------------------------------ */
954    .balign 64
955.L_OP_ARRAY_LENGTH: /* 0x21 */
956/* File: armv6t2/OP_ARRAY_LENGTH.S */
957    /*
958     * Return the length of an array.
959     */
960    mov     r1, rINST, lsr #12          @ r1<- B
961    ubfx    r2, rINST, #8, #4           @ r2<- A
962    GET_VREG(r0, r1)                    @ r0<- vB (object ref)
963    cmp     r0, #0                      @ is object null?
964    beq     common_errNullObject        @ yup, fail
965    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
966    ldr     r3, [r0, #offArrayObject_length]    @ r3<- array length
967    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
968    SET_VREG(r3, r2)                    @ vB<- length
969    GOTO_OPCODE(ip)                     @ jump to next instruction
970
971/* ------------------------------ */
972    .balign 64
973.L_OP_NEW_INSTANCE: /* 0x22 */
974/* File: armv5te/OP_NEW_INSTANCE.S */
975    /*
976     * Create a new instance of a class.
977     */
978    /* new-instance vAA, class@BBBB */
979    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
980    FETCH(r1, 1)                        @ r1<- BBBB
981    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
982    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
983    EXPORT_PC()                         @ req'd for init, resolve, alloc
984    cmp     r0, #0                      @ already resolved?
985    beq     .LOP_NEW_INSTANCE_resolve         @ no, resolve it now
986.LOP_NEW_INSTANCE_resolved:   @ r0=class
987    ldrb    r1, [r0, #offClassObject_status]    @ r1<- ClassStatus enum
988    cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
989    bne     .LOP_NEW_INSTANCE_needinit        @ no, init class now
990.LOP_NEW_INSTANCE_initialized: @ r0=class
991    mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
992    bl      dvmAllocObject              @ r0<- new object
993    b       .LOP_NEW_INSTANCE_finish          @ continue
994
995/* ------------------------------ */
996    .balign 64
997.L_OP_NEW_ARRAY: /* 0x23 */
998/* File: armv5te/OP_NEW_ARRAY.S */
999    /*
1000     * Allocate an array of objects, specified with the array class
1001     * and a count.
1002     *
1003     * The verifier guarantees that this is an array class, so we don't
1004     * check for it here.
1005     */
1006    /* new-array vA, vB, class@CCCC */
1007    mov     r0, rINST, lsr #12          @ r0<- B
1008    FETCH(r2, 1)                        @ r2<- CCCC
1009    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
1010    GET_VREG(r1, r0)                    @ r1<- vB (array length)
1011    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1012    cmp     r1, #0                      @ check length
1013    ldr     r0, [r3, r2, lsl #2]        @ r0<- resolved class
1014    bmi     common_errNegativeArraySize @ negative length, bail - len in r1
1015    cmp     r0, #0                      @ already resolved?
1016    EXPORT_PC()                         @ req'd for resolve, alloc
1017    bne     .LOP_NEW_ARRAY_finish          @ resolved, continue
1018    b       .LOP_NEW_ARRAY_resolve         @ do resolve now
1019
1020/* ------------------------------ */
1021    .balign 64
1022.L_OP_FILLED_NEW_ARRAY: /* 0x24 */
1023/* File: armv5te/OP_FILLED_NEW_ARRAY.S */
1024    /*
1025     * Create a new array with elements filled from registers.
1026     *
1027     * for: filled-new-array, filled-new-array/range
1028     */
1029    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1030    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1031    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
1032    FETCH(r1, 1)                        @ r1<- BBBB
1033    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1034    EXPORT_PC()                         @ need for resolve and alloc
1035    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
1036    mov     r10, rINST, lsr #8          @ r10<- AA or BA
1037    cmp     r0, #0                      @ already resolved?
1038    bne     .LOP_FILLED_NEW_ARRAY_continue        @ yes, continue on
10398:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
1040    mov     r2, #0                      @ r2<- false
1041    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
1042    bl      dvmResolveClass             @ r0<- call(clazz, ref)
1043    cmp     r0, #0                      @ got null?
1044    beq     common_exceptionThrown      @ yes, handle exception
1045    b       .LOP_FILLED_NEW_ARRAY_continue
1046
1047/* ------------------------------ */
1048    .balign 64
1049.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
1050/* File: armv5te/OP_FILLED_NEW_ARRAY_RANGE.S */
1051/* File: armv5te/OP_FILLED_NEW_ARRAY.S */
1052    /*
1053     * Create a new array with elements filled from registers.
1054     *
1055     * for: filled-new-array, filled-new-array/range
1056     */
1057    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1058    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1059    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
1060    FETCH(r1, 1)                        @ r1<- BBBB
1061    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1062    EXPORT_PC()                         @ need for resolve and alloc
1063    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
1064    mov     r10, rINST, lsr #8          @ r10<- AA or BA
1065    cmp     r0, #0                      @ already resolved?
1066    bne     .LOP_FILLED_NEW_ARRAY_RANGE_continue        @ yes, continue on
10678:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
1068    mov     r2, #0                      @ r2<- false
1069    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
1070    bl      dvmResolveClass             @ r0<- call(clazz, ref)
1071    cmp     r0, #0                      @ got null?
1072    beq     common_exceptionThrown      @ yes, handle exception
1073    b       .LOP_FILLED_NEW_ARRAY_RANGE_continue
1074
1075
1076/* ------------------------------ */
1077    .balign 64
1078.L_OP_FILL_ARRAY_DATA: /* 0x26 */
1079/* File: armv5te/OP_FILL_ARRAY_DATA.S */
1080    /* fill-array-data vAA, +BBBBBBBB */
1081    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1082    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1083    mov     r3, rINST, lsr #8           @ r3<- AA
1084    orr     r1, r0, r1, lsl #16         @ r1<- BBBBbbbb
1085    GET_VREG(r0, r3)                    @ r0<- vAA (array object)
1086    add     r1, rPC, r1, lsl #1         @ r1<- PC + BBBBbbbb*2 (array data off.)
1087    EXPORT_PC();
1088    bl      dvmInterpHandleFillArrayData@ fill the array with predefined data
1089    cmp     r0, #0                      @ 0 means an exception is thrown
1090    beq     common_exceptionThrown      @ has exception
1091    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
1092    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1093    GOTO_OPCODE(ip)                     @ jump to next instruction
1094
1095/* ------------------------------ */
1096    .balign 64
1097.L_OP_THROW: /* 0x27 */
1098/* File: armv5te/OP_THROW.S */
1099    /*
1100     * Throw an exception object in the current thread.
1101     */
1102    /* throw vAA */
1103    mov     r2, rINST, lsr #8           @ r2<- AA
1104    GET_VREG(r1, r2)                    @ r1<- vAA (exception object)
1105    EXPORT_PC()                         @ exception handler can throw
1106    cmp     r1, #0                      @ null object?
1107    beq     common_errNullObject        @ yes, throw an NPE instead
1108    @ bypass dvmSetException, just store it
1109    str     r1, [rSELF, #offThread_exception]  @ thread->exception<- obj
1110    b       common_exceptionThrown
1111
1112/* ------------------------------ */
1113    .balign 64
1114.L_OP_GOTO: /* 0x28 */
1115/* File: armv5te/OP_GOTO.S */
1116    /*
1117     * Unconditional branch, 8-bit offset.
1118     *
1119     * The branch distance is a signed code-unit offset, which we need to
1120     * double to get a byte offset.
1121     */
1122    /* goto +AA */
1123    mov     r0, rINST, lsl #16          @ r0<- AAxx0000
1124    movs    r9, r0, asr #24             @ r9<- ssssssAA (sign-extended)
1125    mov     r9, r9, lsl #1              @ r9<- byte offset
1126    bmi     common_backwardBranch       @ backward branch, do periodic checks
1127#if defined(WITH_JIT)
1128    GET_JIT_PROF_TABLE(r0)
1129    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1130    cmp     r0,#0
1131    bne     common_updateProfile
1132    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1133    GOTO_OPCODE(ip)                     @ jump to next instruction
1134#else
1135    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1136    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1137    GOTO_OPCODE(ip)                     @ jump to next instruction
1138#endif
1139
1140/* ------------------------------ */
1141    .balign 64
1142.L_OP_GOTO_16: /* 0x29 */
1143/* File: armv5te/OP_GOTO_16.S */
1144    /*
1145     * Unconditional branch, 16-bit offset.
1146     *
1147     * The branch distance is a signed code-unit offset, which we need to
1148     * double to get a byte offset.
1149     */
1150    /* goto/16 +AAAA */
1151    FETCH_S(r0, 1)                      @ r0<- ssssAAAA (sign-extended)
1152    movs    r9, r0, asl #1              @ r9<- byte offset, check sign
1153    bmi     common_backwardBranch       @ backward branch, do periodic checks
1154#if defined(WITH_JIT)
1155    GET_JIT_PROF_TABLE(r0)
1156    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1157    cmp     r0,#0
1158    bne     common_updateProfile
1159    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1160    GOTO_OPCODE(ip)                     @ jump to next instruction
1161#else
1162    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1163    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1164    GOTO_OPCODE(ip)                     @ jump to next instruction
1165#endif
1166
1167/* ------------------------------ */
1168    .balign 64
1169.L_OP_GOTO_32: /* 0x2a */
1170/* File: armv5te/OP_GOTO_32.S */
1171    /*
1172     * Unconditional branch, 32-bit offset.
1173     *
1174     * The branch distance is a signed code-unit offset, which we need to
1175     * double to get a byte offset.
1176     *
1177     * Unlike most opcodes, this one is allowed to branch to itself, so
1178     * our "backward branch" test must be "<=0" instead of "<0".  The ORRS
1179     * instruction doesn't affect the V flag, so we need to clear it
1180     * explicitly.
1181     */
1182    /* goto/32 +AAAAAAAA */
1183    FETCH(r0, 1)                        @ r0<- aaaa (lo)
1184    FETCH(r1, 2)                        @ r1<- AAAA (hi)
1185    cmp     ip, ip                      @ (clear V flag during stall)
1186    orrs    r0, r0, r1, lsl #16         @ r0<- AAAAaaaa, check sign
1187    mov     r9, r0, asl #1              @ r9<- byte offset
1188    ble     common_backwardBranch       @ backward branch, do periodic checks
1189#if defined(WITH_JIT)
1190    GET_JIT_PROF_TABLE(r0)
1191    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1192    cmp     r0,#0
1193    bne     common_updateProfile
1194    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1195    GOTO_OPCODE(ip)                     @ jump to next instruction
1196#else
1197    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1198    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1199    GOTO_OPCODE(ip)                     @ jump to next instruction
1200#endif
1201
1202/* ------------------------------ */
1203    .balign 64
1204.L_OP_PACKED_SWITCH: /* 0x2b */
1205/* File: armv5te/OP_PACKED_SWITCH.S */
1206    /*
1207     * Handle a packed-switch or sparse-switch instruction.  In both cases
1208     * we decode it and hand it off to a helper function.
1209     *
1210     * We don't really expect backward branches in a switch statement, but
1211     * they're perfectly legal, so we check for them here.
1212     *
1213     * for: packed-switch, sparse-switch
1214     */
1215    /* op vAA, +BBBB */
1216    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1217    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1218    mov     r3, rINST, lsr #8           @ r3<- AA
1219    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
1220    GET_VREG(r1, r3)                    @ r1<- vAA
1221    add     r0, rPC, r0, lsl #1         @ r0<- PC + BBBBbbbb*2
1222    bl      dvmInterpHandlePackedSwitch                       @ r0<- code-unit branch offset
1223    movs    r9, r0, asl #1              @ r9<- branch byte offset, check sign
1224    bmi     common_backwardBranch       @ backward branch, do periodic checks
1225    beq     common_backwardBranch       @ (want to use BLE but V is unknown)
1226#if defined(WITH_JIT)
1227    GET_JIT_PROF_TABLE(r0)
1228    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1229    cmp     r0,#0
1230    bne     common_updateProfile
1231    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1232    GOTO_OPCODE(ip)                     @ jump to next instruction
1233#else
1234    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1235    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1236    GOTO_OPCODE(ip)                     @ jump to next instruction
1237#endif
1238
1239/* ------------------------------ */
1240    .balign 64
1241.L_OP_SPARSE_SWITCH: /* 0x2c */
1242/* File: armv5te/OP_SPARSE_SWITCH.S */
1243/* File: armv5te/OP_PACKED_SWITCH.S */
1244    /*
1245     * Handle a packed-switch or sparse-switch instruction.  In both cases
1246     * we decode it and hand it off to a helper function.
1247     *
1248     * We don't really expect backward branches in a switch statement, but
1249     * they're perfectly legal, so we check for them here.
1250     *
1251     * for: packed-switch, sparse-switch
1252     */
1253    /* op vAA, +BBBB */
1254    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1255    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1256    mov     r3, rINST, lsr #8           @ r3<- AA
1257    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
1258    GET_VREG(r1, r3)                    @ r1<- vAA
1259    add     r0, rPC, r0, lsl #1         @ r0<- PC + BBBBbbbb*2
1260    bl      dvmInterpHandleSparseSwitch                       @ r0<- code-unit branch offset
1261    movs    r9, r0, asl #1              @ r9<- branch byte offset, check sign
1262    bmi     common_backwardBranch       @ backward branch, do periodic checks
1263    beq     common_backwardBranch       @ (want to use BLE but V is unknown)
1264#if defined(WITH_JIT)
1265    GET_JIT_PROF_TABLE(r0)
1266    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1267    cmp     r0,#0
1268    bne     common_updateProfile
1269    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1270    GOTO_OPCODE(ip)                     @ jump to next instruction
1271#else
1272    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1273    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1274    GOTO_OPCODE(ip)                     @ jump to next instruction
1275#endif
1276
1277
1278/* ------------------------------ */
1279    .balign 64
1280.L_OP_CMPL_FLOAT: /* 0x2d */
1281/* File: arm-vfp/OP_CMPL_FLOAT.S */
1282    /*
1283     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1284     * destination register based on the results of the comparison.
1285     *
1286     * int compare(x, y) {
1287     *     if (x == y) {
1288     *         return 0;
1289     *     } else if (x > y) {
1290     *         return 1;
1291     *     } else if (x < y) {
1292     *         return -1;
1293     *     } else {
1294     *         return -1;
1295     *     }
1296     * }
1297     */
1298    /* op vAA, vBB, vCC */
1299    FETCH(r0, 1)                        @ r0<- CCBB
1300    mov     r9, rINST, lsr #8           @ r9<- AA
1301    and     r2, r0, #255                @ r2<- BB
1302    mov     r3, r0, lsr #8              @ r3<- CC
1303    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1304    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1305    flds    s0, [r2]                    @ s0<- vBB
1306    flds    s1, [r3]                    @ s1<- vCC
1307    fcmpes  s0, s1                      @ compare (vBB, vCC)
1308    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1309    mvn     r0, #0                      @ r0<- -1 (default)
1310    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1311    fmstat                              @ export status flags
1312    movgt   r0, #1                      @ (greater than) r1<- 1
1313    moveq   r0, #0                      @ (equal) r1<- 0
1314    b       .LOP_CMPL_FLOAT_finish          @ argh
1315
1316
1317/* ------------------------------ */
1318    .balign 64
1319.L_OP_CMPG_FLOAT: /* 0x2e */
1320/* File: arm-vfp/OP_CMPG_FLOAT.S */
1321    /*
1322     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1323     * destination register based on the results of the comparison.
1324     *
1325     * int compare(x, y) {
1326     *     if (x == y) {
1327     *         return 0;
1328     *     } else if (x < y) {
1329     *         return -1;
1330     *     } else if (x > y) {
1331     *         return 1;
1332     *     } else {
1333     *         return 1;
1334     *     }
1335     * }
1336     */
1337    /* op vAA, vBB, vCC */
1338    FETCH(r0, 1)                        @ r0<- CCBB
1339    mov     r9, rINST, lsr #8           @ r9<- AA
1340    and     r2, r0, #255                @ r2<- BB
1341    mov     r3, r0, lsr #8              @ r3<- CC
1342    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1343    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1344    flds    s0, [r2]                    @ s0<- vBB
1345    flds    s1, [r3]                    @ s1<- vCC
1346    fcmpes  s0, s1                      @ compare (vBB, vCC)
1347    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1348    mov     r0, #1                      @ r0<- 1 (default)
1349    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1350    fmstat                              @ export status flags
1351    mvnmi   r0, #0                      @ (less than) r1<- -1
1352    moveq   r0, #0                      @ (equal) r1<- 0
1353    b       .LOP_CMPG_FLOAT_finish          @ argh
1354
1355
1356/* ------------------------------ */
1357    .balign 64
1358.L_OP_CMPL_DOUBLE: /* 0x2f */
1359/* File: arm-vfp/OP_CMPL_DOUBLE.S */
1360    /*
1361     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1362     * destination register based on the results of the comparison.
1363     *
1364     * int compare(x, y) {
1365     *     if (x == y) {
1366     *         return 0;
1367     *     } else if (x > y) {
1368     *         return 1;
1369     *     } else if (x < y) {
1370     *         return -1;
1371     *     } else {
1372     *         return -1;
1373     *     }
1374     * }
1375     */
1376    /* op vAA, vBB, vCC */
1377    FETCH(r0, 1)                        @ r0<- CCBB
1378    mov     r9, rINST, lsr #8           @ r9<- AA
1379    and     r2, r0, #255                @ r2<- BB
1380    mov     r3, r0, lsr #8              @ r3<- CC
1381    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1382    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1383    fldd    d0, [r2]                    @ d0<- vBB
1384    fldd    d1, [r3]                    @ d1<- vCC
1385    fcmped  d0, d1                      @ compare (vBB, vCC)
1386    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1387    mvn     r0, #0                      @ r0<- -1 (default)
1388    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1389    fmstat                              @ export status flags
1390    movgt   r0, #1                      @ (greater than) r1<- 1
1391    moveq   r0, #0                      @ (equal) r1<- 0
1392    b       .LOP_CMPL_DOUBLE_finish          @ argh
1393
1394
1395/* ------------------------------ */
1396    .balign 64
1397.L_OP_CMPG_DOUBLE: /* 0x30 */
1398/* File: arm-vfp/OP_CMPG_DOUBLE.S */
1399    /*
1400     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1401     * destination register based on the results of the comparison.
1402     *
1403     * int compare(x, y) {
1404     *     if (x == y) {
1405     *         return 0;
1406     *     } else if (x < y) {
1407     *         return -1;
1408     *     } else if (x > y) {
1409     *         return 1;
1410     *     } else {
1411     *         return 1;
1412     *     }
1413     * }
1414     */
1415    /* op vAA, vBB, vCC */
1416    FETCH(r0, 1)                        @ r0<- CCBB
1417    mov     r9, rINST, lsr #8           @ r9<- AA
1418    and     r2, r0, #255                @ r2<- BB
1419    mov     r3, r0, lsr #8              @ r3<- CC
1420    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1421    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1422    fldd    d0, [r2]                    @ d0<- vBB
1423    fldd    d1, [r3]                    @ d1<- vCC
1424    fcmped  d0, d1                      @ compare (vBB, vCC)
1425    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1426    mov     r0, #1                      @ r0<- 1 (default)
1427    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1428    fmstat                              @ export status flags
1429    mvnmi   r0, #0                      @ (less than) r1<- -1
1430    moveq   r0, #0                      @ (equal) r1<- 0
1431    b       .LOP_CMPG_DOUBLE_finish          @ argh
1432
1433
1434/* ------------------------------ */
1435    .balign 64
1436.L_OP_CMP_LONG: /* 0x31 */
1437/* File: armv5te/OP_CMP_LONG.S */
1438    /*
1439     * Compare two 64-bit values.  Puts 0, 1, or -1 into the destination
1440     * register based on the results of the comparison.
1441     *
1442     * We load the full values with LDM, but in practice many values could
1443     * be resolved by only looking at the high word.  This could be made
1444     * faster or slower by splitting the LDM into a pair of LDRs.
1445     *
1446     * If we just wanted to set condition flags, we could do this:
1447     *  subs    ip, r0, r2
1448     *  sbcs    ip, r1, r3
1449     *  subeqs  ip, r0, r2
1450     * Leaving { <0, 0, >0 } in ip.  However, we have to set it to a specific
1451     * integer value, which we can do with 2 conditional mov/mvn instructions
1452     * (set 1, set -1; if they're equal we already have 0 in ip), giving
1453     * us a constant 5-cycle path plus a branch at the end to the
1454     * instruction epilogue code.  The multi-compare approach below needs
1455     * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch
1456     * in the worst case (the 64-bit values are equal).
1457     */
1458    /* cmp-long vAA, vBB, vCC */
1459    FETCH(r0, 1)                        @ r0<- CCBB
1460    mov     r9, rINST, lsr #8           @ r9<- AA
1461    and     r2, r0, #255                @ r2<- BB
1462    mov     r3, r0, lsr #8              @ r3<- CC
1463    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
1464    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
1465    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
1466    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
1467    cmp     r1, r3                      @ compare (vBB+1, vCC+1)
1468    blt     .LOP_CMP_LONG_less            @ signed compare on high part
1469    bgt     .LOP_CMP_LONG_greater
1470    subs    r1, r0, r2                  @ r1<- r0 - r2
1471    bhi     .LOP_CMP_LONG_greater         @ unsigned compare on low part
1472    bne     .LOP_CMP_LONG_less
1473    b       .LOP_CMP_LONG_finish          @ equal; r1 already holds 0
1474
1475/* ------------------------------ */
1476    .balign 64
1477.L_OP_IF_EQ: /* 0x32 */
1478/* File: armv6t2/OP_IF_EQ.S */
1479/* File: armv6t2/bincmp.S */
1480    /*
1481     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1482     * fragment that specifies the *reverse* comparison to perform, e.g.
1483     * for "if-le" you would use "gt".
1484     *
1485     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1486     */
1487    /* if-cmp vA, vB, +CCCC */
1488    mov     r1, rINST, lsr #12          @ r1<- B
1489    ubfx    r0, rINST, #8, #4           @ r0<- A
1490    GET_VREG(r3, r1)                    @ r3<- vB
1491    GET_VREG(r2, r0)                    @ r2<- vA
1492    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1493    cmp     r2, r3                      @ compare (vA, vB)
1494    bne  1f                      @ branch to 1 if comparison failed
1495    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1496    movs    r9, r9, asl #1              @ convert to bytes, check sign
1497    bmi     common_backwardBranch       @ yes, do periodic checks
14981:
1499#if defined(WITH_JIT)
1500    GET_JIT_PROF_TABLE(r0)
1501    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1502    b        common_testUpdateProfile
1503#else
1504    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1505    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1506    GOTO_OPCODE(ip)                     @ jump to next instruction
1507#endif
1508
1509
1510/* ------------------------------ */
1511    .balign 64
1512.L_OP_IF_NE: /* 0x33 */
1513/* File: armv6t2/OP_IF_NE.S */
1514/* File: armv6t2/bincmp.S */
1515    /*
1516     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1517     * fragment that specifies the *reverse* comparison to perform, e.g.
1518     * for "if-le" you would use "gt".
1519     *
1520     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1521     */
1522    /* if-cmp vA, vB, +CCCC */
1523    mov     r1, rINST, lsr #12          @ r1<- B
1524    ubfx    r0, rINST, #8, #4           @ r0<- A
1525    GET_VREG(r3, r1)                    @ r3<- vB
1526    GET_VREG(r2, r0)                    @ r2<- vA
1527    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1528    cmp     r2, r3                      @ compare (vA, vB)
1529    beq  1f                      @ branch to 1 if comparison failed
1530    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1531    movs    r9, r9, asl #1              @ convert to bytes, check sign
1532    bmi     common_backwardBranch       @ yes, do periodic checks
15331:
1534#if defined(WITH_JIT)
1535    GET_JIT_PROF_TABLE(r0)
1536    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1537    b        common_testUpdateProfile
1538#else
1539    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1540    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1541    GOTO_OPCODE(ip)                     @ jump to next instruction
1542#endif
1543
1544
1545/* ------------------------------ */
1546    .balign 64
1547.L_OP_IF_LT: /* 0x34 */
1548/* File: armv6t2/OP_IF_LT.S */
1549/* File: armv6t2/bincmp.S */
1550    /*
1551     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1552     * fragment that specifies the *reverse* comparison to perform, e.g.
1553     * for "if-le" you would use "gt".
1554     *
1555     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1556     */
1557    /* if-cmp vA, vB, +CCCC */
1558    mov     r1, rINST, lsr #12          @ r1<- B
1559    ubfx    r0, rINST, #8, #4           @ r0<- A
1560    GET_VREG(r3, r1)                    @ r3<- vB
1561    GET_VREG(r2, r0)                    @ r2<- vA
1562    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1563    cmp     r2, r3                      @ compare (vA, vB)
1564    bge  1f                      @ branch to 1 if comparison failed
1565    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1566    movs    r9, r9, asl #1              @ convert to bytes, check sign
1567    bmi     common_backwardBranch       @ yes, do periodic checks
15681:
1569#if defined(WITH_JIT)
1570    GET_JIT_PROF_TABLE(r0)
1571    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1572    b        common_testUpdateProfile
1573#else
1574    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1575    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1576    GOTO_OPCODE(ip)                     @ jump to next instruction
1577#endif
1578
1579
1580/* ------------------------------ */
1581    .balign 64
1582.L_OP_IF_GE: /* 0x35 */
1583/* File: armv6t2/OP_IF_GE.S */
1584/* File: armv6t2/bincmp.S */
1585    /*
1586     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1587     * fragment that specifies the *reverse* comparison to perform, e.g.
1588     * for "if-le" you would use "gt".
1589     *
1590     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1591     */
1592    /* if-cmp vA, vB, +CCCC */
1593    mov     r1, rINST, lsr #12          @ r1<- B
1594    ubfx    r0, rINST, #8, #4           @ r0<- A
1595    GET_VREG(r3, r1)                    @ r3<- vB
1596    GET_VREG(r2, r0)                    @ r2<- vA
1597    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1598    cmp     r2, r3                      @ compare (vA, vB)
1599    blt  1f                      @ branch to 1 if comparison failed
1600    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1601    movs    r9, r9, asl #1              @ convert to bytes, check sign
1602    bmi     common_backwardBranch       @ yes, do periodic checks
16031:
1604#if defined(WITH_JIT)
1605    GET_JIT_PROF_TABLE(r0)
1606    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1607    b        common_testUpdateProfile
1608#else
1609    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1610    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1611    GOTO_OPCODE(ip)                     @ jump to next instruction
1612#endif
1613
1614
1615/* ------------------------------ */
1616    .balign 64
1617.L_OP_IF_GT: /* 0x36 */
1618/* File: armv6t2/OP_IF_GT.S */
1619/* File: armv6t2/bincmp.S */
1620    /*
1621     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1622     * fragment that specifies the *reverse* comparison to perform, e.g.
1623     * for "if-le" you would use "gt".
1624     *
1625     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1626     */
1627    /* if-cmp vA, vB, +CCCC */
1628    mov     r1, rINST, lsr #12          @ r1<- B
1629    ubfx    r0, rINST, #8, #4           @ r0<- A
1630    GET_VREG(r3, r1)                    @ r3<- vB
1631    GET_VREG(r2, r0)                    @ r2<- vA
1632    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1633    cmp     r2, r3                      @ compare (vA, vB)
1634    ble  1f                      @ branch to 1 if comparison failed
1635    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1636    movs    r9, r9, asl #1              @ convert to bytes, check sign
1637    bmi     common_backwardBranch       @ yes, do periodic checks
16381:
1639#if defined(WITH_JIT)
1640    GET_JIT_PROF_TABLE(r0)
1641    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1642    b        common_testUpdateProfile
1643#else
1644    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1645    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1646    GOTO_OPCODE(ip)                     @ jump to next instruction
1647#endif
1648
1649
1650/* ------------------------------ */
1651    .balign 64
1652.L_OP_IF_LE: /* 0x37 */
1653/* File: armv6t2/OP_IF_LE.S */
1654/* File: armv6t2/bincmp.S */
1655    /*
1656     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1657     * fragment that specifies the *reverse* comparison to perform, e.g.
1658     * for "if-le" you would use "gt".
1659     *
1660     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1661     */
1662    /* if-cmp vA, vB, +CCCC */
1663    mov     r1, rINST, lsr #12          @ r1<- B
1664    ubfx    r0, rINST, #8, #4           @ r0<- A
1665    GET_VREG(r3, r1)                    @ r3<- vB
1666    GET_VREG(r2, r0)                    @ r2<- vA
1667    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1668    cmp     r2, r3                      @ compare (vA, vB)
1669    bgt  1f                      @ branch to 1 if comparison failed
1670    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1671    movs    r9, r9, asl #1              @ convert to bytes, check sign
1672    bmi     common_backwardBranch       @ yes, do periodic checks
16731:
1674#if defined(WITH_JIT)
1675    GET_JIT_PROF_TABLE(r0)
1676    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1677    b        common_testUpdateProfile
1678#else
1679    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1680    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1681    GOTO_OPCODE(ip)                     @ jump to next instruction
1682#endif
1683
1684
1685/* ------------------------------ */
1686    .balign 64
1687.L_OP_IF_EQZ: /* 0x38 */
1688/* File: armv5te/OP_IF_EQZ.S */
1689/* File: armv5te/zcmp.S */
1690    /*
1691     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1692     * fragment that specifies the *reverse* comparison to perform, e.g.
1693     * for "if-le" you would use "gt".
1694     *
1695     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1696     */
1697    /* if-cmp vAA, +BBBB */
1698    mov     r0, rINST, lsr #8           @ r0<- AA
1699    GET_VREG(r2, r0)                    @ r2<- vAA
1700    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1701    cmp     r2, #0                      @ compare (vA, 0)
1702    bne  1f                      @ branch to 1 if comparison failed
1703    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1704    movs    r9, r9, asl #1              @ convert to bytes, check sign
1705    bmi     common_backwardBranch       @ backward branch, do periodic checks
17061:
1707#if defined(WITH_JIT)
1708    GET_JIT_PROF_TABLE(r0)
1709    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1710    cmp     r0,#0
1711    bne     common_updateProfile
1712    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1713    GOTO_OPCODE(ip)                     @ jump to next instruction
1714#else
1715    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1716    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1717    GOTO_OPCODE(ip)                     @ jump to next instruction
1718#endif
1719
1720
1721/* ------------------------------ */
1722    .balign 64
1723.L_OP_IF_NEZ: /* 0x39 */
1724/* File: armv5te/OP_IF_NEZ.S */
1725/* File: armv5te/zcmp.S */
1726    /*
1727     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1728     * fragment that specifies the *reverse* comparison to perform, e.g.
1729     * for "if-le" you would use "gt".
1730     *
1731     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1732     */
1733    /* if-cmp vAA, +BBBB */
1734    mov     r0, rINST, lsr #8           @ r0<- AA
1735    GET_VREG(r2, r0)                    @ r2<- vAA
1736    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1737    cmp     r2, #0                      @ compare (vA, 0)
1738    beq  1f                      @ branch to 1 if comparison failed
1739    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1740    movs    r9, r9, asl #1              @ convert to bytes, check sign
1741    bmi     common_backwardBranch       @ backward branch, do periodic checks
17421:
1743#if defined(WITH_JIT)
1744    GET_JIT_PROF_TABLE(r0)
1745    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1746    cmp     r0,#0
1747    bne     common_updateProfile
1748    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1749    GOTO_OPCODE(ip)                     @ jump to next instruction
1750#else
1751    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1752    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1753    GOTO_OPCODE(ip)                     @ jump to next instruction
1754#endif
1755
1756
1757/* ------------------------------ */
1758    .balign 64
1759.L_OP_IF_LTZ: /* 0x3a */
1760/* File: armv5te/OP_IF_LTZ.S */
1761/* File: armv5te/zcmp.S */
1762    /*
1763     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1764     * fragment that specifies the *reverse* comparison to perform, e.g.
1765     * for "if-le" you would use "gt".
1766     *
1767     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1768     */
1769    /* if-cmp vAA, +BBBB */
1770    mov     r0, rINST, lsr #8           @ r0<- AA
1771    GET_VREG(r2, r0)                    @ r2<- vAA
1772    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1773    cmp     r2, #0                      @ compare (vA, 0)
1774    bge  1f                      @ branch to 1 if comparison failed
1775    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1776    movs    r9, r9, asl #1              @ convert to bytes, check sign
1777    bmi     common_backwardBranch       @ backward branch, do periodic checks
17781:
1779#if defined(WITH_JIT)
1780    GET_JIT_PROF_TABLE(r0)
1781    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1782    cmp     r0,#0
1783    bne     common_updateProfile
1784    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1785    GOTO_OPCODE(ip)                     @ jump to next instruction
1786#else
1787    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1788    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1789    GOTO_OPCODE(ip)                     @ jump to next instruction
1790#endif
1791
1792
1793/* ------------------------------ */
1794    .balign 64
1795.L_OP_IF_GEZ: /* 0x3b */
1796/* File: armv5te/OP_IF_GEZ.S */
1797/* File: armv5te/zcmp.S */
1798    /*
1799     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1800     * fragment that specifies the *reverse* comparison to perform, e.g.
1801     * for "if-le" you would use "gt".
1802     *
1803     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1804     */
1805    /* if-cmp vAA, +BBBB */
1806    mov     r0, rINST, lsr #8           @ r0<- AA
1807    GET_VREG(r2, r0)                    @ r2<- vAA
1808    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1809    cmp     r2, #0                      @ compare (vA, 0)
1810    blt  1f                      @ branch to 1 if comparison failed
1811    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1812    movs    r9, r9, asl #1              @ convert to bytes, check sign
1813    bmi     common_backwardBranch       @ backward branch, do periodic checks
18141:
1815#if defined(WITH_JIT)
1816    GET_JIT_PROF_TABLE(r0)
1817    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1818    cmp     r0,#0
1819    bne     common_updateProfile
1820    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1821    GOTO_OPCODE(ip)                     @ jump to next instruction
1822#else
1823    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1824    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1825    GOTO_OPCODE(ip)                     @ jump to next instruction
1826#endif
1827
1828
1829/* ------------------------------ */
1830    .balign 64
1831.L_OP_IF_GTZ: /* 0x3c */
1832/* File: armv5te/OP_IF_GTZ.S */
1833/* File: armv5te/zcmp.S */
1834    /*
1835     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1836     * fragment that specifies the *reverse* comparison to perform, e.g.
1837     * for "if-le" you would use "gt".
1838     *
1839     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1840     */
1841    /* if-cmp vAA, +BBBB */
1842    mov     r0, rINST, lsr #8           @ r0<- AA
1843    GET_VREG(r2, r0)                    @ r2<- vAA
1844    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1845    cmp     r2, #0                      @ compare (vA, 0)
1846    ble  1f                      @ branch to 1 if comparison failed
1847    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1848    movs    r9, r9, asl #1              @ convert to bytes, check sign
1849    bmi     common_backwardBranch       @ backward branch, do periodic checks
18501:
1851#if defined(WITH_JIT)
1852    GET_JIT_PROF_TABLE(r0)
1853    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1854    cmp     r0,#0
1855    bne     common_updateProfile
1856    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1857    GOTO_OPCODE(ip)                     @ jump to next instruction
1858#else
1859    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1860    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1861    GOTO_OPCODE(ip)                     @ jump to next instruction
1862#endif
1863
1864
1865/* ------------------------------ */
1866    .balign 64
1867.L_OP_IF_LEZ: /* 0x3d */
1868/* File: armv5te/OP_IF_LEZ.S */
1869/* File: armv5te/zcmp.S */
1870    /*
1871     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1872     * fragment that specifies the *reverse* comparison to perform, e.g.
1873     * for "if-le" you would use "gt".
1874     *
1875     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1876     */
1877    /* if-cmp vAA, +BBBB */
1878    mov     r0, rINST, lsr #8           @ r0<- AA
1879    GET_VREG(r2, r0)                    @ r2<- vAA
1880    mov     r9, #4                      @ r0<- BYTE branch dist for not-taken
1881    cmp     r2, #0                      @ compare (vA, 0)
1882    bgt  1f                      @ branch to 1 if comparison failed
1883    FETCH_S(r9, 1)                      @ r9<- branch offset, in code units
1884    movs    r9, r9, asl #1              @ convert to bytes, check sign
1885    bmi     common_backwardBranch       @ backward branch, do periodic checks
18861:
1887#if defined(WITH_JIT)
1888    GET_JIT_PROF_TABLE(r0)
1889    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1890    cmp     r0,#0
1891    bne     common_updateProfile
1892    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1893    GOTO_OPCODE(ip)                     @ jump to next instruction
1894#else
1895    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
1896    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1897    GOTO_OPCODE(ip)                     @ jump to next instruction
1898#endif
1899
1900
1901/* ------------------------------ */
1902    .balign 64
1903.L_OP_UNUSED_3E: /* 0x3e */
1904/* File: armv5te/OP_UNUSED_3E.S */
1905/* File: armv5te/unused.S */
1906    bl      common_abort
1907
1908
1909/* ------------------------------ */
1910    .balign 64
1911.L_OP_UNUSED_3F: /* 0x3f */
1912/* File: armv5te/OP_UNUSED_3F.S */
1913/* File: armv5te/unused.S */
1914    bl      common_abort
1915
1916
1917/* ------------------------------ */
1918    .balign 64
1919.L_OP_UNUSED_40: /* 0x40 */
1920/* File: armv5te/OP_UNUSED_40.S */
1921/* File: armv5te/unused.S */
1922    bl      common_abort
1923
1924
1925/* ------------------------------ */
1926    .balign 64
1927.L_OP_UNUSED_41: /* 0x41 */
1928/* File: armv5te/OP_UNUSED_41.S */
1929/* File: armv5te/unused.S */
1930    bl      common_abort
1931
1932
1933/* ------------------------------ */
1934    .balign 64
1935.L_OP_UNUSED_42: /* 0x42 */
1936/* File: armv5te/OP_UNUSED_42.S */
1937/* File: armv5te/unused.S */
1938    bl      common_abort
1939
1940
1941/* ------------------------------ */
1942    .balign 64
1943.L_OP_UNUSED_43: /* 0x43 */
1944/* File: armv5te/OP_UNUSED_43.S */
1945/* File: armv5te/unused.S */
1946    bl      common_abort
1947
1948
1949/* ------------------------------ */
1950    .balign 64
1951.L_OP_AGET: /* 0x44 */
1952/* File: armv5te/OP_AGET.S */
1953    /*
1954     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1955     *
1956     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
1957     * instructions.  We use a pair of FETCH_Bs instead.
1958     *
1959     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1960     */
1961    /* op vAA, vBB, vCC */
1962    FETCH_B(r2, 1, 0)                   @ r2<- BB
1963    mov     r9, rINST, lsr #8           @ r9<- AA
1964    FETCH_B(r3, 1, 1)                   @ r3<- CC
1965    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1966    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1967    cmp     r0, #0                      @ null array object?
1968    beq     common_errNullObject        @ yes, bail
1969    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1970    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
1971    cmp     r1, r3                      @ compare unsigned index, length
1972    bcs     common_errArrayIndex        @ index >= length, bail
1973    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1974    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
1975    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1976    SET_VREG(r2, r9)                    @ vAA<- r2
1977    GOTO_OPCODE(ip)                     @ jump to next instruction
1978
1979/* ------------------------------ */
1980    .balign 64
1981.L_OP_AGET_WIDE: /* 0x45 */
1982/* File: armv5te/OP_AGET_WIDE.S */
1983    /*
1984     * Array get, 64 bits.  vAA <- vBB[vCC].
1985     *
1986     * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD.
1987     */
1988    /* aget-wide vAA, vBB, vCC */
1989    FETCH(r0, 1)                        @ r0<- CCBB
1990    mov     r9, rINST, lsr #8           @ r9<- AA
1991    and     r2, r0, #255                @ r2<- BB
1992    mov     r3, r0, lsr #8              @ r3<- CC
1993    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1994    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1995    cmp     r0, #0                      @ null array object?
1996    beq     common_errNullObject        @ yes, bail
1997    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1998    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
1999    cmp     r1, r3                      @ compare unsigned index, length
2000    bcc     .LOP_AGET_WIDE_finish          @ okay, continue below
2001    b       common_errArrayIndex        @ index >= length, bail
2002    @ May want to swap the order of these two branches depending on how the
2003    @ branch prediction (if any) handles conditional forward branches vs.
2004    @ unconditional forward branches.
2005
2006/* ------------------------------ */
2007    .balign 64
2008.L_OP_AGET_OBJECT: /* 0x46 */
2009/* File: armv5te/OP_AGET_OBJECT.S */
2010/* File: armv5te/OP_AGET.S */
2011    /*
2012     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2013     *
2014     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2015     * instructions.  We use a pair of FETCH_Bs instead.
2016     *
2017     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2018     */
2019    /* op vAA, vBB, vCC */
2020    FETCH_B(r2, 1, 0)                   @ r2<- BB
2021    mov     r9, rINST, lsr #8           @ r9<- AA
2022    FETCH_B(r3, 1, 1)                   @ r3<- CC
2023    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2024    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2025    cmp     r0, #0                      @ null array object?
2026    beq     common_errNullObject        @ yes, bail
2027    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2028    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
2029    cmp     r1, r3                      @ compare unsigned index, length
2030    bcs     common_errArrayIndex        @ index >= length, bail
2031    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2032    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2033    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2034    SET_VREG(r2, r9)                    @ vAA<- r2
2035    GOTO_OPCODE(ip)                     @ jump to next instruction
2036
2037
2038/* ------------------------------ */
2039    .balign 64
2040.L_OP_AGET_BOOLEAN: /* 0x47 */
2041/* File: armv5te/OP_AGET_BOOLEAN.S */
2042/* File: armv5te/OP_AGET.S */
2043    /*
2044     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2045     *
2046     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2047     * instructions.  We use a pair of FETCH_Bs instead.
2048     *
2049     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2050     */
2051    /* op vAA, vBB, vCC */
2052    FETCH_B(r2, 1, 0)                   @ r2<- BB
2053    mov     r9, rINST, lsr #8           @ r9<- AA
2054    FETCH_B(r3, 1, 1)                   @ r3<- CC
2055    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2056    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2057    cmp     r0, #0                      @ null array object?
2058    beq     common_errNullObject        @ yes, bail
2059    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2060    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2061    cmp     r1, r3                      @ compare unsigned index, length
2062    bcs     common_errArrayIndex        @ index >= length, bail
2063    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2064    ldrb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2065    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2066    SET_VREG(r2, r9)                    @ vAA<- r2
2067    GOTO_OPCODE(ip)                     @ jump to next instruction
2068
2069
2070/* ------------------------------ */
2071    .balign 64
2072.L_OP_AGET_BYTE: /* 0x48 */
2073/* File: armv5te/OP_AGET_BYTE.S */
2074/* File: armv5te/OP_AGET.S */
2075    /*
2076     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2077     *
2078     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2079     * instructions.  We use a pair of FETCH_Bs instead.
2080     *
2081     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2082     */
2083    /* op vAA, vBB, vCC */
2084    FETCH_B(r2, 1, 0)                   @ r2<- BB
2085    mov     r9, rINST, lsr #8           @ r9<- AA
2086    FETCH_B(r3, 1, 1)                   @ r3<- CC
2087    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2088    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2089    cmp     r0, #0                      @ null array object?
2090    beq     common_errNullObject        @ yes, bail
2091    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2092    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2093    cmp     r1, r3                      @ compare unsigned index, length
2094    bcs     common_errArrayIndex        @ index >= length, bail
2095    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2096    ldrsb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2097    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2098    SET_VREG(r2, r9)                    @ vAA<- r2
2099    GOTO_OPCODE(ip)                     @ jump to next instruction
2100
2101
2102/* ------------------------------ */
2103    .balign 64
2104.L_OP_AGET_CHAR: /* 0x49 */
2105/* File: armv5te/OP_AGET_CHAR.S */
2106/* File: armv5te/OP_AGET.S */
2107    /*
2108     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2109     *
2110     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2111     * instructions.  We use a pair of FETCH_Bs instead.
2112     *
2113     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2114     */
2115    /* op vAA, vBB, vCC */
2116    FETCH_B(r2, 1, 0)                   @ r2<- BB
2117    mov     r9, rINST, lsr #8           @ r9<- AA
2118    FETCH_B(r3, 1, 1)                   @ r3<- CC
2119    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2120    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2121    cmp     r0, #0                      @ null array object?
2122    beq     common_errNullObject        @ yes, bail
2123    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2124    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2125    cmp     r1, r3                      @ compare unsigned index, length
2126    bcs     common_errArrayIndex        @ index >= length, bail
2127    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2128    ldrh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2129    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2130    SET_VREG(r2, r9)                    @ vAA<- r2
2131    GOTO_OPCODE(ip)                     @ jump to next instruction
2132
2133
2134/* ------------------------------ */
2135    .balign 64
2136.L_OP_AGET_SHORT: /* 0x4a */
2137/* File: armv5te/OP_AGET_SHORT.S */
2138/* File: armv5te/OP_AGET.S */
2139    /*
2140     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2141     *
2142     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2143     * instructions.  We use a pair of FETCH_Bs instead.
2144     *
2145     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2146     */
2147    /* op vAA, vBB, vCC */
2148    FETCH_B(r2, 1, 0)                   @ r2<- BB
2149    mov     r9, rINST, lsr #8           @ r9<- AA
2150    FETCH_B(r3, 1, 1)                   @ r3<- CC
2151    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2152    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2153    cmp     r0, #0                      @ null array object?
2154    beq     common_errNullObject        @ yes, bail
2155    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2156    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2157    cmp     r1, r3                      @ compare unsigned index, length
2158    bcs     common_errArrayIndex        @ index >= length, bail
2159    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2160    ldrsh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2161    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2162    SET_VREG(r2, r9)                    @ vAA<- r2
2163    GOTO_OPCODE(ip)                     @ jump to next instruction
2164
2165
2166/* ------------------------------ */
2167    .balign 64
2168.L_OP_APUT: /* 0x4b */
2169/* File: armv5te/OP_APUT.S */
2170    /*
2171     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2172     *
2173     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2174     * instructions.  We use a pair of FETCH_Bs instead.
2175     *
2176     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2177     */
2178    /* op vAA, vBB, vCC */
2179    FETCH_B(r2, 1, 0)                   @ r2<- BB
2180    mov     r9, rINST, lsr #8           @ r9<- AA
2181    FETCH_B(r3, 1, 1)                   @ r3<- CC
2182    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2183    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2184    cmp     r0, #0                      @ null array object?
2185    beq     common_errNullObject        @ yes, bail
2186    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2187    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
2188    cmp     r1, r3                      @ compare unsigned index, length
2189    bcs     common_errArrayIndex        @ index >= length, bail
2190    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2191    GET_VREG(r2, r9)                    @ r2<- vAA
2192    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2193    str  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2194    GOTO_OPCODE(ip)                     @ jump to next instruction
2195
2196/* ------------------------------ */
2197    .balign 64
2198.L_OP_APUT_WIDE: /* 0x4c */
2199/* File: armv5te/OP_APUT_WIDE.S */
2200    /*
2201     * Array put, 64 bits.  vBB[vCC] <- vAA.
2202     *
2203     * Arrays of long/double are 64-bit aligned, so it's okay to use STRD.
2204     */
2205    /* aput-wide vAA, vBB, vCC */
2206    FETCH(r0, 1)                        @ r0<- CCBB
2207    mov     r9, rINST, lsr #8           @ r9<- AA
2208    and     r2, r0, #255                @ r2<- BB
2209    mov     r3, r0, lsr #8              @ r3<- CC
2210    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2211    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2212    cmp     r0, #0                      @ null array object?
2213    beq     common_errNullObject        @ yes, bail
2214    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2215    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
2216    cmp     r1, r3                      @ compare unsigned index, length
2217    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2218    bcc     .LOP_APUT_WIDE_finish          @ okay, continue below
2219    b       common_errArrayIndex        @ index >= length, bail
2220    @ May want to swap the order of these two branches depending on how the
2221    @ branch prediction (if any) handles conditional forward branches vs.
2222    @ unconditional forward branches.
2223
2224/* ------------------------------ */
2225    .balign 64
2226.L_OP_APUT_OBJECT: /* 0x4d */
2227/* File: armv5te/OP_APUT_OBJECT.S */
2228    /*
2229     * Store an object into an array.  vBB[vCC] <- vAA.
2230     */
2231    /* op vAA, vBB, vCC */
2232    FETCH(r0, 1)                        @ r0<- CCBB
2233    mov     r9, rINST, lsr #8           @ r9<- AA
2234    and     r2, r0, #255                @ r2<- BB
2235    mov     r3, r0, lsr #8              @ r3<- CC
2236    GET_VREG(rINST, r2)                 @ rINST<- vBB (array object)
2237    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2238    cmp     rINST, #0                   @ null array object?
2239    GET_VREG(r9, r9)                    @ r9<- vAA
2240    beq     common_errNullObject        @ yes, bail
2241    ldr     r3, [rINST, #offArrayObject_length]   @ r3<- arrayObj->length
2242    add     r10, rINST, r1, lsl #2      @ r10<- arrayObj + index*width
2243    cmp     r1, r3                      @ compare unsigned index, length
2244    bcc     .LOP_APUT_OBJECT_finish          @ we're okay, continue on
2245    b       common_errArrayIndex        @ index >= length, bail
2246
2247
2248/* ------------------------------ */
2249    .balign 64
2250.L_OP_APUT_BOOLEAN: /* 0x4e */
2251/* File: armv5te/OP_APUT_BOOLEAN.S */
2252/* File: armv5te/OP_APUT.S */
2253    /*
2254     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2255     *
2256     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2257     * instructions.  We use a pair of FETCH_Bs instead.
2258     *
2259     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2260     */
2261    /* op vAA, vBB, vCC */
2262    FETCH_B(r2, 1, 0)                   @ r2<- BB
2263    mov     r9, rINST, lsr #8           @ r9<- AA
2264    FETCH_B(r3, 1, 1)                   @ r3<- CC
2265    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2266    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2267    cmp     r0, #0                      @ null array object?
2268    beq     common_errNullObject        @ yes, bail
2269    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2270    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2271    cmp     r1, r3                      @ compare unsigned index, length
2272    bcs     common_errArrayIndex        @ index >= length, bail
2273    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2274    GET_VREG(r2, r9)                    @ r2<- vAA
2275    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2276    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2277    GOTO_OPCODE(ip)                     @ jump to next instruction
2278
2279
2280/* ------------------------------ */
2281    .balign 64
2282.L_OP_APUT_BYTE: /* 0x4f */
2283/* File: armv5te/OP_APUT_BYTE.S */
2284/* File: armv5te/OP_APUT.S */
2285    /*
2286     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2287     *
2288     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2289     * instructions.  We use a pair of FETCH_Bs instead.
2290     *
2291     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2292     */
2293    /* op vAA, vBB, vCC */
2294    FETCH_B(r2, 1, 0)                   @ r2<- BB
2295    mov     r9, rINST, lsr #8           @ r9<- AA
2296    FETCH_B(r3, 1, 1)                   @ r3<- CC
2297    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2298    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2299    cmp     r0, #0                      @ null array object?
2300    beq     common_errNullObject        @ yes, bail
2301    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2302    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2303    cmp     r1, r3                      @ compare unsigned index, length
2304    bcs     common_errArrayIndex        @ index >= length, bail
2305    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2306    GET_VREG(r2, r9)                    @ r2<- vAA
2307    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2308    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2309    GOTO_OPCODE(ip)                     @ jump to next instruction
2310
2311
2312/* ------------------------------ */
2313    .balign 64
2314.L_OP_APUT_CHAR: /* 0x50 */
2315/* File: armv5te/OP_APUT_CHAR.S */
2316/* File: armv5te/OP_APUT.S */
2317    /*
2318     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2319     *
2320     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2321     * instructions.  We use a pair of FETCH_Bs instead.
2322     *
2323     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2324     */
2325    /* op vAA, vBB, vCC */
2326    FETCH_B(r2, 1, 0)                   @ r2<- BB
2327    mov     r9, rINST, lsr #8           @ r9<- AA
2328    FETCH_B(r3, 1, 1)                   @ r3<- CC
2329    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2330    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2331    cmp     r0, #0                      @ null array object?
2332    beq     common_errNullObject        @ yes, bail
2333    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2334    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2335    cmp     r1, r3                      @ compare unsigned index, length
2336    bcs     common_errArrayIndex        @ index >= length, bail
2337    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2338    GET_VREG(r2, r9)                    @ r2<- vAA
2339    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2340    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2341    GOTO_OPCODE(ip)                     @ jump to next instruction
2342
2343
2344/* ------------------------------ */
2345    .balign 64
2346.L_OP_APUT_SHORT: /* 0x51 */
2347/* File: armv5te/OP_APUT_SHORT.S */
2348/* File: armv5te/OP_APUT.S */
2349    /*
2350     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2351     *
2352     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2353     * instructions.  We use a pair of FETCH_Bs instead.
2354     *
2355     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2356     */
2357    /* op vAA, vBB, vCC */
2358    FETCH_B(r2, 1, 0)                   @ r2<- BB
2359    mov     r9, rINST, lsr #8           @ r9<- AA
2360    FETCH_B(r3, 1, 1)                   @ r3<- CC
2361    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2362    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2363    cmp     r0, #0                      @ null array object?
2364    beq     common_errNullObject        @ yes, bail
2365    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2366    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2367    cmp     r1, r3                      @ compare unsigned index, length
2368    bcs     common_errArrayIndex        @ index >= length, bail
2369    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2370    GET_VREG(r2, r9)                    @ r2<- vAA
2371    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2372    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2373    GOTO_OPCODE(ip)                     @ jump to next instruction
2374
2375
2376/* ------------------------------ */
2377    .balign 64
2378.L_OP_IGET: /* 0x52 */
2379/* File: armv6t2/OP_IGET.S */
2380    /*
2381     * General 32-bit instance field get.
2382     *
2383     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2384     */
2385    /* op vA, vB, field@CCCC */
2386    mov     r0, rINST, lsr #12          @ r0<- B
2387    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2388    FETCH(r1, 1)                        @ r1<- field ref CCCC
2389    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2390    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2391    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2392    cmp     r0, #0                      @ is resolved entry null?
2393    bne     .LOP_IGET_finish          @ no, already resolved
23948:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2395    EXPORT_PC()                         @ resolve() could throw
2396    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2397    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2398    cmp     r0, #0
2399    bne     .LOP_IGET_finish
2400    b       common_exceptionThrown
2401
2402/* ------------------------------ */
2403    .balign 64
2404.L_OP_IGET_WIDE: /* 0x53 */
2405/* File: armv6t2/OP_IGET_WIDE.S */
2406    /*
2407     * Wide 32-bit instance field get.
2408     */
2409    /* iget-wide vA, vB, field@CCCC */
2410    mov     r0, rINST, lsr #12          @ r0<- B
2411    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2412    FETCH(r1, 1)                        @ r1<- field ref CCCC
2413    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
2414    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2415    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2416    cmp     r0, #0                      @ is resolved entry null?
2417    bne     .LOP_IGET_WIDE_finish          @ no, already resolved
24188:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
2419    EXPORT_PC()                         @ resolve() could throw
2420    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2421    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2422    cmp     r0, #0
2423    bne     .LOP_IGET_WIDE_finish
2424    b       common_exceptionThrown
2425
2426/* ------------------------------ */
2427    .balign 64
2428.L_OP_IGET_OBJECT: /* 0x54 */
2429/* File: armv5te/OP_IGET_OBJECT.S */
2430/* File: armv5te/OP_IGET.S */
2431    /*
2432     * General 32-bit instance field get.
2433     *
2434     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2435     */
2436    /* op vA, vB, field@CCCC */
2437    mov     r0, rINST, lsr #12          @ r0<- B
2438    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2439    FETCH(r1, 1)                        @ r1<- field ref CCCC
2440    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2441    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2442    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2443    cmp     r0, #0                      @ is resolved entry null?
2444    bne     .LOP_IGET_OBJECT_finish          @ no, already resolved
24458:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2446    EXPORT_PC()                         @ resolve() could throw
2447    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2448    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2449    cmp     r0, #0
2450    bne     .LOP_IGET_OBJECT_finish
2451    b       common_exceptionThrown
2452
2453
2454/* ------------------------------ */
2455    .balign 64
2456.L_OP_IGET_BOOLEAN: /* 0x55 */
2457/* File: armv5te/OP_IGET_BOOLEAN.S */
2458@include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" }
2459/* File: armv5te/OP_IGET.S */
2460    /*
2461     * General 32-bit instance field get.
2462     *
2463     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2464     */
2465    /* op vA, vB, field@CCCC */
2466    mov     r0, rINST, lsr #12          @ r0<- B
2467    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2468    FETCH(r1, 1)                        @ r1<- field ref CCCC
2469    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2470    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2471    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2472    cmp     r0, #0                      @ is resolved entry null?
2473    bne     .LOP_IGET_BOOLEAN_finish          @ no, already resolved
24748:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2475    EXPORT_PC()                         @ resolve() could throw
2476    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2477    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2478    cmp     r0, #0
2479    bne     .LOP_IGET_BOOLEAN_finish
2480    b       common_exceptionThrown
2481
2482
2483/* ------------------------------ */
2484    .balign 64
2485.L_OP_IGET_BYTE: /* 0x56 */
2486/* File: armv5te/OP_IGET_BYTE.S */
2487@include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" }
2488/* File: armv5te/OP_IGET.S */
2489    /*
2490     * General 32-bit instance field get.
2491     *
2492     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2493     */
2494    /* op vA, vB, field@CCCC */
2495    mov     r0, rINST, lsr #12          @ r0<- B
2496    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2497    FETCH(r1, 1)                        @ r1<- field ref CCCC
2498    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2499    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2500    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2501    cmp     r0, #0                      @ is resolved entry null?
2502    bne     .LOP_IGET_BYTE_finish          @ no, already resolved
25038:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2504    EXPORT_PC()                         @ resolve() could throw
2505    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2506    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2507    cmp     r0, #0
2508    bne     .LOP_IGET_BYTE_finish
2509    b       common_exceptionThrown
2510
2511
2512/* ------------------------------ */
2513    .balign 64
2514.L_OP_IGET_CHAR: /* 0x57 */
2515/* File: armv5te/OP_IGET_CHAR.S */
2516@include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" }
2517/* File: armv5te/OP_IGET.S */
2518    /*
2519     * General 32-bit instance field get.
2520     *
2521     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2522     */
2523    /* op vA, vB, field@CCCC */
2524    mov     r0, rINST, lsr #12          @ r0<- B
2525    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2526    FETCH(r1, 1)                        @ r1<- field ref CCCC
2527    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2528    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2529    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2530    cmp     r0, #0                      @ is resolved entry null?
2531    bne     .LOP_IGET_CHAR_finish          @ no, already resolved
25328:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2533    EXPORT_PC()                         @ resolve() could throw
2534    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2535    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2536    cmp     r0, #0
2537    bne     .LOP_IGET_CHAR_finish
2538    b       common_exceptionThrown
2539
2540
2541/* ------------------------------ */
2542    .balign 64
2543.L_OP_IGET_SHORT: /* 0x58 */
2544/* File: armv5te/OP_IGET_SHORT.S */
2545@include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" }
2546/* File: armv5te/OP_IGET.S */
2547    /*
2548     * General 32-bit instance field get.
2549     *
2550     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2551     */
2552    /* op vA, vB, field@CCCC */
2553    mov     r0, rINST, lsr #12          @ r0<- B
2554    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2555    FETCH(r1, 1)                        @ r1<- field ref CCCC
2556    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2557    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2558    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2559    cmp     r0, #0                      @ is resolved entry null?
2560    bne     .LOP_IGET_SHORT_finish          @ no, already resolved
25618:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2562    EXPORT_PC()                         @ resolve() could throw
2563    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2564    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2565    cmp     r0, #0
2566    bne     .LOP_IGET_SHORT_finish
2567    b       common_exceptionThrown
2568
2569
2570/* ------------------------------ */
2571    .balign 64
2572.L_OP_IPUT: /* 0x59 */
2573/* File: armv6t2/OP_IPUT.S */
2574    /*
2575     * General 32-bit instance field put.
2576     *
2577     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
2578     */
2579    /* op vA, vB, field@CCCC */
2580    mov     r0, rINST, lsr #12          @ r0<- B
2581    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2582    FETCH(r1, 1)                        @ r1<- field ref CCCC
2583    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2584    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2585    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2586    cmp     r0, #0                      @ is resolved entry null?
2587    bne     .LOP_IPUT_finish          @ no, already resolved
25888:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2589    EXPORT_PC()                         @ resolve() could throw
2590    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2591    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2592    cmp     r0, #0                      @ success?
2593    bne     .LOP_IPUT_finish          @ yes, finish up
2594    b       common_exceptionThrown
2595
2596/* ------------------------------ */
2597    .balign 64
2598.L_OP_IPUT_WIDE: /* 0x5a */
2599/* File: armv6t2/OP_IPUT_WIDE.S */
2600    /* iput-wide vA, vB, field@CCCC */
2601    mov     r0, rINST, lsr #12          @ r0<- B
2602    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2603    FETCH(r1, 1)                        @ r1<- field ref CCCC
2604    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
2605    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2606    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2607    cmp     r0, #0                      @ is resolved entry null?
2608    bne     .LOP_IPUT_WIDE_finish          @ no, already resolved
26098:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
2610    EXPORT_PC()                         @ resolve() could throw
2611    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2612    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2613    cmp     r0, #0                      @ success?
2614    bne     .LOP_IPUT_WIDE_finish          @ yes, finish up
2615    b       common_exceptionThrown
2616
2617/* ------------------------------ */
2618    .balign 64
2619.L_OP_IPUT_OBJECT: /* 0x5b */
2620/* File: armv5te/OP_IPUT_OBJECT.S */
2621    /*
2622     * 32-bit instance field put.
2623     *
2624     * for: iput-object, iput-object-volatile
2625     */
2626    /* op vA, vB, field@CCCC */
2627    mov     r0, rINST, lsr #12          @ r0<- B
2628    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2629    FETCH(r1, 1)                        @ r1<- field ref CCCC
2630    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2631    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2632    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2633    cmp     r0, #0                      @ is resolved entry null?
2634    bne     .LOP_IPUT_OBJECT_finish          @ no, already resolved
26358:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2636    EXPORT_PC()                         @ resolve() could throw
2637    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2638    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2639    cmp     r0, #0                      @ success?
2640    bne     .LOP_IPUT_OBJECT_finish          @ yes, finish up
2641    b       common_exceptionThrown
2642
2643/* ------------------------------ */
2644    .balign 64
2645.L_OP_IPUT_BOOLEAN: /* 0x5c */
2646/* File: armv5te/OP_IPUT_BOOLEAN.S */
2647@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" }
2648/* File: armv5te/OP_IPUT.S */
2649    /*
2650     * General 32-bit instance field put.
2651     *
2652     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2653     */
2654    /* op vA, vB, field@CCCC */
2655    mov     r0, rINST, lsr #12          @ r0<- B
2656    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2657    FETCH(r1, 1)                        @ r1<- field ref CCCC
2658    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2659    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2660    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2661    cmp     r0, #0                      @ is resolved entry null?
2662    bne     .LOP_IPUT_BOOLEAN_finish          @ no, already resolved
26638:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2664    EXPORT_PC()                         @ resolve() could throw
2665    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2666    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2667    cmp     r0, #0                      @ success?
2668    bne     .LOP_IPUT_BOOLEAN_finish          @ yes, finish up
2669    b       common_exceptionThrown
2670
2671
2672/* ------------------------------ */
2673    .balign 64
2674.L_OP_IPUT_BYTE: /* 0x5d */
2675/* File: armv5te/OP_IPUT_BYTE.S */
2676@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" }
2677/* File: armv5te/OP_IPUT.S */
2678    /*
2679     * General 32-bit instance field put.
2680     *
2681     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2682     */
2683    /* op vA, vB, field@CCCC */
2684    mov     r0, rINST, lsr #12          @ r0<- B
2685    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2686    FETCH(r1, 1)                        @ r1<- field ref CCCC
2687    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2688    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2689    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2690    cmp     r0, #0                      @ is resolved entry null?
2691    bne     .LOP_IPUT_BYTE_finish          @ no, already resolved
26928:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2693    EXPORT_PC()                         @ resolve() could throw
2694    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2695    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2696    cmp     r0, #0                      @ success?
2697    bne     .LOP_IPUT_BYTE_finish          @ yes, finish up
2698    b       common_exceptionThrown
2699
2700
2701/* ------------------------------ */
2702    .balign 64
2703.L_OP_IPUT_CHAR: /* 0x5e */
2704/* File: armv5te/OP_IPUT_CHAR.S */
2705@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" }
2706/* File: armv5te/OP_IPUT.S */
2707    /*
2708     * General 32-bit instance field put.
2709     *
2710     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2711     */
2712    /* op vA, vB, field@CCCC */
2713    mov     r0, rINST, lsr #12          @ r0<- B
2714    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2715    FETCH(r1, 1)                        @ r1<- field ref CCCC
2716    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2717    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2718    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2719    cmp     r0, #0                      @ is resolved entry null?
2720    bne     .LOP_IPUT_CHAR_finish          @ no, already resolved
27218:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2722    EXPORT_PC()                         @ resolve() could throw
2723    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2724    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2725    cmp     r0, #0                      @ success?
2726    bne     .LOP_IPUT_CHAR_finish          @ yes, finish up
2727    b       common_exceptionThrown
2728
2729
2730/* ------------------------------ */
2731    .balign 64
2732.L_OP_IPUT_SHORT: /* 0x5f */
2733/* File: armv5te/OP_IPUT_SHORT.S */
2734@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" }
2735/* File: armv5te/OP_IPUT.S */
2736    /*
2737     * General 32-bit instance field put.
2738     *
2739     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2740     */
2741    /* op vA, vB, field@CCCC */
2742    mov     r0, rINST, lsr #12          @ r0<- B
2743    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2744    FETCH(r1, 1)                        @ r1<- field ref CCCC
2745    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2746    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2747    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2748    cmp     r0, #0                      @ is resolved entry null?
2749    bne     .LOP_IPUT_SHORT_finish          @ no, already resolved
27508:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2751    EXPORT_PC()                         @ resolve() could throw
2752    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2753    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2754    cmp     r0, #0                      @ success?
2755    bne     .LOP_IPUT_SHORT_finish          @ yes, finish up
2756    b       common_exceptionThrown
2757
2758
2759/* ------------------------------ */
2760    .balign 64
2761.L_OP_SGET: /* 0x60 */
2762/* File: armv5te/OP_SGET.S */
2763    /*
2764     * General 32-bit SGET handler.
2765     *
2766     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2767     */
2768    /* op vAA, field@BBBB */
2769    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2770    FETCH(r1, 1)                        @ r1<- field ref BBBB
2771    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2772    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2773    cmp     r0, #0                      @ is resolved entry null?
2774    beq     .LOP_SGET_resolve         @ yes, do resolve
2775.LOP_SGET_finish: @ field ptr in r0
2776    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2777    @ no-op                             @ acquiring load
2778    mov     r2, rINST, lsr #8           @ r2<- AA
2779    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2780    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2781    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2782    GOTO_OPCODE(ip)                     @ jump to next instruction
2783
2784/* ------------------------------ */
2785    .balign 64
2786.L_OP_SGET_WIDE: /* 0x61 */
2787/* File: armv5te/OP_SGET_WIDE.S */
2788    /*
2789     * 64-bit SGET handler.
2790     */
2791    /* sget-wide vAA, field@BBBB */
2792    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2793    FETCH(r1, 1)                        @ r1<- field ref BBBB
2794    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2795    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2796    cmp     r0, #0                      @ is resolved entry null?
2797    beq     .LOP_SGET_WIDE_resolve         @ yes, do resolve
2798.LOP_SGET_WIDE_finish:
2799    mov     r9, rINST, lsr #8           @ r9<- AA
2800    .if 0
2801    add     r0, r0, #offStaticField_value @ r0<- pointer to data
2802    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
2803    .else
2804    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
2805    .endif
2806    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2807    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2808    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
2809    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2810    GOTO_OPCODE(ip)                     @ jump to next instruction
2811
2812/* ------------------------------ */
2813    .balign 64
2814.L_OP_SGET_OBJECT: /* 0x62 */
2815/* File: armv5te/OP_SGET_OBJECT.S */
2816/* File: armv5te/OP_SGET.S */
2817    /*
2818     * General 32-bit SGET handler.
2819     *
2820     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2821     */
2822    /* op vAA, field@BBBB */
2823    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2824    FETCH(r1, 1)                        @ r1<- field ref BBBB
2825    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2826    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2827    cmp     r0, #0                      @ is resolved entry null?
2828    beq     .LOP_SGET_OBJECT_resolve         @ yes, do resolve
2829.LOP_SGET_OBJECT_finish: @ field ptr in r0
2830    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2831    @ no-op                             @ acquiring load
2832    mov     r2, rINST, lsr #8           @ r2<- AA
2833    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2834    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2835    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2836    GOTO_OPCODE(ip)                     @ jump to next instruction
2837
2838
2839/* ------------------------------ */
2840    .balign 64
2841.L_OP_SGET_BOOLEAN: /* 0x63 */
2842/* File: armv5te/OP_SGET_BOOLEAN.S */
2843/* File: armv5te/OP_SGET.S */
2844    /*
2845     * General 32-bit SGET handler.
2846     *
2847     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2848     */
2849    /* op vAA, field@BBBB */
2850    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2851    FETCH(r1, 1)                        @ r1<- field ref BBBB
2852    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2853    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2854    cmp     r0, #0                      @ is resolved entry null?
2855    beq     .LOP_SGET_BOOLEAN_resolve         @ yes, do resolve
2856.LOP_SGET_BOOLEAN_finish: @ field ptr in r0
2857    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2858    @ no-op                             @ acquiring load
2859    mov     r2, rINST, lsr #8           @ r2<- AA
2860    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2861    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2862    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2863    GOTO_OPCODE(ip)                     @ jump to next instruction
2864
2865
2866/* ------------------------------ */
2867    .balign 64
2868.L_OP_SGET_BYTE: /* 0x64 */
2869/* File: armv5te/OP_SGET_BYTE.S */
2870/* File: armv5te/OP_SGET.S */
2871    /*
2872     * General 32-bit SGET handler.
2873     *
2874     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2875     */
2876    /* op vAA, field@BBBB */
2877    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2878    FETCH(r1, 1)                        @ r1<- field ref BBBB
2879    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2880    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2881    cmp     r0, #0                      @ is resolved entry null?
2882    beq     .LOP_SGET_BYTE_resolve         @ yes, do resolve
2883.LOP_SGET_BYTE_finish: @ field ptr in r0
2884    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2885    @ no-op                             @ acquiring load
2886    mov     r2, rINST, lsr #8           @ r2<- AA
2887    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2888    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2889    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2890    GOTO_OPCODE(ip)                     @ jump to next instruction
2891
2892
2893/* ------------------------------ */
2894    .balign 64
2895.L_OP_SGET_CHAR: /* 0x65 */
2896/* File: armv5te/OP_SGET_CHAR.S */
2897/* File: armv5te/OP_SGET.S */
2898    /*
2899     * General 32-bit SGET handler.
2900     *
2901     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2902     */
2903    /* op vAA, field@BBBB */
2904    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2905    FETCH(r1, 1)                        @ r1<- field ref BBBB
2906    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2907    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2908    cmp     r0, #0                      @ is resolved entry null?
2909    beq     .LOP_SGET_CHAR_resolve         @ yes, do resolve
2910.LOP_SGET_CHAR_finish: @ field ptr in r0
2911    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2912    @ no-op                             @ acquiring load
2913    mov     r2, rINST, lsr #8           @ r2<- AA
2914    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2915    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2916    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2917    GOTO_OPCODE(ip)                     @ jump to next instruction
2918
2919
2920/* ------------------------------ */
2921    .balign 64
2922.L_OP_SGET_SHORT: /* 0x66 */
2923/* File: armv5te/OP_SGET_SHORT.S */
2924/* File: armv5te/OP_SGET.S */
2925    /*
2926     * General 32-bit SGET handler.
2927     *
2928     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2929     */
2930    /* op vAA, field@BBBB */
2931    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2932    FETCH(r1, 1)                        @ r1<- field ref BBBB
2933    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2934    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2935    cmp     r0, #0                      @ is resolved entry null?
2936    beq     .LOP_SGET_SHORT_resolve         @ yes, do resolve
2937.LOP_SGET_SHORT_finish: @ field ptr in r0
2938    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2939    @ no-op                             @ acquiring load
2940    mov     r2, rINST, lsr #8           @ r2<- AA
2941    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2942    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2943    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2944    GOTO_OPCODE(ip)                     @ jump to next instruction
2945
2946
2947/* ------------------------------ */
2948    .balign 64
2949.L_OP_SPUT: /* 0x67 */
2950/* File: armv5te/OP_SPUT.S */
2951    /*
2952     * General 32-bit SPUT handler.
2953     *
2954     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2955     */
2956    /* op vAA, field@BBBB */
2957    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2958    FETCH(r1, 1)                        @ r1<- field ref BBBB
2959    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
2960    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
2961    cmp     r0, #0                      @ is resolved entry null?
2962    beq     .LOP_SPUT_resolve         @ yes, do resolve
2963.LOP_SPUT_finish:   @ field ptr in r0
2964    mov     r2, rINST, lsr #8           @ r2<- AA
2965    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2966    GET_VREG(r1, r2)                    @ r1<- fp[AA]
2967    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2968    @ no-op                             @ releasing store
2969    str     r1, [r0, #offStaticField_value] @ field<- vAA
2970    GOTO_OPCODE(ip)                     @ jump to next instruction
2971
2972/* ------------------------------ */
2973    .balign 64
2974.L_OP_SPUT_WIDE: /* 0x68 */
2975/* File: armv5te/OP_SPUT_WIDE.S */
2976    /*
2977     * 64-bit SPUT handler.
2978     */
2979    /* sput-wide vAA, field@BBBB */
2980    ldr     r0, [rSELF, #offThread_methodClassDex]  @ r0<- DvmDex
2981    FETCH(r1, 1)                        @ r1<- field ref BBBB
2982    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
2983    mov     r9, rINST, lsr #8           @ r9<- AA
2984    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
2985    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2986    cmp     r2, #0                      @ is resolved entry null?
2987    beq     .LOP_SPUT_WIDE_resolve         @ yes, do resolve
2988.LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9
2989    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2990    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
2991    GET_INST_OPCODE(r10)                @ extract opcode from rINST
2992    .if 0
2993    add     r2, r2, #offStaticField_value @ r2<- pointer to data
2994    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
2995    .else
2996    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
2997    .endif
2998    GOTO_OPCODE(r10)                    @ jump to next instruction
2999
3000/* ------------------------------ */
3001    .balign 64
3002.L_OP_SPUT_OBJECT: /* 0x69 */
3003/* File: armv5te/OP_SPUT_OBJECT.S */
3004    /*
3005     * 32-bit SPUT handler for objects
3006     *
3007     * for: sput-object, sput-object-volatile
3008     */
3009    /* op vAA, field@BBBB */
3010    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
3011    FETCH(r1, 1)                        @ r1<- field ref BBBB
3012    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3013    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3014    cmp     r0, #0                      @ is resolved entry null?
3015    bne     .LOP_SPUT_OBJECT_finish          @ no, continue
3016    ldr     r9, [rSELF, #offThread_method]    @ r9<- current method
3017    EXPORT_PC()                         @ resolve() could throw, so export now
3018    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
3019    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
3020    cmp     r0, #0                      @ success?
3021    bne     .LOP_SPUT_OBJECT_finish          @ yes, finish
3022    b       common_exceptionThrown      @ no, handle exception
3023
3024
3025/* ------------------------------ */
3026    .balign 64
3027.L_OP_SPUT_BOOLEAN: /* 0x6a */
3028/* File: armv5te/OP_SPUT_BOOLEAN.S */
3029/* File: armv5te/OP_SPUT.S */
3030    /*
3031     * General 32-bit SPUT handler.
3032     *
3033     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3034     */
3035    /* op vAA, field@BBBB */
3036    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
3037    FETCH(r1, 1)                        @ r1<- field ref BBBB
3038    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3039    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3040    cmp     r0, #0                      @ is resolved entry null?
3041    beq     .LOP_SPUT_BOOLEAN_resolve         @ yes, do resolve
3042.LOP_SPUT_BOOLEAN_finish:   @ field ptr in r0
3043    mov     r2, rINST, lsr #8           @ r2<- AA
3044    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3045    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3046    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3047    @ no-op                             @ releasing store
3048    str     r1, [r0, #offStaticField_value] @ field<- vAA
3049    GOTO_OPCODE(ip)                     @ jump to next instruction
3050
3051
3052/* ------------------------------ */
3053    .balign 64
3054.L_OP_SPUT_BYTE: /* 0x6b */
3055/* File: armv5te/OP_SPUT_BYTE.S */
3056/* File: armv5te/OP_SPUT.S */
3057    /*
3058     * General 32-bit SPUT handler.
3059     *
3060     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3061     */
3062    /* op vAA, field@BBBB */
3063    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
3064    FETCH(r1, 1)                        @ r1<- field ref BBBB
3065    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3066    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3067    cmp     r0, #0                      @ is resolved entry null?
3068    beq     .LOP_SPUT_BYTE_resolve         @ yes, do resolve
3069.LOP_SPUT_BYTE_finish:   @ field ptr in r0
3070    mov     r2, rINST, lsr #8           @ r2<- AA
3071    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3072    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3073    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3074    @ no-op                             @ releasing store
3075    str     r1, [r0, #offStaticField_value] @ field<- vAA
3076    GOTO_OPCODE(ip)                     @ jump to next instruction
3077
3078
3079/* ------------------------------ */
3080    .balign 64
3081.L_OP_SPUT_CHAR: /* 0x6c */
3082/* File: armv5te/OP_SPUT_CHAR.S */
3083/* File: armv5te/OP_SPUT.S */
3084    /*
3085     * General 32-bit SPUT handler.
3086     *
3087     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3088     */
3089    /* op vAA, field@BBBB */
3090    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
3091    FETCH(r1, 1)                        @ r1<- field ref BBBB
3092    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3093    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3094    cmp     r0, #0                      @ is resolved entry null?
3095    beq     .LOP_SPUT_CHAR_resolve         @ yes, do resolve
3096.LOP_SPUT_CHAR_finish:   @ field ptr in r0
3097    mov     r2, rINST, lsr #8           @ r2<- AA
3098    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3099    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3100    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3101    @ no-op                             @ releasing store
3102    str     r1, [r0, #offStaticField_value] @ field<- vAA
3103    GOTO_OPCODE(ip)                     @ jump to next instruction
3104
3105
3106/* ------------------------------ */
3107    .balign 64
3108.L_OP_SPUT_SHORT: /* 0x6d */
3109/* File: armv5te/OP_SPUT_SHORT.S */
3110/* File: armv5te/OP_SPUT.S */
3111    /*
3112     * General 32-bit SPUT handler.
3113     *
3114     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3115     */
3116    /* op vAA, field@BBBB */
3117    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
3118    FETCH(r1, 1)                        @ r1<- field ref BBBB
3119    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
3120    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
3121    cmp     r0, #0                      @ is resolved entry null?
3122    beq     .LOP_SPUT_SHORT_resolve         @ yes, do resolve
3123.LOP_SPUT_SHORT_finish:   @ field ptr in r0
3124    mov     r2, rINST, lsr #8           @ r2<- AA
3125    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3126    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3127    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3128    @ no-op                             @ releasing store
3129    str     r1, [r0, #offStaticField_value] @ field<- vAA
3130    GOTO_OPCODE(ip)                     @ jump to next instruction
3131
3132
3133/* ------------------------------ */
3134    .balign 64
3135.L_OP_INVOKE_VIRTUAL: /* 0x6e */
3136/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3137    /*
3138     * Handle a virtual method call.
3139     *
3140     * for: invoke-virtual, invoke-virtual/range
3141     */
3142    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3143    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3144    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3145    FETCH(r1, 1)                        @ r1<- BBBB
3146    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3147    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3148    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3149    .if     (!0)
3150    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3151    .endif
3152    cmp     r0, #0                      @ already resolved?
3153    EXPORT_PC()                         @ must export for invoke
3154    bne     .LOP_INVOKE_VIRTUAL_continue        @ yes, continue on
3155    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
3156    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3157    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3158    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3159    cmp     r0, #0                      @ got null?
3160    bne     .LOP_INVOKE_VIRTUAL_continue        @ no, continue
3161    b       common_exceptionThrown      @ yes, handle exception
3162
3163/* ------------------------------ */
3164    .balign 64
3165.L_OP_INVOKE_SUPER: /* 0x6f */
3166/* File: armv5te/OP_INVOKE_SUPER.S */
3167    /*
3168     * Handle a "super" method call.
3169     *
3170     * for: invoke-super, invoke-super/range
3171     */
3172    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3173    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3174    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3175    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3176    .if     (!0)
3177    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3178    .endif
3179    FETCH(r1, 1)                        @ r1<- BBBB
3180    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3181    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3182    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3183    cmp     r2, #0                      @ null "this"?
3184    ldr     r9, [rSELF, #offThread_method] @ r9<- current method
3185    beq     common_errNullObject        @ null "this", throw exception
3186    cmp     r0, #0                      @ already resolved?
3187    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
3188    EXPORT_PC()                         @ must export for invoke
3189    bne     .LOP_INVOKE_SUPER_continue        @ resolved, continue on
3190    b       .LOP_INVOKE_SUPER_resolve         @ do resolve now
3191
3192/* ------------------------------ */
3193    .balign 64
3194.L_OP_INVOKE_DIRECT: /* 0x70 */
3195/* File: armv5te/OP_INVOKE_DIRECT.S */
3196    /*
3197     * Handle a direct method call.
3198     *
3199     * (We could defer the "is 'this' pointer null" test to the common
3200     * method invocation code, and use a flag to indicate that static
3201     * calls don't count.  If we do this as part of copying the arguments
3202     * out we could avoiding loading the first arg twice.)
3203     *
3204     * for: invoke-direct, invoke-direct/range
3205     */
3206    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3207    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3208    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3209    FETCH(r1, 1)                        @ r1<- BBBB
3210    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3211    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3212    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3213    .if     (!0)
3214    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3215    .endif
3216    cmp     r0, #0                      @ already resolved?
3217    EXPORT_PC()                         @ must export for invoke
3218    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3219    beq     .LOP_INVOKE_DIRECT_resolve         @ not resolved, do it now
3220.LOP_INVOKE_DIRECT_finish:
3221    cmp     r2, #0                      @ null "this" ref?
3222    bne     common_invokeMethodNoRange   @ no, continue on
3223    b       common_errNullObject        @ yes, throw exception
3224
3225/* ------------------------------ */
3226    .balign 64
3227.L_OP_INVOKE_STATIC: /* 0x71 */
3228/* File: armv5te/OP_INVOKE_STATIC.S */
3229    /*
3230     * Handle a static method call.
3231     *
3232     * for: invoke-static, invoke-static/range
3233     */
3234    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3235    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3236    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3237    FETCH(r1, 1)                        @ r1<- BBBB
3238    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3239    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3240    cmp     r0, #0                      @ already resolved?
3241    EXPORT_PC()                         @ must export for invoke
3242    bne     common_invokeMethodNoRange @ yes, continue on
32430:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
3244    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3245    mov     r2, #METHOD_STATIC          @ resolver method type
3246    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3247    cmp     r0, #0                      @ got null?
3248    bne     common_invokeMethodNoRange @ no, continue
3249    b       common_exceptionThrown      @ yes, handle exception
3250
3251/* ------------------------------ */
3252    .balign 64
3253.L_OP_INVOKE_INTERFACE: /* 0x72 */
3254/* File: armv5te/OP_INVOKE_INTERFACE.S */
3255    /*
3256     * Handle an interface method call.
3257     *
3258     * for: invoke-interface, invoke-interface/range
3259     */
3260    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3261    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3262    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3263    FETCH(r1, 1)                        @ r1<- BBBB
3264    .if     (!0)
3265    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3266    .endif
3267    EXPORT_PC()                         @ must export for invoke
3268    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
3269    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- methodClassDex
3270    cmp     r0, #0                      @ null obj?
3271    ldr     r2, [rSELF, #offThread_method]  @ r2<- method
3272    beq     common_errNullObject        @ yes, fail
3273    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
3274    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3275    cmp     r0, #0                      @ failed?
3276    beq     common_exceptionThrown      @ yes, handle exception
3277    b       common_invokeMethodNoRange @ jump to common handler
3278
3279/* ------------------------------ */
3280    .balign 64
3281.L_OP_UNUSED_73: /* 0x73 */
3282/* File: armv5te/OP_UNUSED_73.S */
3283/* File: armv5te/unused.S */
3284    bl      common_abort
3285
3286
3287/* ------------------------------ */
3288    .balign 64
3289.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
3290/* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */
3291/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3292    /*
3293     * Handle a virtual method call.
3294     *
3295     * for: invoke-virtual, invoke-virtual/range
3296     */
3297    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3298    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3299    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3300    FETCH(r1, 1)                        @ r1<- BBBB
3301    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3302    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3303    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3304    .if     (!1)
3305    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3306    .endif
3307    cmp     r0, #0                      @ already resolved?
3308    EXPORT_PC()                         @ must export for invoke
3309    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ yes, continue on
3310    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
3311    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3312    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3313    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3314    cmp     r0, #0                      @ got null?
3315    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ no, continue
3316    b       common_exceptionThrown      @ yes, handle exception
3317
3318
3319/* ------------------------------ */
3320    .balign 64
3321.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */
3322/* File: armv5te/OP_INVOKE_SUPER_RANGE.S */
3323/* File: armv5te/OP_INVOKE_SUPER.S */
3324    /*
3325     * Handle a "super" method call.
3326     *
3327     * for: invoke-super, invoke-super/range
3328     */
3329    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3330    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3331    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3332    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3333    .if     (!1)
3334    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3335    .endif
3336    FETCH(r1, 1)                        @ r1<- BBBB
3337    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3338    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3339    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3340    cmp     r2, #0                      @ null "this"?
3341    ldr     r9, [rSELF, #offThread_method] @ r9<- current method
3342    beq     common_errNullObject        @ null "this", throw exception
3343    cmp     r0, #0                      @ already resolved?
3344    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
3345    EXPORT_PC()                         @ must export for invoke
3346    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ resolved, continue on
3347    b       .LOP_INVOKE_SUPER_RANGE_resolve         @ do resolve now
3348
3349
3350/* ------------------------------ */
3351    .balign 64
3352.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
3353/* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */
3354/* File: armv5te/OP_INVOKE_DIRECT.S */
3355    /*
3356     * Handle a direct method call.
3357     *
3358     * (We could defer the "is 'this' pointer null" test to the common
3359     * method invocation code, and use a flag to indicate that static
3360     * calls don't count.  If we do this as part of copying the arguments
3361     * out we could avoiding loading the first arg twice.)
3362     *
3363     * for: invoke-direct, invoke-direct/range
3364     */
3365    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3366    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3367    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3368    FETCH(r1, 1)                        @ r1<- BBBB
3369    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3370    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3371    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3372    .if     (!1)
3373    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3374    .endif
3375    cmp     r0, #0                      @ already resolved?
3376    EXPORT_PC()                         @ must export for invoke
3377    GET_VREG(r2, r10)                   @ r2<- "this" ptr
3378    beq     .LOP_INVOKE_DIRECT_RANGE_resolve         @ not resolved, do it now
3379.LOP_INVOKE_DIRECT_RANGE_finish:
3380    cmp     r2, #0                      @ null "this" ref?
3381    bne     common_invokeMethodRange   @ no, continue on
3382    b       common_errNullObject        @ yes, throw exception
3383
3384
3385/* ------------------------------ */
3386    .balign 64
3387.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */
3388/* File: armv5te/OP_INVOKE_STATIC_RANGE.S */
3389/* File: armv5te/OP_INVOKE_STATIC.S */
3390    /*
3391     * Handle a static method call.
3392     *
3393     * for: invoke-static, invoke-static/range
3394     */
3395    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3396    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3397    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3398    FETCH(r1, 1)                        @ r1<- BBBB
3399    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3400    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3401    cmp     r0, #0                      @ already resolved?
3402    EXPORT_PC()                         @ must export for invoke
3403    bne     common_invokeMethodRange @ yes, continue on
34040:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
3405    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3406    mov     r2, #METHOD_STATIC          @ resolver method type
3407    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3408    cmp     r0, #0                      @ got null?
3409    bne     common_invokeMethodRange @ no, continue
3410    b       common_exceptionThrown      @ yes, handle exception
3411
3412
3413/* ------------------------------ */
3414    .balign 64
3415.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
3416/* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */
3417/* File: armv5te/OP_INVOKE_INTERFACE.S */
3418    /*
3419     * Handle an interface method call.
3420     *
3421     * for: invoke-interface, invoke-interface/range
3422     */
3423    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3424    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3425    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3426    FETCH(r1, 1)                        @ r1<- BBBB
3427    .if     (!1)
3428    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3429    .endif
3430    EXPORT_PC()                         @ must export for invoke
3431    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
3432    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- methodClassDex
3433    cmp     r0, #0                      @ null obj?
3434    ldr     r2, [rSELF, #offThread_method]  @ r2<- method
3435    beq     common_errNullObject        @ yes, fail
3436    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
3437    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3438    cmp     r0, #0                      @ failed?
3439    beq     common_exceptionThrown      @ yes, handle exception
3440    b       common_invokeMethodRange @ jump to common handler
3441
3442
3443/* ------------------------------ */
3444    .balign 64
3445.L_OP_UNUSED_79: /* 0x79 */
3446/* File: armv5te/OP_UNUSED_79.S */
3447/* File: armv5te/unused.S */
3448    bl      common_abort
3449
3450
3451/* ------------------------------ */
3452    .balign 64
3453.L_OP_UNUSED_7A: /* 0x7a */
3454/* File: armv5te/OP_UNUSED_7A.S */
3455/* File: armv5te/unused.S */
3456    bl      common_abort
3457
3458
3459/* ------------------------------ */
3460    .balign 64
3461.L_OP_NEG_INT: /* 0x7b */
3462/* File: armv6t2/OP_NEG_INT.S */
3463/* File: armv6t2/unop.S */
3464    /*
3465     * Generic 32-bit unary operation.  Provide an "instr" line that
3466     * specifies an instruction that performs "result = op r0".
3467     * This could be an ARM instruction or a function call.
3468     *
3469     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3470     *      int-to-byte, int-to-char, int-to-short
3471     */
3472    /* unop vA, vB */
3473    mov     r3, rINST, lsr #12          @ r3<- B
3474    ubfx    r9, rINST, #8, #4           @ r9<- A
3475    GET_VREG(r0, r3)                    @ r0<- vB
3476                               @ optional op; may set condition codes
3477    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3478    rsb     r0, r0, #0                              @ r0<- op, r0-r3 changed
3479    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3480    SET_VREG(r0, r9)                    @ vAA<- r0
3481    GOTO_OPCODE(ip)                     @ jump to next instruction
3482    /* 8-9 instructions */
3483
3484
3485/* ------------------------------ */
3486    .balign 64
3487.L_OP_NOT_INT: /* 0x7c */
3488/* File: armv6t2/OP_NOT_INT.S */
3489/* File: armv6t2/unop.S */
3490    /*
3491     * Generic 32-bit unary operation.  Provide an "instr" line that
3492     * specifies an instruction that performs "result = op r0".
3493     * This could be an ARM instruction or a function call.
3494     *
3495     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3496     *      int-to-byte, int-to-char, int-to-short
3497     */
3498    /* unop vA, vB */
3499    mov     r3, rINST, lsr #12          @ r3<- B
3500    ubfx    r9, rINST, #8, #4           @ r9<- A
3501    GET_VREG(r0, r3)                    @ r0<- vB
3502                               @ optional op; may set condition codes
3503    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3504    mvn     r0, r0                              @ r0<- op, r0-r3 changed
3505    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3506    SET_VREG(r0, r9)                    @ vAA<- r0
3507    GOTO_OPCODE(ip)                     @ jump to next instruction
3508    /* 8-9 instructions */
3509
3510
3511/* ------------------------------ */
3512    .balign 64
3513.L_OP_NEG_LONG: /* 0x7d */
3514/* File: armv6t2/OP_NEG_LONG.S */
3515/* File: armv6t2/unopWide.S */
3516    /*
3517     * Generic 64-bit unary operation.  Provide an "instr" line that
3518     * specifies an instruction that performs "result = op r0/r1".
3519     * This could be an ARM instruction or a function call.
3520     *
3521     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3522     */
3523    /* unop vA, vB */
3524    mov     r3, rINST, lsr #12          @ r3<- B
3525    ubfx    r9, rINST, #8, #4           @ r9<- A
3526    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3527    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3528    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3529    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3530    rsbs    r0, r0, #0                           @ optional op; may set condition codes
3531    rsc     r1, r1, #0                              @ r0/r1<- op, r2-r3 changed
3532    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3533    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3534    GOTO_OPCODE(ip)                     @ jump to next instruction
3535    /* 10-11 instructions */
3536
3537
3538/* ------------------------------ */
3539    .balign 64
3540.L_OP_NOT_LONG: /* 0x7e */
3541/* File: armv6t2/OP_NOT_LONG.S */
3542/* File: armv6t2/unopWide.S */
3543    /*
3544     * Generic 64-bit unary operation.  Provide an "instr" line that
3545     * specifies an instruction that performs "result = op r0/r1".
3546     * This could be an ARM instruction or a function call.
3547     *
3548     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3549     */
3550    /* unop vA, vB */
3551    mov     r3, rINST, lsr #12          @ r3<- B
3552    ubfx    r9, rINST, #8, #4           @ r9<- A
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    /* 10-11 instructions */
3563
3564
3565/* ------------------------------ */
3566    .balign 64
3567.L_OP_NEG_FLOAT: /* 0x7f */
3568/* File: armv6t2/OP_NEG_FLOAT.S */
3569/* File: armv6t2/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    ubfx    r9, rINST, #8, #4           @ r9<- A
3581    GET_VREG(r0, r3)                    @ r0<- vB
3582                               @ optional op; may set condition codes
3583    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3584    add     r0, r0, #0x80000000                              @ r0<- op, r0-r3 changed
3585    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3586    SET_VREG(r0, r9)                    @ vAA<- r0
3587    GOTO_OPCODE(ip)                     @ jump to next instruction
3588    /* 8-9 instructions */
3589
3590
3591/* ------------------------------ */
3592    .balign 64
3593.L_OP_NEG_DOUBLE: /* 0x80 */
3594/* File: armv6t2/OP_NEG_DOUBLE.S */
3595/* File: armv6t2/unopWide.S */
3596    /*
3597     * Generic 64-bit unary operation.  Provide an "instr" line that
3598     * specifies an instruction that performs "result = op r0/r1".
3599     * This could be an ARM instruction or a function call.
3600     *
3601     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3602     */
3603    /* unop vA, vB */
3604    mov     r3, rINST, lsr #12          @ r3<- B
3605    ubfx    r9, rINST, #8, #4           @ r9<- A
3606    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3607    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3608    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3609    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3610                               @ optional op; may set condition codes
3611    add     r1, r1, #0x80000000                              @ r0/r1<- op, r2-r3 changed
3612    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3613    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3614    GOTO_OPCODE(ip)                     @ jump to next instruction
3615    /* 10-11 instructions */
3616
3617
3618/* ------------------------------ */
3619    .balign 64
3620.L_OP_INT_TO_LONG: /* 0x81 */
3621/* File: armv6t2/OP_INT_TO_LONG.S */
3622/* File: armv6t2/unopWider.S */
3623    /*
3624     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3625     * that specifies an instruction that performs "result = op r0", where
3626     * "result" is a 64-bit quantity in r0/r1.
3627     *
3628     * For: int-to-long, int-to-double, float-to-long, float-to-double
3629     */
3630    /* unop vA, vB */
3631    mov     r3, rINST, lsr #12          @ r3<- B
3632    ubfx    r9, rINST, #8, #4           @ r9<- A
3633    GET_VREG(r0, r3)                    @ r0<- vB
3634    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3635                               @ optional op; may set condition codes
3636    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3637    mov     r1, r0, asr #31                              @ r0<- op, r0-r3 changed
3638    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3639    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3640    GOTO_OPCODE(ip)                     @ jump to next instruction
3641    /* 9-10 instructions */
3642
3643
3644/* ------------------------------ */
3645    .balign 64
3646.L_OP_INT_TO_FLOAT: /* 0x82 */
3647/* File: arm-vfp/OP_INT_TO_FLOAT.S */
3648/* File: arm-vfp/funop.S */
3649    /*
3650     * Generic 32-bit unary floating-point operation.  Provide an "instr"
3651     * line that specifies an instruction that performs "s1 = op s0".
3652     *
3653     * for: int-to-float, float-to-int
3654     */
3655    /* unop vA, vB */
3656    mov     r3, rINST, lsr #12          @ r3<- B
3657    mov     r9, rINST, lsr #8           @ r9<- A+
3658    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3659    flds    s0, [r3]                    @ s0<- vB
3660    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3661    and     r9, r9, #15                 @ r9<- A
3662    fsitos  s1, s0                              @ s1<- op
3663    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3664    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3665    fsts    s1, [r9]                    @ vA<- s1
3666    GOTO_OPCODE(ip)                     @ jump to next instruction
3667
3668
3669/* ------------------------------ */
3670    .balign 64
3671.L_OP_INT_TO_DOUBLE: /* 0x83 */
3672/* File: arm-vfp/OP_INT_TO_DOUBLE.S */
3673/* File: arm-vfp/funopWider.S */
3674    /*
3675     * Generic 32bit-to-64bit floating point unary operation.  Provide an
3676     * "instr" line that specifies an instruction that performs "d0 = op s0".
3677     *
3678     * For: int-to-double, float-to-double
3679     */
3680    /* unop vA, vB */
3681    mov     r3, rINST, lsr #12          @ r3<- B
3682    mov     r9, rINST, lsr #8           @ r9<- A+
3683    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3684    flds    s0, [r3]                    @ s0<- vB
3685    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3686    and     r9, r9, #15                 @ r9<- A
3687    fsitod  d0, s0                              @ d0<- op
3688    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3689    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3690    fstd    d0, [r9]                    @ vA<- d0
3691    GOTO_OPCODE(ip)                     @ jump to next instruction
3692
3693
3694/* ------------------------------ */
3695    .balign 64
3696.L_OP_LONG_TO_INT: /* 0x84 */
3697/* File: armv5te/OP_LONG_TO_INT.S */
3698/* we ignore the high word, making this equivalent to a 32-bit reg move */
3699/* File: armv5te/OP_MOVE.S */
3700    /* for move, move-object, long-to-int */
3701    /* op vA, vB */
3702    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
3703    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
3704    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3705    GET_VREG(r2, r1)                    @ r2<- fp[B]
3706    and     r0, r0, #15
3707    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
3708    SET_VREG(r2, r0)                    @ fp[A]<- r2
3709    GOTO_OPCODE(ip)                     @ execute next instruction
3710
3711
3712/* ------------------------------ */
3713    .balign 64
3714.L_OP_LONG_TO_FLOAT: /* 0x85 */
3715/* File: armv6t2/OP_LONG_TO_FLOAT.S */
3716/* File: armv6t2/unopNarrower.S */
3717    /*
3718     * Generic 64bit-to-32bit unary operation.  Provide an "instr" line
3719     * that specifies an instruction that performs "result = op r0/r1", where
3720     * "result" is a 32-bit quantity in r0.
3721     *
3722     * For: long-to-float, double-to-int, double-to-float
3723     *
3724     * (This would work for long-to-int, but that instruction is actually
3725     * an exact match for OP_MOVE.)
3726     */
3727    /* unop vA, vB */
3728    mov     r3, rINST, lsr #12          @ r3<- B
3729    ubfx    r9, rINST, #8, #4           @ r9<- A
3730    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3731    ldmia   r3, {r0-r1}                 @ r0/r1<- vB/vB+1
3732    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3733                               @ optional op; may set condition codes
3734    bl      __aeabi_l2f                              @ r0<- op, r0-r3 changed
3735    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3736    SET_VREG(r0, r9)                    @ vA<- r0
3737    GOTO_OPCODE(ip)                     @ jump to next instruction
3738    /* 9-10 instructions */
3739
3740
3741/* ------------------------------ */
3742    .balign 64
3743.L_OP_LONG_TO_DOUBLE: /* 0x86 */
3744/* File: armv6t2/OP_LONG_TO_DOUBLE.S */
3745/* File: armv6t2/unopWide.S */
3746    /*
3747     * Generic 64-bit unary operation.  Provide an "instr" line that
3748     * specifies an instruction that performs "result = op r0/r1".
3749     * This could be an ARM instruction or a function call.
3750     *
3751     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3752     */
3753    /* unop vA, vB */
3754    mov     r3, rINST, lsr #12          @ r3<- B
3755    ubfx    r9, rINST, #8, #4           @ r9<- A
3756    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3757    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3758    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3759    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3760                               @ optional op; may set condition codes
3761    bl      __aeabi_l2d                              @ r0/r1<- op, r2-r3 changed
3762    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3763    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3764    GOTO_OPCODE(ip)                     @ jump to next instruction
3765    /* 10-11 instructions */
3766
3767
3768/* ------------------------------ */
3769    .balign 64
3770.L_OP_FLOAT_TO_INT: /* 0x87 */
3771/* File: arm-vfp/OP_FLOAT_TO_INT.S */
3772/* File: arm-vfp/funop.S */
3773    /*
3774     * Generic 32-bit unary floating-point operation.  Provide an "instr"
3775     * line that specifies an instruction that performs "s1 = op s0".
3776     *
3777     * for: int-to-float, float-to-int
3778     */
3779    /* unop vA, vB */
3780    mov     r3, rINST, lsr #12          @ r3<- B
3781    mov     r9, rINST, lsr #8           @ r9<- A+
3782    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3783    flds    s0, [r3]                    @ s0<- vB
3784    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3785    and     r9, r9, #15                 @ r9<- A
3786    ftosizs s1, s0                              @ s1<- op
3787    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3788    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3789    fsts    s1, [r9]                    @ vA<- s1
3790    GOTO_OPCODE(ip)                     @ jump to next instruction
3791
3792
3793/* ------------------------------ */
3794    .balign 64
3795.L_OP_FLOAT_TO_LONG: /* 0x88 */
3796/* File: armv6t2/OP_FLOAT_TO_LONG.S */
3797@include "armv6t2/unopWider.S" {"instr":"bl      __aeabi_f2lz"}
3798/* File: armv6t2/unopWider.S */
3799    /*
3800     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3801     * that specifies an instruction that performs "result = op r0", where
3802     * "result" is a 64-bit quantity in r0/r1.
3803     *
3804     * For: int-to-long, int-to-double, float-to-long, float-to-double
3805     */
3806    /* unop vA, vB */
3807    mov     r3, rINST, lsr #12          @ r3<- B
3808    ubfx    r9, rINST, #8, #4           @ r9<- A
3809    GET_VREG(r0, r3)                    @ r0<- vB
3810    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3811                               @ optional op; may set condition codes
3812    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3813    bl      f2l_doconv                              @ r0<- op, r0-r3 changed
3814    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3815    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3816    GOTO_OPCODE(ip)                     @ jump to next instruction
3817    /* 9-10 instructions */
3818
3819
3820
3821/* ------------------------------ */
3822    .balign 64
3823.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */
3824/* File: arm-vfp/OP_FLOAT_TO_DOUBLE.S */
3825/* File: arm-vfp/funopWider.S */
3826    /*
3827     * Generic 32bit-to-64bit floating point unary operation.  Provide an
3828     * "instr" line that specifies an instruction that performs "d0 = op s0".
3829     *
3830     * For: int-to-double, float-to-double
3831     */
3832    /* unop vA, vB */
3833    mov     r3, rINST, lsr #12          @ r3<- B
3834    mov     r9, rINST, lsr #8           @ r9<- A+
3835    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3836    flds    s0, [r3]                    @ s0<- vB
3837    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3838    and     r9, r9, #15                 @ r9<- A
3839    fcvtds  d0, s0                              @ d0<- op
3840    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3841    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3842    fstd    d0, [r9]                    @ vA<- d0
3843    GOTO_OPCODE(ip)                     @ jump to next instruction
3844
3845
3846/* ------------------------------ */
3847    .balign 64
3848.L_OP_DOUBLE_TO_INT: /* 0x8a */
3849/* File: arm-vfp/OP_DOUBLE_TO_INT.S */
3850/* File: arm-vfp/funopNarrower.S */
3851    /*
3852     * Generic 64bit-to-32bit unary floating point operation.  Provide an
3853     * "instr" line that specifies an instruction that performs "s0 = op d0".
3854     *
3855     * For: double-to-int, double-to-float
3856     */
3857    /* unop vA, vB */
3858    mov     r3, rINST, lsr #12          @ r3<- B
3859    mov     r9, rINST, lsr #8           @ r9<- A+
3860    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3861    fldd    d0, [r3]                    @ d0<- vB
3862    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3863    and     r9, r9, #15                 @ r9<- A
3864    ftosizd  s0, d0                              @ s0<- op
3865    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3866    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3867    fsts    s0, [r9]                    @ vA<- s0
3868    GOTO_OPCODE(ip)                     @ jump to next instruction
3869
3870
3871/* ------------------------------ */
3872    .balign 64
3873.L_OP_DOUBLE_TO_LONG: /* 0x8b */
3874/* File: armv6t2/OP_DOUBLE_TO_LONG.S */
3875@include "armv6t2/unopWide.S" {"instr":"bl      __aeabi_d2lz"}
3876/* File: armv6t2/unopWide.S */
3877    /*
3878     * Generic 64-bit unary operation.  Provide an "instr" line that
3879     * specifies an instruction that performs "result = op r0/r1".
3880     * This could be an ARM instruction or a function call.
3881     *
3882     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3883     */
3884    /* unop vA, vB */
3885    mov     r3, rINST, lsr #12          @ r3<- B
3886    ubfx    r9, rINST, #8, #4           @ r9<- A
3887    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3888    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3889    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3890    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3891                               @ optional op; may set condition codes
3892    bl      d2l_doconv                              @ r0/r1<- op, r2-r3 changed
3893    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3894    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3895    GOTO_OPCODE(ip)                     @ jump to next instruction
3896    /* 10-11 instructions */
3897
3898
3899
3900/* ------------------------------ */
3901    .balign 64
3902.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */
3903/* File: arm-vfp/OP_DOUBLE_TO_FLOAT.S */
3904/* File: arm-vfp/funopNarrower.S */
3905    /*
3906     * Generic 64bit-to-32bit unary floating point operation.  Provide an
3907     * "instr" line that specifies an instruction that performs "s0 = op d0".
3908     *
3909     * For: double-to-int, double-to-float
3910     */
3911    /* unop vA, vB */
3912    mov     r3, rINST, lsr #12          @ r3<- B
3913    mov     r9, rINST, lsr #8           @ r9<- A+
3914    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3915    fldd    d0, [r3]                    @ d0<- vB
3916    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3917    and     r9, r9, #15                 @ r9<- A
3918    fcvtsd  s0, d0                              @ s0<- op
3919    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3920    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3921    fsts    s0, [r9]                    @ vA<- s0
3922    GOTO_OPCODE(ip)                     @ jump to next instruction
3923
3924
3925/* ------------------------------ */
3926    .balign 64
3927.L_OP_INT_TO_BYTE: /* 0x8d */
3928/* File: armv6t2/OP_INT_TO_BYTE.S */
3929/* File: armv6t2/unop.S */
3930    /*
3931     * Generic 32-bit unary operation.  Provide an "instr" line that
3932     * specifies an instruction that performs "result = op r0".
3933     * This could be an ARM instruction or a function call.
3934     *
3935     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3936     *      int-to-byte, int-to-char, int-to-short
3937     */
3938    /* unop vA, vB */
3939    mov     r3, rINST, lsr #12          @ r3<- B
3940    ubfx    r9, rINST, #8, #4           @ r9<- A
3941    GET_VREG(r0, r3)                    @ r0<- vB
3942                               @ optional op; may set condition codes
3943    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3944    sxtb    r0, r0                              @ r0<- op, r0-r3 changed
3945    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3946    SET_VREG(r0, r9)                    @ vAA<- r0
3947    GOTO_OPCODE(ip)                     @ jump to next instruction
3948    /* 8-9 instructions */
3949
3950
3951/* ------------------------------ */
3952    .balign 64
3953.L_OP_INT_TO_CHAR: /* 0x8e */
3954/* File: armv6t2/OP_INT_TO_CHAR.S */
3955/* File: armv6t2/unop.S */
3956    /*
3957     * Generic 32-bit unary operation.  Provide an "instr" line that
3958     * specifies an instruction that performs "result = op r0".
3959     * This could be an ARM instruction or a function call.
3960     *
3961     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3962     *      int-to-byte, int-to-char, int-to-short
3963     */
3964    /* unop vA, vB */
3965    mov     r3, rINST, lsr #12          @ r3<- B
3966    ubfx    r9, rINST, #8, #4           @ r9<- A
3967    GET_VREG(r0, r3)                    @ r0<- vB
3968                               @ optional op; may set condition codes
3969    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3970    uxth    r0, r0                              @ r0<- op, r0-r3 changed
3971    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3972    SET_VREG(r0, r9)                    @ vAA<- r0
3973    GOTO_OPCODE(ip)                     @ jump to next instruction
3974    /* 8-9 instructions */
3975
3976
3977/* ------------------------------ */
3978    .balign 64
3979.L_OP_INT_TO_SHORT: /* 0x8f */
3980/* File: armv6t2/OP_INT_TO_SHORT.S */
3981/* File: armv6t2/unop.S */
3982    /*
3983     * Generic 32-bit unary operation.  Provide an "instr" line that
3984     * specifies an instruction that performs "result = op r0".
3985     * This could be an ARM instruction or a function call.
3986     *
3987     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3988     *      int-to-byte, int-to-char, int-to-short
3989     */
3990    /* unop vA, vB */
3991    mov     r3, rINST, lsr #12          @ r3<- B
3992    ubfx    r9, rINST, #8, #4           @ r9<- A
3993    GET_VREG(r0, r3)                    @ r0<- vB
3994                               @ optional op; may set condition codes
3995    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3996    sxth    r0, r0                              @ r0<- op, r0-r3 changed
3997    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3998    SET_VREG(r0, r9)                    @ vAA<- r0
3999    GOTO_OPCODE(ip)                     @ jump to next instruction
4000    /* 8-9 instructions */
4001
4002
4003/* ------------------------------ */
4004    .balign 64
4005.L_OP_ADD_INT: /* 0x90 */
4006/* File: armv5te/OP_ADD_INT.S */
4007/* File: armv5te/binop.S */
4008    /*
4009     * Generic 32-bit binary operation.  Provide an "instr" line that
4010     * specifies an instruction that performs "result = r0 op r1".
4011     * This could be an ARM instruction or a function call.  (If the result
4012     * comes back in a register other than r0, you can override "result".)
4013     *
4014     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4015     * vCC (r1).  Useful for integer division and modulus.  Note that we
4016     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4017     * handles it correctly.
4018     *
4019     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4020     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4021     *      mul-float, div-float, rem-float
4022     */
4023    /* binop vAA, vBB, vCC */
4024    FETCH(r0, 1)                        @ r0<- CCBB
4025    mov     r9, rINST, lsr #8           @ r9<- AA
4026    mov     r3, r0, lsr #8              @ r3<- CC
4027    and     r2, r0, #255                @ r2<- BB
4028    GET_VREG(r1, r3)                    @ r1<- vCC
4029    GET_VREG(r0, r2)                    @ r0<- vBB
4030    .if 0
4031    cmp     r1, #0                      @ is second operand zero?
4032    beq     common_errDivideByZero
4033    .endif
4034
4035    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4036                               @ optional op; may set condition codes
4037    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
4038    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4039    SET_VREG(r0, r9)               @ vAA<- r0
4040    GOTO_OPCODE(ip)                     @ jump to next instruction
4041    /* 11-14 instructions */
4042
4043
4044/* ------------------------------ */
4045    .balign 64
4046.L_OP_SUB_INT: /* 0x91 */
4047/* File: armv5te/OP_SUB_INT.S */
4048/* File: armv5te/binop.S */
4049    /*
4050     * Generic 32-bit binary operation.  Provide an "instr" line that
4051     * specifies an instruction that performs "result = r0 op r1".
4052     * This could be an ARM instruction or a function call.  (If the result
4053     * comes back in a register other than r0, you can override "result".)
4054     *
4055     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4056     * vCC (r1).  Useful for integer division and modulus.  Note that we
4057     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4058     * handles it correctly.
4059     *
4060     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4061     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4062     *      mul-float, div-float, rem-float
4063     */
4064    /* binop vAA, vBB, vCC */
4065    FETCH(r0, 1)                        @ r0<- CCBB
4066    mov     r9, rINST, lsr #8           @ r9<- AA
4067    mov     r3, r0, lsr #8              @ r3<- CC
4068    and     r2, r0, #255                @ r2<- BB
4069    GET_VREG(r1, r3)                    @ r1<- vCC
4070    GET_VREG(r0, r2)                    @ r0<- vBB
4071    .if 0
4072    cmp     r1, #0                      @ is second operand zero?
4073    beq     common_errDivideByZero
4074    .endif
4075
4076    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4077                               @ optional op; may set condition codes
4078    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
4079    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4080    SET_VREG(r0, r9)               @ vAA<- r0
4081    GOTO_OPCODE(ip)                     @ jump to next instruction
4082    /* 11-14 instructions */
4083
4084
4085/* ------------------------------ */
4086    .balign 64
4087.L_OP_MUL_INT: /* 0x92 */
4088/* File: armv5te/OP_MUL_INT.S */
4089/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
4090/* File: armv5te/binop.S */
4091    /*
4092     * Generic 32-bit binary operation.  Provide an "instr" line that
4093     * specifies an instruction that performs "result = r0 op r1".
4094     * This could be an ARM instruction or a function call.  (If the result
4095     * comes back in a register other than r0, you can override "result".)
4096     *
4097     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4098     * vCC (r1).  Useful for integer division and modulus.  Note that we
4099     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4100     * handles it correctly.
4101     *
4102     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4103     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4104     *      mul-float, div-float, rem-float
4105     */
4106    /* binop vAA, vBB, vCC */
4107    FETCH(r0, 1)                        @ r0<- CCBB
4108    mov     r9, rINST, lsr #8           @ r9<- AA
4109    mov     r3, r0, lsr #8              @ r3<- CC
4110    and     r2, r0, #255                @ r2<- BB
4111    GET_VREG(r1, r3)                    @ r1<- vCC
4112    GET_VREG(r0, r2)                    @ r0<- vBB
4113    .if 0
4114    cmp     r1, #0                      @ is second operand zero?
4115    beq     common_errDivideByZero
4116    .endif
4117
4118    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4119                               @ optional op; may set condition codes
4120    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
4121    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4122    SET_VREG(r0, r9)               @ vAA<- r0
4123    GOTO_OPCODE(ip)                     @ jump to next instruction
4124    /* 11-14 instructions */
4125
4126
4127/* ------------------------------ */
4128    .balign 64
4129.L_OP_DIV_INT: /* 0x93 */
4130/* File: armv5te/OP_DIV_INT.S */
4131/* File: armv5te/binop.S */
4132    /*
4133     * Generic 32-bit binary operation.  Provide an "instr" line that
4134     * specifies an instruction that performs "result = r0 op r1".
4135     * This could be an ARM instruction or a function call.  (If the result
4136     * comes back in a register other than r0, you can override "result".)
4137     *
4138     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4139     * vCC (r1).  Useful for integer division and modulus.  Note that we
4140     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4141     * handles it correctly.
4142     *
4143     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4144     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4145     *      mul-float, div-float, rem-float
4146     */
4147    /* binop vAA, vBB, vCC */
4148    FETCH(r0, 1)                        @ r0<- CCBB
4149    mov     r9, rINST, lsr #8           @ r9<- AA
4150    mov     r3, r0, lsr #8              @ r3<- CC
4151    and     r2, r0, #255                @ r2<- BB
4152    GET_VREG(r1, r3)                    @ r1<- vCC
4153    GET_VREG(r0, r2)                    @ r0<- vBB
4154    .if 1
4155    cmp     r1, #0                      @ is second operand zero?
4156    beq     common_errDivideByZero
4157    .endif
4158
4159    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4160                               @ optional op; may set condition codes
4161    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
4162    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4163    SET_VREG(r0, r9)               @ vAA<- r0
4164    GOTO_OPCODE(ip)                     @ jump to next instruction
4165    /* 11-14 instructions */
4166
4167
4168/* ------------------------------ */
4169    .balign 64
4170.L_OP_REM_INT: /* 0x94 */
4171/* File: armv5te/OP_REM_INT.S */
4172/* idivmod returns quotient in r0 and remainder in r1 */
4173/* File: armv5te/binop.S */
4174    /*
4175     * Generic 32-bit binary operation.  Provide an "instr" line that
4176     * specifies an instruction that performs "result = r0 op r1".
4177     * This could be an ARM instruction or a function call.  (If the result
4178     * comes back in a register other than r0, you can override "result".)
4179     *
4180     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4181     * vCC (r1).  Useful for integer division and modulus.  Note that we
4182     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4183     * handles it correctly.
4184     *
4185     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4186     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4187     *      mul-float, div-float, rem-float
4188     */
4189    /* binop vAA, vBB, vCC */
4190    FETCH(r0, 1)                        @ r0<- CCBB
4191    mov     r9, rINST, lsr #8           @ r9<- AA
4192    mov     r3, r0, lsr #8              @ r3<- CC
4193    and     r2, r0, #255                @ r2<- BB
4194    GET_VREG(r1, r3)                    @ r1<- vCC
4195    GET_VREG(r0, r2)                    @ r0<- vBB
4196    .if 1
4197    cmp     r1, #0                      @ is second operand zero?
4198    beq     common_errDivideByZero
4199    .endif
4200
4201    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4202                               @ optional op; may set condition codes
4203    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
4204    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4205    SET_VREG(r1, r9)               @ vAA<- r1
4206    GOTO_OPCODE(ip)                     @ jump to next instruction
4207    /* 11-14 instructions */
4208
4209
4210/* ------------------------------ */
4211    .balign 64
4212.L_OP_AND_INT: /* 0x95 */
4213/* File: armv5te/OP_AND_INT.S */
4214/* File: armv5te/binop.S */
4215    /*
4216     * Generic 32-bit binary operation.  Provide an "instr" line that
4217     * specifies an instruction that performs "result = r0 op r1".
4218     * This could be an ARM instruction or a function call.  (If the result
4219     * comes back in a register other than r0, you can override "result".)
4220     *
4221     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4222     * vCC (r1).  Useful for integer division and modulus.  Note that we
4223     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4224     * handles it correctly.
4225     *
4226     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4227     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4228     *      mul-float, div-float, rem-float
4229     */
4230    /* binop vAA, vBB, vCC */
4231    FETCH(r0, 1)                        @ r0<- CCBB
4232    mov     r9, rINST, lsr #8           @ r9<- AA
4233    mov     r3, r0, lsr #8              @ r3<- CC
4234    and     r2, r0, #255                @ r2<- BB
4235    GET_VREG(r1, r3)                    @ r1<- vCC
4236    GET_VREG(r0, r2)                    @ r0<- vBB
4237    .if 0
4238    cmp     r1, #0                      @ is second operand zero?
4239    beq     common_errDivideByZero
4240    .endif
4241
4242    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4243                               @ optional op; may set condition codes
4244    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
4245    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4246    SET_VREG(r0, r9)               @ vAA<- r0
4247    GOTO_OPCODE(ip)                     @ jump to next instruction
4248    /* 11-14 instructions */
4249
4250
4251/* ------------------------------ */
4252    .balign 64
4253.L_OP_OR_INT: /* 0x96 */
4254/* File: armv5te/OP_OR_INT.S */
4255/* File: armv5te/binop.S */
4256    /*
4257     * Generic 32-bit binary operation.  Provide an "instr" line that
4258     * specifies an instruction that performs "result = r0 op r1".
4259     * This could be an ARM instruction or a function call.  (If the result
4260     * comes back in a register other than r0, you can override "result".)
4261     *
4262     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4263     * vCC (r1).  Useful for integer division and modulus.  Note that we
4264     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4265     * handles it correctly.
4266     *
4267     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4268     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4269     *      mul-float, div-float, rem-float
4270     */
4271    /* binop vAA, vBB, vCC */
4272    FETCH(r0, 1)                        @ r0<- CCBB
4273    mov     r9, rINST, lsr #8           @ r9<- AA
4274    mov     r3, r0, lsr #8              @ r3<- CC
4275    and     r2, r0, #255                @ r2<- BB
4276    GET_VREG(r1, r3)                    @ r1<- vCC
4277    GET_VREG(r0, r2)                    @ r0<- vBB
4278    .if 0
4279    cmp     r1, #0                      @ is second operand zero?
4280    beq     common_errDivideByZero
4281    .endif
4282
4283    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4284                               @ optional op; may set condition codes
4285    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
4286    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4287    SET_VREG(r0, r9)               @ vAA<- r0
4288    GOTO_OPCODE(ip)                     @ jump to next instruction
4289    /* 11-14 instructions */
4290
4291
4292/* ------------------------------ */
4293    .balign 64
4294.L_OP_XOR_INT: /* 0x97 */
4295/* File: armv5te/OP_XOR_INT.S */
4296/* File: armv5te/binop.S */
4297    /*
4298     * Generic 32-bit binary operation.  Provide an "instr" line that
4299     * specifies an instruction that performs "result = r0 op r1".
4300     * This could be an ARM instruction or a function call.  (If the result
4301     * comes back in a register other than r0, you can override "result".)
4302     *
4303     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4304     * vCC (r1).  Useful for integer division and modulus.  Note that we
4305     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4306     * handles it correctly.
4307     *
4308     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4309     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4310     *      mul-float, div-float, rem-float
4311     */
4312    /* binop vAA, vBB, vCC */
4313    FETCH(r0, 1)                        @ r0<- CCBB
4314    mov     r9, rINST, lsr #8           @ r9<- AA
4315    mov     r3, r0, lsr #8              @ r3<- CC
4316    and     r2, r0, #255                @ r2<- BB
4317    GET_VREG(r1, r3)                    @ r1<- vCC
4318    GET_VREG(r0, r2)                    @ r0<- vBB
4319    .if 0
4320    cmp     r1, #0                      @ is second operand zero?
4321    beq     common_errDivideByZero
4322    .endif
4323
4324    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4325                               @ optional op; may set condition codes
4326    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
4327    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4328    SET_VREG(r0, r9)               @ vAA<- r0
4329    GOTO_OPCODE(ip)                     @ jump to next instruction
4330    /* 11-14 instructions */
4331
4332
4333/* ------------------------------ */
4334    .balign 64
4335.L_OP_SHL_INT: /* 0x98 */
4336/* File: armv5te/OP_SHL_INT.S */
4337/* File: armv5te/binop.S */
4338    /*
4339     * Generic 32-bit binary operation.  Provide an "instr" line that
4340     * specifies an instruction that performs "result = r0 op r1".
4341     * This could be an ARM instruction or a function call.  (If the result
4342     * comes back in a register other than r0, you can override "result".)
4343     *
4344     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4345     * vCC (r1).  Useful for integer division and modulus.  Note that we
4346     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4347     * handles it correctly.
4348     *
4349     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4350     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4351     *      mul-float, div-float, rem-float
4352     */
4353    /* binop vAA, vBB, vCC */
4354    FETCH(r0, 1)                        @ r0<- CCBB
4355    mov     r9, rINST, lsr #8           @ r9<- AA
4356    mov     r3, r0, lsr #8              @ r3<- CC
4357    and     r2, r0, #255                @ r2<- BB
4358    GET_VREG(r1, r3)                    @ r1<- vCC
4359    GET_VREG(r0, r2)                    @ r0<- vBB
4360    .if 0
4361    cmp     r1, #0                      @ is second operand zero?
4362    beq     common_errDivideByZero
4363    .endif
4364
4365    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4366    and     r1, r1, #31                           @ optional op; may set condition codes
4367    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
4368    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4369    SET_VREG(r0, r9)               @ vAA<- r0
4370    GOTO_OPCODE(ip)                     @ jump to next instruction
4371    /* 11-14 instructions */
4372
4373
4374/* ------------------------------ */
4375    .balign 64
4376.L_OP_SHR_INT: /* 0x99 */
4377/* File: armv5te/OP_SHR_INT.S */
4378/* File: armv5te/binop.S */
4379    /*
4380     * Generic 32-bit binary operation.  Provide an "instr" line that
4381     * specifies an instruction that performs "result = r0 op r1".
4382     * This could be an ARM instruction or a function call.  (If the result
4383     * comes back in a register other than r0, you can override "result".)
4384     *
4385     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4386     * vCC (r1).  Useful for integer division and modulus.  Note that we
4387     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4388     * handles it correctly.
4389     *
4390     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4391     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4392     *      mul-float, div-float, rem-float
4393     */
4394    /* binop vAA, vBB, vCC */
4395    FETCH(r0, 1)                        @ r0<- CCBB
4396    mov     r9, rINST, lsr #8           @ r9<- AA
4397    mov     r3, r0, lsr #8              @ r3<- CC
4398    and     r2, r0, #255                @ r2<- BB
4399    GET_VREG(r1, r3)                    @ r1<- vCC
4400    GET_VREG(r0, r2)                    @ r0<- vBB
4401    .if 0
4402    cmp     r1, #0                      @ is second operand zero?
4403    beq     common_errDivideByZero
4404    .endif
4405
4406    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4407    and     r1, r1, #31                           @ optional op; may set condition codes
4408    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
4409    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4410    SET_VREG(r0, r9)               @ vAA<- r0
4411    GOTO_OPCODE(ip)                     @ jump to next instruction
4412    /* 11-14 instructions */
4413
4414
4415/* ------------------------------ */
4416    .balign 64
4417.L_OP_USHR_INT: /* 0x9a */
4418/* File: armv5te/OP_USHR_INT.S */
4419/* File: armv5te/binop.S */
4420    /*
4421     * Generic 32-bit binary operation.  Provide an "instr" line that
4422     * specifies an instruction that performs "result = r0 op r1".
4423     * This could be an ARM instruction or a function call.  (If the result
4424     * comes back in a register other than r0, you can override "result".)
4425     *
4426     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4427     * vCC (r1).  Useful for integer division and modulus.  Note that we
4428     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4429     * handles it correctly.
4430     *
4431     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4432     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4433     *      mul-float, div-float, rem-float
4434     */
4435    /* binop vAA, vBB, vCC */
4436    FETCH(r0, 1)                        @ r0<- CCBB
4437    mov     r9, rINST, lsr #8           @ r9<- AA
4438    mov     r3, r0, lsr #8              @ r3<- CC
4439    and     r2, r0, #255                @ r2<- BB
4440    GET_VREG(r1, r3)                    @ r1<- vCC
4441    GET_VREG(r0, r2)                    @ r0<- vBB
4442    .if 0
4443    cmp     r1, #0                      @ is second operand zero?
4444    beq     common_errDivideByZero
4445    .endif
4446
4447    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4448    and     r1, r1, #31                           @ optional op; may set condition codes
4449    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
4450    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4451    SET_VREG(r0, r9)               @ vAA<- r0
4452    GOTO_OPCODE(ip)                     @ jump to next instruction
4453    /* 11-14 instructions */
4454
4455
4456/* ------------------------------ */
4457    .balign 64
4458.L_OP_ADD_LONG: /* 0x9b */
4459/* File: armv5te/OP_ADD_LONG.S */
4460/* File: armv5te/binopWide.S */
4461    /*
4462     * Generic 64-bit binary operation.  Provide an "instr" line that
4463     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4464     * This could be an ARM instruction or a function call.  (If the result
4465     * comes back in a register other than r0, you can override "result".)
4466     *
4467     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4468     * vCC (r1).  Useful for integer division and modulus.
4469     *
4470     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4471     *      xor-long, add-double, sub-double, mul-double, div-double,
4472     *      rem-double
4473     *
4474     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4475     */
4476    /* binop vAA, vBB, vCC */
4477    FETCH(r0, 1)                        @ r0<- CCBB
4478    mov     r9, rINST, lsr #8           @ r9<- AA
4479    and     r2, r0, #255                @ r2<- BB
4480    mov     r3, r0, lsr #8              @ r3<- CC
4481    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4482    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4483    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4484    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4485    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4486    .if 0
4487    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4488    beq     common_errDivideByZero
4489    .endif
4490    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4491
4492    adds    r0, r0, r2                           @ optional op; may set condition codes
4493    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
4494    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4495    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4496    GOTO_OPCODE(ip)                     @ jump to next instruction
4497    /* 14-17 instructions */
4498
4499
4500/* ------------------------------ */
4501    .balign 64
4502.L_OP_SUB_LONG: /* 0x9c */
4503/* File: armv5te/OP_SUB_LONG.S */
4504/* File: armv5te/binopWide.S */
4505    /*
4506     * Generic 64-bit binary operation.  Provide an "instr" line that
4507     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4508     * This could be an ARM instruction or a function call.  (If the result
4509     * comes back in a register other than r0, you can override "result".)
4510     *
4511     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4512     * vCC (r1).  Useful for integer division and modulus.
4513     *
4514     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4515     *      xor-long, add-double, sub-double, mul-double, div-double,
4516     *      rem-double
4517     *
4518     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4519     */
4520    /* binop vAA, vBB, vCC */
4521    FETCH(r0, 1)                        @ r0<- CCBB
4522    mov     r9, rINST, lsr #8           @ r9<- AA
4523    and     r2, r0, #255                @ r2<- BB
4524    mov     r3, r0, lsr #8              @ r3<- CC
4525    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4526    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4527    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4528    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4529    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4530    .if 0
4531    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4532    beq     common_errDivideByZero
4533    .endif
4534    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4535
4536    subs    r0, r0, r2                           @ optional op; may set condition codes
4537    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
4538    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4539    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4540    GOTO_OPCODE(ip)                     @ jump to next instruction
4541    /* 14-17 instructions */
4542
4543
4544/* ------------------------------ */
4545    .balign 64
4546.L_OP_MUL_LONG: /* 0x9d */
4547/* File: armv5te/OP_MUL_LONG.S */
4548    /*
4549     * Signed 64-bit integer multiply.
4550     *
4551     * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
4552     *        WX
4553     *      x YZ
4554     *  --------
4555     *     ZW ZX
4556     *  YW YX
4557     *
4558     * The low word of the result holds ZX, the high word holds
4559     * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
4560     * it doesn't fit in the low 64 bits.
4561     *
4562     * Unlike most ARM math operations, multiply instructions have
4563     * restrictions on using the same register more than once (Rd and Rm
4564     * cannot be the same).
4565     */
4566    /* mul-long vAA, vBB, vCC */
4567    FETCH(r0, 1)                        @ r0<- CCBB
4568    and     r2, r0, #255                @ r2<- BB
4569    mov     r3, r0, lsr #8              @ r3<- CC
4570    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4571    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4572    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4573    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4574    mul     ip, r2, r1                  @  ip<- ZxW
4575    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
4576    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
4577    mov     r0, rINST, lsr #8           @ r0<- AA
4578    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
4579    add     r0, rFP, r0, lsl #2         @ r0<- &fp[AA]
4580    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4581    b       .LOP_MUL_LONG_finish
4582
4583/* ------------------------------ */
4584    .balign 64
4585.L_OP_DIV_LONG: /* 0x9e */
4586/* File: armv5te/OP_DIV_LONG.S */
4587/* File: armv5te/binopWide.S */
4588    /*
4589     * Generic 64-bit binary operation.  Provide an "instr" line that
4590     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4591     * This could be an ARM instruction or a function call.  (If the result
4592     * comes back in a register other than r0, you can override "result".)
4593     *
4594     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4595     * vCC (r1).  Useful for integer division and modulus.
4596     *
4597     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4598     *      xor-long, add-double, sub-double, mul-double, div-double,
4599     *      rem-double
4600     *
4601     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4602     */
4603    /* binop vAA, vBB, vCC */
4604    FETCH(r0, 1)                        @ r0<- CCBB
4605    mov     r9, rINST, lsr #8           @ r9<- AA
4606    and     r2, r0, #255                @ r2<- BB
4607    mov     r3, r0, lsr #8              @ r3<- CC
4608    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4609    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4610    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4611    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4612    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4613    .if 1
4614    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4615    beq     common_errDivideByZero
4616    .endif
4617    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4618
4619                               @ optional op; may set condition codes
4620    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4621    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4622    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4623    GOTO_OPCODE(ip)                     @ jump to next instruction
4624    /* 14-17 instructions */
4625
4626
4627/* ------------------------------ */
4628    .balign 64
4629.L_OP_REM_LONG: /* 0x9f */
4630/* File: armv5te/OP_REM_LONG.S */
4631/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
4632/* File: armv5te/binopWide.S */
4633    /*
4634     * Generic 64-bit binary operation.  Provide an "instr" line that
4635     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4636     * This could be an ARM instruction or a function call.  (If the result
4637     * comes back in a register other than r0, you can override "result".)
4638     *
4639     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4640     * vCC (r1).  Useful for integer division and modulus.
4641     *
4642     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4643     *      xor-long, add-double, sub-double, mul-double, div-double,
4644     *      rem-double
4645     *
4646     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4647     */
4648    /* binop vAA, vBB, vCC */
4649    FETCH(r0, 1)                        @ r0<- CCBB
4650    mov     r9, rINST, lsr #8           @ r9<- AA
4651    and     r2, r0, #255                @ r2<- BB
4652    mov     r3, r0, lsr #8              @ r3<- CC
4653    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4654    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4655    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4656    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4657    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4658    .if 1
4659    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4660    beq     common_errDivideByZero
4661    .endif
4662    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4663
4664                               @ optional op; may set condition codes
4665    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4666    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4667    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
4668    GOTO_OPCODE(ip)                     @ jump to next instruction
4669    /* 14-17 instructions */
4670
4671
4672/* ------------------------------ */
4673    .balign 64
4674.L_OP_AND_LONG: /* 0xa0 */
4675/* File: armv5te/OP_AND_LONG.S */
4676/* File: armv5te/binopWide.S */
4677    /*
4678     * Generic 64-bit binary operation.  Provide an "instr" line that
4679     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4680     * This could be an ARM instruction or a function call.  (If the result
4681     * comes back in a register other than r0, you can override "result".)
4682     *
4683     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4684     * vCC (r1).  Useful for integer division and modulus.
4685     *
4686     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4687     *      xor-long, add-double, sub-double, mul-double, div-double,
4688     *      rem-double
4689     *
4690     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4691     */
4692    /* binop vAA, vBB, vCC */
4693    FETCH(r0, 1)                        @ r0<- CCBB
4694    mov     r9, rINST, lsr #8           @ r9<- AA
4695    and     r2, r0, #255                @ r2<- BB
4696    mov     r3, r0, lsr #8              @ r3<- CC
4697    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4698    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4699    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4700    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4701    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4702    .if 0
4703    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4704    beq     common_errDivideByZero
4705    .endif
4706    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4707
4708    and     r0, r0, r2                           @ optional op; may set condition codes
4709    and     r1, r1, r3                              @ result<- op, r0-r3 changed
4710    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4711    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4712    GOTO_OPCODE(ip)                     @ jump to next instruction
4713    /* 14-17 instructions */
4714
4715
4716/* ------------------------------ */
4717    .balign 64
4718.L_OP_OR_LONG: /* 0xa1 */
4719/* File: armv5te/OP_OR_LONG.S */
4720/* File: armv5te/binopWide.S */
4721    /*
4722     * Generic 64-bit binary operation.  Provide an "instr" line that
4723     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4724     * This could be an ARM instruction or a function call.  (If the result
4725     * comes back in a register other than r0, you can override "result".)
4726     *
4727     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4728     * vCC (r1).  Useful for integer division and modulus.
4729     *
4730     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4731     *      xor-long, add-double, sub-double, mul-double, div-double,
4732     *      rem-double
4733     *
4734     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4735     */
4736    /* binop vAA, vBB, vCC */
4737    FETCH(r0, 1)                        @ r0<- CCBB
4738    mov     r9, rINST, lsr #8           @ r9<- AA
4739    and     r2, r0, #255                @ r2<- BB
4740    mov     r3, r0, lsr #8              @ r3<- CC
4741    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4742    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4743    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4744    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4745    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4746    .if 0
4747    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4748    beq     common_errDivideByZero
4749    .endif
4750    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4751
4752    orr     r0, r0, r2                           @ optional op; may set condition codes
4753    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
4754    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4755    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4756    GOTO_OPCODE(ip)                     @ jump to next instruction
4757    /* 14-17 instructions */
4758
4759
4760/* ------------------------------ */
4761    .balign 64
4762.L_OP_XOR_LONG: /* 0xa2 */
4763/* File: armv5te/OP_XOR_LONG.S */
4764/* File: armv5te/binopWide.S */
4765    /*
4766     * Generic 64-bit binary operation.  Provide an "instr" line that
4767     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4768     * This could be an ARM instruction or a function call.  (If the result
4769     * comes back in a register other than r0, you can override "result".)
4770     *
4771     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4772     * vCC (r1).  Useful for integer division and modulus.
4773     *
4774     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4775     *      xor-long, add-double, sub-double, mul-double, div-double,
4776     *      rem-double
4777     *
4778     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4779     */
4780    /* binop vAA, vBB, vCC */
4781    FETCH(r0, 1)                        @ r0<- CCBB
4782    mov     r9, rINST, lsr #8           @ r9<- AA
4783    and     r2, r0, #255                @ r2<- BB
4784    mov     r3, r0, lsr #8              @ r3<- CC
4785    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4786    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4787    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4788    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4789    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4790    .if 0
4791    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4792    beq     common_errDivideByZero
4793    .endif
4794    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4795
4796    eor     r0, r0, r2                           @ optional op; may set condition codes
4797    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
4798    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4799    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4800    GOTO_OPCODE(ip)                     @ jump to next instruction
4801    /* 14-17 instructions */
4802
4803
4804/* ------------------------------ */
4805    .balign 64
4806.L_OP_SHL_LONG: /* 0xa3 */
4807/* File: armv5te/OP_SHL_LONG.S */
4808    /*
4809     * Long integer shift.  This is different from the generic 32/64-bit
4810     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4811     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4812     * 6 bits of the shift distance.
4813     */
4814    /* shl-long vAA, vBB, vCC */
4815    FETCH(r0, 1)                        @ r0<- CCBB
4816    mov     r9, rINST, lsr #8           @ r9<- AA
4817    and     r3, r0, #255                @ r3<- BB
4818    mov     r0, r0, lsr #8              @ r0<- CC
4819    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4820    GET_VREG(r2, r0)                    @ r2<- vCC
4821    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4822    and     r2, r2, #63                 @ r2<- r2 & 0x3f
4823    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4824
4825    mov     r1, r1, asl r2              @  r1<- r1 << r2
4826    rsb     r3, r2, #32                 @  r3<- 32 - r2
4827    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
4828    subs    ip, r2, #32                 @  ip<- r2 - 32
4829    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
4830    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4831    b       .LOP_SHL_LONG_finish
4832
4833/* ------------------------------ */
4834    .balign 64
4835.L_OP_SHR_LONG: /* 0xa4 */
4836/* File: armv5te/OP_SHR_LONG.S */
4837    /*
4838     * Long integer shift.  This is different from the generic 32/64-bit
4839     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4840     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4841     * 6 bits of the shift distance.
4842     */
4843    /* shr-long vAA, vBB, vCC */
4844    FETCH(r0, 1)                        @ r0<- CCBB
4845    mov     r9, rINST, lsr #8           @ r9<- AA
4846    and     r3, r0, #255                @ r3<- BB
4847    mov     r0, r0, lsr #8              @ r0<- CC
4848    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4849    GET_VREG(r2, r0)                    @ r2<- vCC
4850    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4851    and     r2, r2, #63                 @ r0<- r0 & 0x3f
4852    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4853
4854    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
4855    rsb     r3, r2, #32                 @  r3<- 32 - r2
4856    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
4857    subs    ip, r2, #32                 @  ip<- r2 - 32
4858    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
4859    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4860    b       .LOP_SHR_LONG_finish
4861
4862/* ------------------------------ */
4863    .balign 64
4864.L_OP_USHR_LONG: /* 0xa5 */
4865/* File: armv5te/OP_USHR_LONG.S */
4866    /*
4867     * Long integer shift.  This is different from the generic 32/64-bit
4868     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4869     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4870     * 6 bits of the shift distance.
4871     */
4872    /* ushr-long vAA, vBB, vCC */
4873    FETCH(r0, 1)                        @ r0<- CCBB
4874    mov     r9, rINST, lsr #8           @ r9<- AA
4875    and     r3, r0, #255                @ r3<- BB
4876    mov     r0, r0, lsr #8              @ r0<- CC
4877    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4878    GET_VREG(r2, r0)                    @ r2<- vCC
4879    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4880    and     r2, r2, #63                 @ r0<- r0 & 0x3f
4881    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4882
4883    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
4884    rsb     r3, r2, #32                 @  r3<- 32 - r2
4885    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
4886    subs    ip, r2, #32                 @  ip<- r2 - 32
4887    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
4888    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4889    b       .LOP_USHR_LONG_finish
4890
4891/* ------------------------------ */
4892    .balign 64
4893.L_OP_ADD_FLOAT: /* 0xa6 */
4894/* File: arm-vfp/OP_ADD_FLOAT.S */
4895/* File: arm-vfp/fbinop.S */
4896    /*
4897     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4898     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4899     * use the "softfp" ABI, this must be an instruction, not a function call.
4900     *
4901     * For: add-float, sub-float, mul-float, div-float
4902     */
4903    /* floatop vAA, vBB, vCC */
4904    FETCH(r0, 1)                        @ r0<- CCBB
4905    mov     r9, rINST, lsr #8           @ r9<- AA
4906    mov     r3, r0, lsr #8              @ r3<- CC
4907    and     r2, r0, #255                @ r2<- BB
4908    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4909    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4910    flds    s1, [r3]                    @ s1<- vCC
4911    flds    s0, [r2]                    @ s0<- vBB
4912
4913    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4914    fadds   s2, s0, s1                              @ s2<- op
4915    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4916    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4917    fsts    s2, [r9]                    @ vAA<- s2
4918    GOTO_OPCODE(ip)                     @ jump to next instruction
4919
4920
4921/* ------------------------------ */
4922    .balign 64
4923.L_OP_SUB_FLOAT: /* 0xa7 */
4924/* File: arm-vfp/OP_SUB_FLOAT.S */
4925/* File: arm-vfp/fbinop.S */
4926    /*
4927     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4928     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4929     * use the "softfp" ABI, this must be an instruction, not a function call.
4930     *
4931     * For: add-float, sub-float, mul-float, div-float
4932     */
4933    /* floatop vAA, vBB, vCC */
4934    FETCH(r0, 1)                        @ r0<- CCBB
4935    mov     r9, rINST, lsr #8           @ r9<- AA
4936    mov     r3, r0, lsr #8              @ r3<- CC
4937    and     r2, r0, #255                @ r2<- BB
4938    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4939    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4940    flds    s1, [r3]                    @ s1<- vCC
4941    flds    s0, [r2]                    @ s0<- vBB
4942
4943    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4944    fsubs   s2, s0, s1                              @ s2<- op
4945    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4946    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4947    fsts    s2, [r9]                    @ vAA<- s2
4948    GOTO_OPCODE(ip)                     @ jump to next instruction
4949
4950
4951/* ------------------------------ */
4952    .balign 64
4953.L_OP_MUL_FLOAT: /* 0xa8 */
4954/* File: arm-vfp/OP_MUL_FLOAT.S */
4955/* File: arm-vfp/fbinop.S */
4956    /*
4957     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4958     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4959     * use the "softfp" ABI, this must be an instruction, not a function call.
4960     *
4961     * For: add-float, sub-float, mul-float, div-float
4962     */
4963    /* floatop vAA, vBB, vCC */
4964    FETCH(r0, 1)                        @ r0<- CCBB
4965    mov     r9, rINST, lsr #8           @ r9<- AA
4966    mov     r3, r0, lsr #8              @ r3<- CC
4967    and     r2, r0, #255                @ r2<- BB
4968    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4969    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4970    flds    s1, [r3]                    @ s1<- vCC
4971    flds    s0, [r2]                    @ s0<- vBB
4972
4973    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4974    fmuls   s2, s0, s1                              @ s2<- op
4975    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4976    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4977    fsts    s2, [r9]                    @ vAA<- s2
4978    GOTO_OPCODE(ip)                     @ jump to next instruction
4979
4980
4981/* ------------------------------ */
4982    .balign 64
4983.L_OP_DIV_FLOAT: /* 0xa9 */
4984/* File: arm-vfp/OP_DIV_FLOAT.S */
4985/* File: arm-vfp/fbinop.S */
4986    /*
4987     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4988     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4989     * use the "softfp" ABI, this must be an instruction, not a function call.
4990     *
4991     * For: add-float, sub-float, mul-float, div-float
4992     */
4993    /* floatop vAA, vBB, vCC */
4994    FETCH(r0, 1)                        @ r0<- CCBB
4995    mov     r9, rINST, lsr #8           @ r9<- AA
4996    mov     r3, r0, lsr #8              @ r3<- CC
4997    and     r2, r0, #255                @ r2<- BB
4998    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4999    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5000    flds    s1, [r3]                    @ s1<- vCC
5001    flds    s0, [r2]                    @ s0<- vBB
5002
5003    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5004    fdivs   s2, s0, s1                              @ s2<- op
5005    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5006    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5007    fsts    s2, [r9]                    @ vAA<- s2
5008    GOTO_OPCODE(ip)                     @ jump to next instruction
5009
5010
5011/* ------------------------------ */
5012    .balign 64
5013.L_OP_REM_FLOAT: /* 0xaa */
5014/* File: armv5te/OP_REM_FLOAT.S */
5015/* EABI doesn't define a float remainder function, but libm does */
5016/* File: armv5te/binop.S */
5017    /*
5018     * Generic 32-bit binary operation.  Provide an "instr" line that
5019     * specifies an instruction that performs "result = r0 op r1".
5020     * This could be an ARM instruction or a function call.  (If the result
5021     * comes back in a register other than r0, you can override "result".)
5022     *
5023     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5024     * vCC (r1).  Useful for integer division and modulus.  Note that we
5025     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
5026     * handles it correctly.
5027     *
5028     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
5029     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
5030     *      mul-float, div-float, rem-float
5031     */
5032    /* binop vAA, vBB, vCC */
5033    FETCH(r0, 1)                        @ r0<- CCBB
5034    mov     r9, rINST, lsr #8           @ r9<- AA
5035    mov     r3, r0, lsr #8              @ r3<- CC
5036    and     r2, r0, #255                @ r2<- BB
5037    GET_VREG(r1, r3)                    @ r1<- vCC
5038    GET_VREG(r0, r2)                    @ r0<- vBB
5039    .if 0
5040    cmp     r1, #0                      @ is second operand zero?
5041    beq     common_errDivideByZero
5042    .endif
5043
5044    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5045                               @ optional op; may set condition codes
5046    bl      fmodf                              @ r0<- op, r0-r3 changed
5047    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5048    SET_VREG(r0, r9)               @ vAA<- r0
5049    GOTO_OPCODE(ip)                     @ jump to next instruction
5050    /* 11-14 instructions */
5051
5052
5053/* ------------------------------ */
5054    .balign 64
5055.L_OP_ADD_DOUBLE: /* 0xab */
5056/* File: arm-vfp/OP_ADD_DOUBLE.S */
5057/* File: arm-vfp/fbinopWide.S */
5058    /*
5059     * Generic 64-bit double-precision floating point binary operation.
5060     * Provide an "instr" line that specifies an instruction that performs
5061     * "d2 = d0 op d1".
5062     *
5063     * for: add-double, sub-double, mul-double, div-double
5064     */
5065    /* doubleop vAA, vBB, vCC */
5066    FETCH(r0, 1)                        @ r0<- CCBB
5067    mov     r9, rINST, lsr #8           @ r9<- AA
5068    mov     r3, r0, lsr #8              @ r3<- CC
5069    and     r2, r0, #255                @ r2<- BB
5070    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5071    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5072    fldd    d1, [r3]                    @ d1<- vCC
5073    fldd    d0, [r2]                    @ d0<- vBB
5074
5075    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5076    faddd   d2, d0, d1                              @ s2<- op
5077    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5078    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5079    fstd    d2, [r9]                    @ vAA<- d2
5080    GOTO_OPCODE(ip)                     @ jump to next instruction
5081
5082
5083/* ------------------------------ */
5084    .balign 64
5085.L_OP_SUB_DOUBLE: /* 0xac */
5086/* File: arm-vfp/OP_SUB_DOUBLE.S */
5087/* File: arm-vfp/fbinopWide.S */
5088    /*
5089     * Generic 64-bit double-precision floating point binary operation.
5090     * Provide an "instr" line that specifies an instruction that performs
5091     * "d2 = d0 op d1".
5092     *
5093     * for: add-double, sub-double, mul-double, div-double
5094     */
5095    /* doubleop vAA, vBB, vCC */
5096    FETCH(r0, 1)                        @ r0<- CCBB
5097    mov     r9, rINST, lsr #8           @ r9<- AA
5098    mov     r3, r0, lsr #8              @ r3<- CC
5099    and     r2, r0, #255                @ r2<- BB
5100    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5101    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5102    fldd    d1, [r3]                    @ d1<- vCC
5103    fldd    d0, [r2]                    @ d0<- vBB
5104
5105    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5106    fsubd   d2, d0, d1                              @ s2<- op
5107    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5108    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5109    fstd    d2, [r9]                    @ vAA<- d2
5110    GOTO_OPCODE(ip)                     @ jump to next instruction
5111
5112
5113/* ------------------------------ */
5114    .balign 64
5115.L_OP_MUL_DOUBLE: /* 0xad */
5116/* File: arm-vfp/OP_MUL_DOUBLE.S */
5117/* File: arm-vfp/fbinopWide.S */
5118    /*
5119     * Generic 64-bit double-precision floating point binary operation.
5120     * Provide an "instr" line that specifies an instruction that performs
5121     * "d2 = d0 op d1".
5122     *
5123     * for: add-double, sub-double, mul-double, div-double
5124     */
5125    /* doubleop vAA, vBB, vCC */
5126    FETCH(r0, 1)                        @ r0<- CCBB
5127    mov     r9, rINST, lsr #8           @ r9<- AA
5128    mov     r3, r0, lsr #8              @ r3<- CC
5129    and     r2, r0, #255                @ r2<- BB
5130    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5131    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5132    fldd    d1, [r3]                    @ d1<- vCC
5133    fldd    d0, [r2]                    @ d0<- vBB
5134
5135    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5136    fmuld   d2, d0, d1                              @ s2<- op
5137    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5138    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5139    fstd    d2, [r9]                    @ vAA<- d2
5140    GOTO_OPCODE(ip)                     @ jump to next instruction
5141
5142
5143/* ------------------------------ */
5144    .balign 64
5145.L_OP_DIV_DOUBLE: /* 0xae */
5146/* File: arm-vfp/OP_DIV_DOUBLE.S */
5147/* File: arm-vfp/fbinopWide.S */
5148    /*
5149     * Generic 64-bit double-precision floating point binary operation.
5150     * Provide an "instr" line that specifies an instruction that performs
5151     * "d2 = d0 op d1".
5152     *
5153     * for: add-double, sub-double, mul-double, div-double
5154     */
5155    /* doubleop vAA, vBB, vCC */
5156    FETCH(r0, 1)                        @ r0<- CCBB
5157    mov     r9, rINST, lsr #8           @ r9<- AA
5158    mov     r3, r0, lsr #8              @ r3<- CC
5159    and     r2, r0, #255                @ r2<- BB
5160    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5161    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5162    fldd    d1, [r3]                    @ d1<- vCC
5163    fldd    d0, [r2]                    @ d0<- vBB
5164
5165    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5166    fdivd   d2, d0, d1                              @ s2<- op
5167    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5168    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5169    fstd    d2, [r9]                    @ vAA<- d2
5170    GOTO_OPCODE(ip)                     @ jump to next instruction
5171
5172
5173/* ------------------------------ */
5174    .balign 64
5175.L_OP_REM_DOUBLE: /* 0xaf */
5176/* File: armv5te/OP_REM_DOUBLE.S */
5177/* EABI doesn't define a double remainder function, but libm does */
5178/* File: armv5te/binopWide.S */
5179    /*
5180     * Generic 64-bit binary operation.  Provide an "instr" line that
5181     * specifies an instruction that performs "result = r0-r1 op r2-r3".
5182     * This could be an ARM instruction or a function call.  (If the result
5183     * comes back in a register other than r0, you can override "result".)
5184     *
5185     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5186     * vCC (r1).  Useful for integer division and modulus.
5187     *
5188     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
5189     *      xor-long, add-double, sub-double, mul-double, div-double,
5190     *      rem-double
5191     *
5192     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
5193     */
5194    /* binop vAA, vBB, vCC */
5195    FETCH(r0, 1)                        @ r0<- CCBB
5196    mov     r9, rINST, lsr #8           @ r9<- AA
5197    and     r2, r0, #255                @ r2<- BB
5198    mov     r3, r0, lsr #8              @ r3<- CC
5199    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5200    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
5201    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
5202    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5203    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
5204    .if 0
5205    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5206    beq     common_errDivideByZero
5207    .endif
5208    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5209
5210                               @ optional op; may set condition codes
5211    bl      fmod                              @ result<- op, r0-r3 changed
5212    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5213    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5214    GOTO_OPCODE(ip)                     @ jump to next instruction
5215    /* 14-17 instructions */
5216
5217
5218/* ------------------------------ */
5219    .balign 64
5220.L_OP_ADD_INT_2ADDR: /* 0xb0 */
5221/* File: armv6t2/OP_ADD_INT_2ADDR.S */
5222/* File: armv6t2/binop2addr.S */
5223    /*
5224     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5225     * that specifies an instruction that performs "result = r0 op r1".
5226     * This could be an ARM instruction or a function call.  (If the result
5227     * comes back in a register other than r0, you can override "result".)
5228     *
5229     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5230     * vCC (r1).  Useful for integer division and modulus.
5231     *
5232     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5233     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5234     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5235     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5236     */
5237    /* binop/2addr vA, vB */
5238    mov     r3, rINST, lsr #12          @ r3<- B
5239    ubfx    r9, rINST, #8, #4           @ r9<- A
5240    GET_VREG(r1, r3)                    @ r1<- vB
5241    GET_VREG(r0, r9)                    @ r0<- vA
5242    .if 0
5243    cmp     r1, #0                      @ is second operand zero?
5244    beq     common_errDivideByZero
5245    .endif
5246    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5247
5248                               @ optional op; may set condition codes
5249    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
5250    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5251    SET_VREG(r0, r9)               @ vAA<- r0
5252    GOTO_OPCODE(ip)                     @ jump to next instruction
5253    /* 10-13 instructions */
5254
5255
5256/* ------------------------------ */
5257    .balign 64
5258.L_OP_SUB_INT_2ADDR: /* 0xb1 */
5259/* File: armv6t2/OP_SUB_INT_2ADDR.S */
5260/* File: armv6t2/binop2addr.S */
5261    /*
5262     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5263     * that specifies an instruction that performs "result = r0 op r1".
5264     * This could be an ARM instruction or a function call.  (If the result
5265     * comes back in a register other than r0, you can override "result".)
5266     *
5267     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5268     * vCC (r1).  Useful for integer division and modulus.
5269     *
5270     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5271     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5272     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5273     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5274     */
5275    /* binop/2addr vA, vB */
5276    mov     r3, rINST, lsr #12          @ r3<- B
5277    ubfx    r9, rINST, #8, #4           @ r9<- A
5278    GET_VREG(r1, r3)                    @ r1<- vB
5279    GET_VREG(r0, r9)                    @ r0<- vA
5280    .if 0
5281    cmp     r1, #0                      @ is second operand zero?
5282    beq     common_errDivideByZero
5283    .endif
5284    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5285
5286                               @ optional op; may set condition codes
5287    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
5288    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5289    SET_VREG(r0, r9)               @ vAA<- r0
5290    GOTO_OPCODE(ip)                     @ jump to next instruction
5291    /* 10-13 instructions */
5292
5293
5294/* ------------------------------ */
5295    .balign 64
5296.L_OP_MUL_INT_2ADDR: /* 0xb2 */
5297/* File: armv6t2/OP_MUL_INT_2ADDR.S */
5298/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
5299/* File: armv6t2/binop2addr.S */
5300    /*
5301     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5302     * that specifies an instruction that performs "result = r0 op r1".
5303     * This could be an ARM instruction or a function call.  (If the result
5304     * comes back in a register other than r0, you can override "result".)
5305     *
5306     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5307     * vCC (r1).  Useful for integer division and modulus.
5308     *
5309     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5310     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5311     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5312     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5313     */
5314    /* binop/2addr vA, vB */
5315    mov     r3, rINST, lsr #12          @ r3<- B
5316    ubfx    r9, rINST, #8, #4           @ r9<- A
5317    GET_VREG(r1, r3)                    @ r1<- vB
5318    GET_VREG(r0, r9)                    @ r0<- vA
5319    .if 0
5320    cmp     r1, #0                      @ is second operand zero?
5321    beq     common_errDivideByZero
5322    .endif
5323    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5324
5325                               @ optional op; may set condition codes
5326    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
5327    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5328    SET_VREG(r0, r9)               @ vAA<- r0
5329    GOTO_OPCODE(ip)                     @ jump to next instruction
5330    /* 10-13 instructions */
5331
5332
5333/* ------------------------------ */
5334    .balign 64
5335.L_OP_DIV_INT_2ADDR: /* 0xb3 */
5336/* File: armv6t2/OP_DIV_INT_2ADDR.S */
5337/* File: armv6t2/binop2addr.S */
5338    /*
5339     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5340     * that specifies an instruction that performs "result = r0 op r1".
5341     * This could be an ARM instruction or a function call.  (If the result
5342     * comes back in a register other than r0, you can override "result".)
5343     *
5344     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5345     * vCC (r1).  Useful for integer division and modulus.
5346     *
5347     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5348     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5349     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5350     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5351     */
5352    /* binop/2addr vA, vB */
5353    mov     r3, rINST, lsr #12          @ r3<- B
5354    ubfx    r9, rINST, #8, #4           @ r9<- A
5355    GET_VREG(r1, r3)                    @ r1<- vB
5356    GET_VREG(r0, r9)                    @ r0<- vA
5357    .if 1
5358    cmp     r1, #0                      @ is second operand zero?
5359    beq     common_errDivideByZero
5360    .endif
5361    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5362
5363                               @ optional op; may set condition codes
5364    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
5365    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5366    SET_VREG(r0, r9)               @ vAA<- r0
5367    GOTO_OPCODE(ip)                     @ jump to next instruction
5368    /* 10-13 instructions */
5369
5370
5371/* ------------------------------ */
5372    .balign 64
5373.L_OP_REM_INT_2ADDR: /* 0xb4 */
5374/* File: armv6t2/OP_REM_INT_2ADDR.S */
5375/* idivmod returns quotient in r0 and remainder in r1 */
5376/* File: armv6t2/binop2addr.S */
5377    /*
5378     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5379     * that specifies an instruction that performs "result = r0 op r1".
5380     * This could be an ARM instruction or a function call.  (If the result
5381     * comes back in a register other than r0, you can override "result".)
5382     *
5383     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5384     * vCC (r1).  Useful for integer division and modulus.
5385     *
5386     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5387     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5388     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5389     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5390     */
5391    /* binop/2addr vA, vB */
5392    mov     r3, rINST, lsr #12          @ r3<- B
5393    ubfx    r9, rINST, #8, #4           @ r9<- A
5394    GET_VREG(r1, r3)                    @ r1<- vB
5395    GET_VREG(r0, r9)                    @ r0<- vA
5396    .if 1
5397    cmp     r1, #0                      @ is second operand zero?
5398    beq     common_errDivideByZero
5399    .endif
5400    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5401
5402                               @ optional op; may set condition codes
5403    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
5404    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5405    SET_VREG(r1, r9)               @ vAA<- r1
5406    GOTO_OPCODE(ip)                     @ jump to next instruction
5407    /* 10-13 instructions */
5408
5409
5410/* ------------------------------ */
5411    .balign 64
5412.L_OP_AND_INT_2ADDR: /* 0xb5 */
5413/* File: armv6t2/OP_AND_INT_2ADDR.S */
5414/* File: armv6t2/binop2addr.S */
5415    /*
5416     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5417     * that specifies an instruction that performs "result = r0 op r1".
5418     * This could be an ARM instruction or a function call.  (If the result
5419     * comes back in a register other than r0, you can override "result".)
5420     *
5421     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5422     * vCC (r1).  Useful for integer division and modulus.
5423     *
5424     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5425     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5426     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5427     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5428     */
5429    /* binop/2addr vA, vB */
5430    mov     r3, rINST, lsr #12          @ r3<- B
5431    ubfx    r9, rINST, #8, #4           @ r9<- A
5432    GET_VREG(r1, r3)                    @ r1<- vB
5433    GET_VREG(r0, r9)                    @ r0<- vA
5434    .if 0
5435    cmp     r1, #0                      @ is second operand zero?
5436    beq     common_errDivideByZero
5437    .endif
5438    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5439
5440                               @ optional op; may set condition codes
5441    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
5442    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5443    SET_VREG(r0, r9)               @ vAA<- r0
5444    GOTO_OPCODE(ip)                     @ jump to next instruction
5445    /* 10-13 instructions */
5446
5447
5448/* ------------------------------ */
5449    .balign 64
5450.L_OP_OR_INT_2ADDR: /* 0xb6 */
5451/* File: armv6t2/OP_OR_INT_2ADDR.S */
5452/* File: armv6t2/binop2addr.S */
5453    /*
5454     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5455     * that specifies an instruction that performs "result = r0 op r1".
5456     * This could be an ARM instruction or a function call.  (If the result
5457     * comes back in a register other than r0, you can override "result".)
5458     *
5459     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5460     * vCC (r1).  Useful for integer division and modulus.
5461     *
5462     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5463     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5464     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5465     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5466     */
5467    /* binop/2addr vA, vB */
5468    mov     r3, rINST, lsr #12          @ r3<- B
5469    ubfx    r9, rINST, #8, #4           @ r9<- A
5470    GET_VREG(r1, r3)                    @ r1<- vB
5471    GET_VREG(r0, r9)                    @ r0<- vA
5472    .if 0
5473    cmp     r1, #0                      @ is second operand zero?
5474    beq     common_errDivideByZero
5475    .endif
5476    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5477
5478                               @ optional op; may set condition codes
5479    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
5480    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5481    SET_VREG(r0, r9)               @ vAA<- r0
5482    GOTO_OPCODE(ip)                     @ jump to next instruction
5483    /* 10-13 instructions */
5484
5485
5486/* ------------------------------ */
5487    .balign 64
5488.L_OP_XOR_INT_2ADDR: /* 0xb7 */
5489/* File: armv6t2/OP_XOR_INT_2ADDR.S */
5490/* File: armv6t2/binop2addr.S */
5491    /*
5492     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5493     * that specifies an instruction that performs "result = r0 op r1".
5494     * This could be an ARM instruction or a function call.  (If the result
5495     * comes back in a register other than r0, you can override "result".)
5496     *
5497     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5498     * vCC (r1).  Useful for integer division and modulus.
5499     *
5500     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5501     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5502     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5503     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5504     */
5505    /* binop/2addr vA, vB */
5506    mov     r3, rINST, lsr #12          @ r3<- B
5507    ubfx    r9, rINST, #8, #4           @ r9<- A
5508    GET_VREG(r1, r3)                    @ r1<- vB
5509    GET_VREG(r0, r9)                    @ r0<- vA
5510    .if 0
5511    cmp     r1, #0                      @ is second operand zero?
5512    beq     common_errDivideByZero
5513    .endif
5514    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5515
5516                               @ optional op; may set condition codes
5517    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
5518    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5519    SET_VREG(r0, r9)               @ vAA<- r0
5520    GOTO_OPCODE(ip)                     @ jump to next instruction
5521    /* 10-13 instructions */
5522
5523
5524/* ------------------------------ */
5525    .balign 64
5526.L_OP_SHL_INT_2ADDR: /* 0xb8 */
5527/* File: armv6t2/OP_SHL_INT_2ADDR.S */
5528/* File: armv6t2/binop2addr.S */
5529    /*
5530     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5531     * that specifies an instruction that performs "result = r0 op r1".
5532     * This could be an ARM instruction or a function call.  (If the result
5533     * comes back in a register other than r0, you can override "result".)
5534     *
5535     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5536     * vCC (r1).  Useful for integer division and modulus.
5537     *
5538     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5539     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5540     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5541     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5542     */
5543    /* binop/2addr vA, vB */
5544    mov     r3, rINST, lsr #12          @ r3<- B
5545    ubfx    r9, rINST, #8, #4           @ r9<- A
5546    GET_VREG(r1, r3)                    @ r1<- vB
5547    GET_VREG(r0, r9)                    @ r0<- vA
5548    .if 0
5549    cmp     r1, #0                      @ is second operand zero?
5550    beq     common_errDivideByZero
5551    .endif
5552    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5553
5554    and     r1, r1, #31                           @ optional op; may set condition codes
5555    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
5556    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5557    SET_VREG(r0, r9)               @ vAA<- r0
5558    GOTO_OPCODE(ip)                     @ jump to next instruction
5559    /* 10-13 instructions */
5560
5561
5562/* ------------------------------ */
5563    .balign 64
5564.L_OP_SHR_INT_2ADDR: /* 0xb9 */
5565/* File: armv6t2/OP_SHR_INT_2ADDR.S */
5566/* File: armv6t2/binop2addr.S */
5567    /*
5568     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5569     * that specifies an instruction that performs "result = r0 op r1".
5570     * This could be an ARM instruction or a function call.  (If the result
5571     * comes back in a register other than r0, you can override "result".)
5572     *
5573     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5574     * vCC (r1).  Useful for integer division and modulus.
5575     *
5576     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5577     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5578     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5579     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5580     */
5581    /* binop/2addr vA, vB */
5582    mov     r3, rINST, lsr #12          @ r3<- B
5583    ubfx    r9, rINST, #8, #4           @ r9<- A
5584    GET_VREG(r1, r3)                    @ r1<- vB
5585    GET_VREG(r0, r9)                    @ r0<- vA
5586    .if 0
5587    cmp     r1, #0                      @ is second operand zero?
5588    beq     common_errDivideByZero
5589    .endif
5590    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5591
5592    and     r1, r1, #31                           @ optional op; may set condition codes
5593    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
5594    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5595    SET_VREG(r0, r9)               @ vAA<- r0
5596    GOTO_OPCODE(ip)                     @ jump to next instruction
5597    /* 10-13 instructions */
5598
5599
5600/* ------------------------------ */
5601    .balign 64
5602.L_OP_USHR_INT_2ADDR: /* 0xba */
5603/* File: armv6t2/OP_USHR_INT_2ADDR.S */
5604/* File: armv6t2/binop2addr.S */
5605    /*
5606     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5607     * that specifies an instruction that performs "result = r0 op r1".
5608     * This could be an ARM instruction or a function call.  (If the result
5609     * comes back in a register other than r0, you can override "result".)
5610     *
5611     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5612     * vCC (r1).  Useful for integer division and modulus.
5613     *
5614     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5615     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5616     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5617     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5618     */
5619    /* binop/2addr vA, vB */
5620    mov     r3, rINST, lsr #12          @ r3<- B
5621    ubfx    r9, rINST, #8, #4           @ r9<- A
5622    GET_VREG(r1, r3)                    @ r1<- vB
5623    GET_VREG(r0, r9)                    @ r0<- vA
5624    .if 0
5625    cmp     r1, #0                      @ is second operand zero?
5626    beq     common_errDivideByZero
5627    .endif
5628    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5629
5630    and     r1, r1, #31                           @ optional op; may set condition codes
5631    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
5632    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5633    SET_VREG(r0, r9)               @ vAA<- r0
5634    GOTO_OPCODE(ip)                     @ jump to next instruction
5635    /* 10-13 instructions */
5636
5637
5638/* ------------------------------ */
5639    .balign 64
5640.L_OP_ADD_LONG_2ADDR: /* 0xbb */
5641/* File: armv6t2/OP_ADD_LONG_2ADDR.S */
5642/* File: armv6t2/binopWide2addr.S */
5643    /*
5644     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5645     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5646     * This could be an ARM instruction or a function call.  (If the result
5647     * comes back in a register other than r0, you can override "result".)
5648     *
5649     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5650     * vCC (r1).  Useful for integer division and modulus.
5651     *
5652     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5653     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5654     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5655     *      rem-double/2addr
5656     */
5657    /* binop/2addr vA, vB */
5658    mov     r1, rINST, lsr #12          @ r1<- B
5659    ubfx    r9, rINST, #8, #4           @ r9<- A
5660    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5661    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5662    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5663    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5664    .if 0
5665    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5666    beq     common_errDivideByZero
5667    .endif
5668    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5669
5670    adds    r0, r0, r2                           @ optional op; may set condition codes
5671    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
5672    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5673    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5674    GOTO_OPCODE(ip)                     @ jump to next instruction
5675    /* 12-15 instructions */
5676
5677
5678/* ------------------------------ */
5679    .balign 64
5680.L_OP_SUB_LONG_2ADDR: /* 0xbc */
5681/* File: armv6t2/OP_SUB_LONG_2ADDR.S */
5682/* File: armv6t2/binopWide2addr.S */
5683    /*
5684     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5685     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5686     * This could be an ARM instruction or a function call.  (If the result
5687     * comes back in a register other than r0, you can override "result".)
5688     *
5689     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5690     * vCC (r1).  Useful for integer division and modulus.
5691     *
5692     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5693     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5694     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5695     *      rem-double/2addr
5696     */
5697    /* binop/2addr vA, vB */
5698    mov     r1, rINST, lsr #12          @ r1<- B
5699    ubfx    r9, rINST, #8, #4           @ r9<- A
5700    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5701    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5702    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5703    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5704    .if 0
5705    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5706    beq     common_errDivideByZero
5707    .endif
5708    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5709
5710    subs    r0, r0, r2                           @ optional op; may set condition codes
5711    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
5712    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5713    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5714    GOTO_OPCODE(ip)                     @ jump to next instruction
5715    /* 12-15 instructions */
5716
5717
5718/* ------------------------------ */
5719    .balign 64
5720.L_OP_MUL_LONG_2ADDR: /* 0xbd */
5721/* File: armv6t2/OP_MUL_LONG_2ADDR.S */
5722    /*
5723     * Signed 64-bit integer multiply, "/2addr" version.
5724     *
5725     * See OP_MUL_LONG for an explanation.
5726     *
5727     * We get a little tight on registers, so to avoid looking up &fp[A]
5728     * again we stuff it into rINST.
5729     */
5730    /* mul-long/2addr vA, vB */
5731    mov     r1, rINST, lsr #12          @ r1<- B
5732    ubfx    r9, rINST, #8, #4           @ r9<- A
5733    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5734    add     rINST, rFP, r9, lsl #2      @ rINST<- &fp[A]
5735    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5736    ldmia   rINST, {r0-r1}              @ r0/r1<- vAA/vAA+1
5737    mul     ip, r2, r1                  @  ip<- ZxW
5738    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
5739    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
5740    mov     r0, rINST                   @ r0<- &fp[A] (free up rINST)
5741    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5742    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
5743    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5744    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
5745    GOTO_OPCODE(ip)                     @ jump to next instruction
5746
5747/* ------------------------------ */
5748    .balign 64
5749.L_OP_DIV_LONG_2ADDR: /* 0xbe */
5750/* File: armv6t2/OP_DIV_LONG_2ADDR.S */
5751/* File: armv6t2/binopWide2addr.S */
5752    /*
5753     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5754     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5755     * This could be an ARM instruction or a function call.  (If the result
5756     * comes back in a register other than r0, you can override "result".)
5757     *
5758     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5759     * vCC (r1).  Useful for integer division and modulus.
5760     *
5761     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5762     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5763     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5764     *      rem-double/2addr
5765     */
5766    /* binop/2addr vA, vB */
5767    mov     r1, rINST, lsr #12          @ r1<- B
5768    ubfx    r9, rINST, #8, #4           @ r9<- A
5769    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5770    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5771    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5772    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5773    .if 1
5774    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5775    beq     common_errDivideByZero
5776    .endif
5777    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5778
5779                               @ optional op; may set condition codes
5780    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
5781    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5782    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5783    GOTO_OPCODE(ip)                     @ jump to next instruction
5784    /* 12-15 instructions */
5785
5786
5787/* ------------------------------ */
5788    .balign 64
5789.L_OP_REM_LONG_2ADDR: /* 0xbf */
5790/* File: armv6t2/OP_REM_LONG_2ADDR.S */
5791/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
5792/* File: armv6t2/binopWide2addr.S */
5793    /*
5794     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5795     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5796     * This could be an ARM instruction or a function call.  (If the result
5797     * comes back in a register other than r0, you can override "result".)
5798     *
5799     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5800     * vCC (r1).  Useful for integer division and modulus.
5801     *
5802     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5803     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5804     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5805     *      rem-double/2addr
5806     */
5807    /* binop/2addr vA, vB */
5808    mov     r1, rINST, lsr #12          @ r1<- B
5809    ubfx    r9, rINST, #8, #4           @ r9<- A
5810    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5811    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5812    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5813    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5814    .if 1
5815    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5816    beq     common_errDivideByZero
5817    .endif
5818    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5819
5820                               @ optional op; may set condition codes
5821    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
5822    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5823    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
5824    GOTO_OPCODE(ip)                     @ jump to next instruction
5825    /* 12-15 instructions */
5826
5827
5828/* ------------------------------ */
5829    .balign 64
5830.L_OP_AND_LONG_2ADDR: /* 0xc0 */
5831/* File: armv6t2/OP_AND_LONG_2ADDR.S */
5832/* File: armv6t2/binopWide2addr.S */
5833    /*
5834     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5835     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5836     * This could be an ARM instruction or a function call.  (If the result
5837     * comes back in a register other than r0, you can override "result".)
5838     *
5839     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5840     * vCC (r1).  Useful for integer division and modulus.
5841     *
5842     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5843     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5844     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5845     *      rem-double/2addr
5846     */
5847    /* binop/2addr vA, vB */
5848    mov     r1, rINST, lsr #12          @ r1<- B
5849    ubfx    r9, rINST, #8, #4           @ r9<- A
5850    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5851    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5852    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5853    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5854    .if 0
5855    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5856    beq     common_errDivideByZero
5857    .endif
5858    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5859
5860    and     r0, r0, r2                           @ optional op; may set condition codes
5861    and     r1, r1, r3                              @ result<- op, r0-r3 changed
5862    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5863    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5864    GOTO_OPCODE(ip)                     @ jump to next instruction
5865    /* 12-15 instructions */
5866
5867
5868/* ------------------------------ */
5869    .balign 64
5870.L_OP_OR_LONG_2ADDR: /* 0xc1 */
5871/* File: armv6t2/OP_OR_LONG_2ADDR.S */
5872/* File: armv6t2/binopWide2addr.S */
5873    /*
5874     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5875     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5876     * This could be an ARM instruction or a function call.  (If the result
5877     * comes back in a register other than r0, you can override "result".)
5878     *
5879     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5880     * vCC (r1).  Useful for integer division and modulus.
5881     *
5882     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5883     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5884     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5885     *      rem-double/2addr
5886     */
5887    /* binop/2addr vA, vB */
5888    mov     r1, rINST, lsr #12          @ r1<- B
5889    ubfx    r9, rINST, #8, #4           @ r9<- A
5890    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5891    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5892    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5893    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5894    .if 0
5895    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5896    beq     common_errDivideByZero
5897    .endif
5898    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5899
5900    orr     r0, r0, r2                           @ optional op; may set condition codes
5901    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
5902    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5903    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5904    GOTO_OPCODE(ip)                     @ jump to next instruction
5905    /* 12-15 instructions */
5906
5907
5908/* ------------------------------ */
5909    .balign 64
5910.L_OP_XOR_LONG_2ADDR: /* 0xc2 */
5911/* File: armv6t2/OP_XOR_LONG_2ADDR.S */
5912/* File: armv6t2/binopWide2addr.S */
5913    /*
5914     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5915     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5916     * This could be an ARM instruction or a function call.  (If the result
5917     * comes back in a register other than r0, you can override "result".)
5918     *
5919     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5920     * vCC (r1).  Useful for integer division and modulus.
5921     *
5922     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5923     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5924     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5925     *      rem-double/2addr
5926     */
5927    /* binop/2addr vA, vB */
5928    mov     r1, rINST, lsr #12          @ r1<- B
5929    ubfx    r9, rINST, #8, #4           @ r9<- A
5930    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5931    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5932    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5933    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5934    .if 0
5935    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5936    beq     common_errDivideByZero
5937    .endif
5938    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5939
5940    eor     r0, r0, r2                           @ optional op; may set condition codes
5941    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
5942    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5943    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5944    GOTO_OPCODE(ip)                     @ jump to next instruction
5945    /* 12-15 instructions */
5946
5947
5948/* ------------------------------ */
5949    .balign 64
5950.L_OP_SHL_LONG_2ADDR: /* 0xc3 */
5951/* File: armv6t2/OP_SHL_LONG_2ADDR.S */
5952    /*
5953     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5954     * 32-bit shift distance.
5955     */
5956    /* shl-long/2addr vA, vB */
5957    mov     r3, rINST, lsr #12          @ r3<- B
5958    ubfx    r9, rINST, #8, #4           @ r9<- A
5959    GET_VREG(r2, r3)                    @ r2<- vB
5960    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5961    and     r2, r2, #63                 @ r2<- r2 & 0x3f
5962    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5963
5964    mov     r1, r1, asl r2              @  r1<- r1 << r2
5965    rsb     r3, r2, #32                 @  r3<- 32 - r2
5966    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
5967    subs    ip, r2, #32                 @  ip<- r2 - 32
5968    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5969    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
5970    mov     r0, r0, asl r2              @  r0<- r0 << r2
5971    b       .LOP_SHL_LONG_2ADDR_finish
5972
5973/* ------------------------------ */
5974    .balign 64
5975.L_OP_SHR_LONG_2ADDR: /* 0xc4 */
5976/* File: armv6t2/OP_SHR_LONG_2ADDR.S */
5977    /*
5978     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5979     * 32-bit shift distance.
5980     */
5981    /* shr-long/2addr vA, vB */
5982    mov     r3, rINST, lsr #12          @ r3<- B
5983    ubfx    r9, rINST, #8, #4           @ r9<- A
5984    GET_VREG(r2, r3)                    @ r2<- vB
5985    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5986    and     r2, r2, #63                 @ r2<- r2 & 0x3f
5987    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5988
5989    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
5990    rsb     r3, r2, #32                 @  r3<- 32 - r2
5991    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
5992    subs    ip, r2, #32                 @  ip<- r2 - 32
5993    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5994    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
5995    mov     r1, r1, asr r2              @  r1<- r1 >> r2
5996    b       .LOP_SHR_LONG_2ADDR_finish
5997
5998/* ------------------------------ */
5999    .balign 64
6000.L_OP_USHR_LONG_2ADDR: /* 0xc5 */
6001/* File: armv6t2/OP_USHR_LONG_2ADDR.S */
6002    /*
6003     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6004     * 32-bit shift distance.
6005     */
6006    /* ushr-long/2addr vA, vB */
6007    mov     r3, rINST, lsr #12          @ r3<- B
6008    ubfx    r9, rINST, #8, #4           @ r9<- A
6009    GET_VREG(r2, r3)                    @ r2<- vB
6010    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6011    and     r2, r2, #63                 @ r2<- r2 & 0x3f
6012    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6013
6014    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
6015    rsb     r3, r2, #32                 @  r3<- 32 - r2
6016    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
6017    subs    ip, r2, #32                 @  ip<- r2 - 32
6018    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6019    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
6020    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
6021    b       .LOP_USHR_LONG_2ADDR_finish
6022
6023/* ------------------------------ */
6024    .balign 64
6025.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
6026/* File: arm-vfp/OP_ADD_FLOAT_2ADDR.S */
6027/* File: arm-vfp/fbinop2addr.S */
6028    /*
6029     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6030     * an "instr" line that specifies an instruction that performs
6031     * "s2 = s0 op s1".
6032     *
6033     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6034     */
6035    /* binop/2addr vA, vB */
6036    mov     r3, rINST, lsr #12          @ r3<- B
6037    mov     r9, rINST, lsr #8           @ r9<- A+
6038    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6039    and     r9, r9, #15                 @ r9<- A
6040    flds    s1, [r3]                    @ s1<- vB
6041    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6042    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6043    flds    s0, [r9]                    @ s0<- vA
6044
6045    fadds   s2, s0, s1                              @ s2<- op
6046    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6047    fsts    s2, [r9]                    @ vAA<- s2
6048    GOTO_OPCODE(ip)                     @ jump to next instruction
6049
6050
6051/* ------------------------------ */
6052    .balign 64
6053.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
6054/* File: arm-vfp/OP_SUB_FLOAT_2ADDR.S */
6055/* File: arm-vfp/fbinop2addr.S */
6056    /*
6057     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6058     * an "instr" line that specifies an instruction that performs
6059     * "s2 = s0 op s1".
6060     *
6061     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6062     */
6063    /* binop/2addr vA, vB */
6064    mov     r3, rINST, lsr #12          @ r3<- B
6065    mov     r9, rINST, lsr #8           @ r9<- A+
6066    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6067    and     r9, r9, #15                 @ r9<- A
6068    flds    s1, [r3]                    @ s1<- vB
6069    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6070    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6071    flds    s0, [r9]                    @ s0<- vA
6072
6073    fsubs   s2, s0, s1                              @ s2<- op
6074    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6075    fsts    s2, [r9]                    @ vAA<- s2
6076    GOTO_OPCODE(ip)                     @ jump to next instruction
6077
6078
6079/* ------------------------------ */
6080    .balign 64
6081.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
6082/* File: arm-vfp/OP_MUL_FLOAT_2ADDR.S */
6083/* File: arm-vfp/fbinop2addr.S */
6084    /*
6085     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6086     * an "instr" line that specifies an instruction that performs
6087     * "s2 = s0 op s1".
6088     *
6089     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6090     */
6091    /* binop/2addr vA, vB */
6092    mov     r3, rINST, lsr #12          @ r3<- B
6093    mov     r9, rINST, lsr #8           @ r9<- A+
6094    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6095    and     r9, r9, #15                 @ r9<- A
6096    flds    s1, [r3]                    @ s1<- vB
6097    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6098    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6099    flds    s0, [r9]                    @ s0<- vA
6100
6101    fmuls   s2, s0, s1                              @ s2<- op
6102    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6103    fsts    s2, [r9]                    @ vAA<- s2
6104    GOTO_OPCODE(ip)                     @ jump to next instruction
6105
6106
6107/* ------------------------------ */
6108    .balign 64
6109.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
6110/* File: arm-vfp/OP_DIV_FLOAT_2ADDR.S */
6111/* File: arm-vfp/fbinop2addr.S */
6112    /*
6113     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6114     * an "instr" line that specifies an instruction that performs
6115     * "s2 = s0 op s1".
6116     *
6117     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6118     */
6119    /* binop/2addr vA, vB */
6120    mov     r3, rINST, lsr #12          @ r3<- B
6121    mov     r9, rINST, lsr #8           @ r9<- A+
6122    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6123    and     r9, r9, #15                 @ r9<- A
6124    flds    s1, [r3]                    @ s1<- vB
6125    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6126    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6127    flds    s0, [r9]                    @ s0<- vA
6128
6129    fdivs   s2, s0, s1                              @ s2<- op
6130    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6131    fsts    s2, [r9]                    @ vAA<- s2
6132    GOTO_OPCODE(ip)                     @ jump to next instruction
6133
6134
6135/* ------------------------------ */
6136    .balign 64
6137.L_OP_REM_FLOAT_2ADDR: /* 0xca */
6138/* File: armv6t2/OP_REM_FLOAT_2ADDR.S */
6139/* EABI doesn't define a float remainder function, but libm does */
6140/* File: armv6t2/binop2addr.S */
6141    /*
6142     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6143     * that specifies an instruction that performs "result = r0 op r1".
6144     * This could be an ARM instruction or a function call.  (If the result
6145     * comes back in a register other than r0, you can override "result".)
6146     *
6147     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6148     * vCC (r1).  Useful for integer division and modulus.
6149     *
6150     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6151     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6152     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6153     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6154     */
6155    /* binop/2addr vA, vB */
6156    mov     r3, rINST, lsr #12          @ r3<- B
6157    ubfx    r9, rINST, #8, #4           @ r9<- A
6158    GET_VREG(r1, r3)                    @ r1<- vB
6159    GET_VREG(r0, r9)                    @ r0<- vA
6160    .if 0
6161    cmp     r1, #0                      @ is second operand zero?
6162    beq     common_errDivideByZero
6163    .endif
6164    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6165
6166                               @ optional op; may set condition codes
6167    bl      fmodf                              @ r0<- op, r0-r3 changed
6168    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6169    SET_VREG(r0, r9)               @ vAA<- r0
6170    GOTO_OPCODE(ip)                     @ jump to next instruction
6171    /* 10-13 instructions */
6172
6173
6174/* ------------------------------ */
6175    .balign 64
6176.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
6177/* File: arm-vfp/OP_ADD_DOUBLE_2ADDR.S */
6178/* File: arm-vfp/fbinopWide2addr.S */
6179    /*
6180     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6181     * an "instr" line that specifies an instruction that performs
6182     * "d2 = d0 op d1".
6183     *
6184     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6185     *      div-double/2addr
6186     */
6187    /* binop/2addr vA, vB */
6188    mov     r3, rINST, lsr #12          @ r3<- B
6189    mov     r9, rINST, lsr #8           @ r9<- A+
6190    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6191    and     r9, r9, #15                 @ r9<- A
6192    fldd    d1, [r3]                    @ d1<- vB
6193    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6194    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6195    fldd    d0, [r9]                    @ d0<- vA
6196
6197    faddd   d2, d0, d1                              @ d2<- op
6198    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6199    fstd    d2, [r9]                    @ vAA<- d2
6200    GOTO_OPCODE(ip)                     @ jump to next instruction
6201
6202
6203/* ------------------------------ */
6204    .balign 64
6205.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
6206/* File: arm-vfp/OP_SUB_DOUBLE_2ADDR.S */
6207/* File: arm-vfp/fbinopWide2addr.S */
6208    /*
6209     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6210     * an "instr" line that specifies an instruction that performs
6211     * "d2 = d0 op d1".
6212     *
6213     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6214     *      div-double/2addr
6215     */
6216    /* binop/2addr vA, vB */
6217    mov     r3, rINST, lsr #12          @ r3<- B
6218    mov     r9, rINST, lsr #8           @ r9<- A+
6219    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6220    and     r9, r9, #15                 @ r9<- A
6221    fldd    d1, [r3]                    @ d1<- vB
6222    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6223    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6224    fldd    d0, [r9]                    @ d0<- vA
6225
6226    fsubd   d2, d0, d1                              @ d2<- op
6227    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6228    fstd    d2, [r9]                    @ vAA<- d2
6229    GOTO_OPCODE(ip)                     @ jump to next instruction
6230
6231
6232/* ------------------------------ */
6233    .balign 64
6234.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
6235/* File: arm-vfp/OP_MUL_DOUBLE_2ADDR.S */
6236/* File: arm-vfp/fbinopWide2addr.S */
6237    /*
6238     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6239     * an "instr" line that specifies an instruction that performs
6240     * "d2 = d0 op d1".
6241     *
6242     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6243     *      div-double/2addr
6244     */
6245    /* binop/2addr vA, vB */
6246    mov     r3, rINST, lsr #12          @ r3<- B
6247    mov     r9, rINST, lsr #8           @ r9<- A+
6248    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6249    and     r9, r9, #15                 @ r9<- A
6250    fldd    d1, [r3]                    @ d1<- vB
6251    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6252    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6253    fldd    d0, [r9]                    @ d0<- vA
6254
6255    fmuld   d2, d0, d1                              @ d2<- op
6256    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6257    fstd    d2, [r9]                    @ vAA<- d2
6258    GOTO_OPCODE(ip)                     @ jump to next instruction
6259
6260
6261/* ------------------------------ */
6262    .balign 64
6263.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */
6264/* File: arm-vfp/OP_DIV_DOUBLE_2ADDR.S */
6265/* File: arm-vfp/fbinopWide2addr.S */
6266    /*
6267     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6268     * an "instr" line that specifies an instruction that performs
6269     * "d2 = d0 op d1".
6270     *
6271     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6272     *      div-double/2addr
6273     */
6274    /* binop/2addr vA, vB */
6275    mov     r3, rINST, lsr #12          @ r3<- B
6276    mov     r9, rINST, lsr #8           @ r9<- A+
6277    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6278    and     r9, r9, #15                 @ r9<- A
6279    fldd    d1, [r3]                    @ d1<- vB
6280    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6281    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6282    fldd    d0, [r9]                    @ d0<- vA
6283
6284    fdivd   d2, d0, d1                              @ d2<- op
6285    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6286    fstd    d2, [r9]                    @ vAA<- d2
6287    GOTO_OPCODE(ip)                     @ jump to next instruction
6288
6289
6290/* ------------------------------ */
6291    .balign 64
6292.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */
6293/* File: armv6t2/OP_REM_DOUBLE_2ADDR.S */
6294/* EABI doesn't define a double remainder function, but libm does */
6295/* File: armv6t2/binopWide2addr.S */
6296    /*
6297     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6298     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6299     * This could be an ARM instruction or a function call.  (If the result
6300     * comes back in a register other than r0, you can override "result".)
6301     *
6302     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6303     * vCC (r1).  Useful for integer division and modulus.
6304     *
6305     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6306     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6307     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6308     *      rem-double/2addr
6309     */
6310    /* binop/2addr vA, vB */
6311    mov     r1, rINST, lsr #12          @ r1<- B
6312    ubfx    r9, rINST, #8, #4           @ r9<- A
6313    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6314    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6315    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6316    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6317    .if 0
6318    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6319    beq     common_errDivideByZero
6320    .endif
6321    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6322
6323                               @ optional op; may set condition codes
6324    bl      fmod                              @ result<- op, r0-r3 changed
6325    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6326    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6327    GOTO_OPCODE(ip)                     @ jump to next instruction
6328    /* 12-15 instructions */
6329
6330
6331/* ------------------------------ */
6332    .balign 64
6333.L_OP_ADD_INT_LIT16: /* 0xd0 */
6334/* File: armv6t2/OP_ADD_INT_LIT16.S */
6335/* File: armv6t2/binopLit16.S */
6336    /*
6337     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6338     * that specifies an instruction that performs "result = r0 op r1".
6339     * This could be an ARM instruction or a function call.  (If the result
6340     * comes back in a register other than r0, you can override "result".)
6341     *
6342     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6343     * vCC (r1).  Useful for integer division and modulus.
6344     *
6345     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6346     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6347     */
6348    /* binop/lit16 vA, vB, #+CCCC */
6349    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6350    mov     r2, rINST, lsr #12          @ r2<- B
6351    ubfx    r9, rINST, #8, #4           @ r9<- A
6352    GET_VREG(r0, r2)                    @ r0<- vB
6353    .if 0
6354    cmp     r1, #0                      @ is second operand zero?
6355    beq     common_errDivideByZero
6356    .endif
6357    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6358
6359    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
6360    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6361    SET_VREG(r0, r9)               @ vAA<- r0
6362    GOTO_OPCODE(ip)                     @ jump to next instruction
6363    /* 10-13 instructions */
6364
6365
6366/* ------------------------------ */
6367    .balign 64
6368.L_OP_RSUB_INT: /* 0xd1 */
6369/* File: armv6t2/OP_RSUB_INT.S */
6370/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
6371/* File: armv6t2/binopLit16.S */
6372    /*
6373     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6374     * that specifies an instruction that performs "result = r0 op r1".
6375     * This could be an ARM instruction or a function call.  (If the result
6376     * comes back in a register other than r0, you can override "result".)
6377     *
6378     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6379     * vCC (r1).  Useful for integer division and modulus.
6380     *
6381     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6382     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6383     */
6384    /* binop/lit16 vA, vB, #+CCCC */
6385    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6386    mov     r2, rINST, lsr #12          @ r2<- B
6387    ubfx    r9, rINST, #8, #4           @ r9<- A
6388    GET_VREG(r0, r2)                    @ r0<- vB
6389    .if 0
6390    cmp     r1, #0                      @ is second operand zero?
6391    beq     common_errDivideByZero
6392    .endif
6393    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6394
6395    rsb     r0, r0, r1                              @ r0<- op, r0-r3 changed
6396    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6397    SET_VREG(r0, r9)               @ vAA<- r0
6398    GOTO_OPCODE(ip)                     @ jump to next instruction
6399    /* 10-13 instructions */
6400
6401
6402/* ------------------------------ */
6403    .balign 64
6404.L_OP_MUL_INT_LIT16: /* 0xd2 */
6405/* File: armv6t2/OP_MUL_INT_LIT16.S */
6406/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
6407/* File: armv6t2/binopLit16.S */
6408    /*
6409     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6410     * that specifies an instruction that performs "result = r0 op r1".
6411     * This could be an ARM instruction or a function call.  (If the result
6412     * comes back in a register other than r0, you can override "result".)
6413     *
6414     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6415     * vCC (r1).  Useful for integer division and modulus.
6416     *
6417     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6418     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6419     */
6420    /* binop/lit16 vA, vB, #+CCCC */
6421    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6422    mov     r2, rINST, lsr #12          @ r2<- B
6423    ubfx    r9, rINST, #8, #4           @ r9<- A
6424    GET_VREG(r0, r2)                    @ r0<- vB
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    mul     r0, r1, r0                              @ 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_DIV_INT_LIT16: /* 0xd3 */
6441/* File: armv6t2/OP_DIV_INT_LIT16.S */
6442/* File: armv6t2/binopLit16.S */
6443    /*
6444     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6445     * that specifies an instruction that performs "result = r0 op r1".
6446     * This could be an ARM instruction or a function call.  (If the result
6447     * comes back in a register other than r0, you can override "result".)
6448     *
6449     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6450     * vCC (r1).  Useful for integer division and modulus.
6451     *
6452     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6453     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6454     */
6455    /* binop/lit16 vA, vB, #+CCCC */
6456    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6457    mov     r2, rINST, lsr #12          @ r2<- B
6458    ubfx    r9, rINST, #8, #4           @ r9<- A
6459    GET_VREG(r0, r2)                    @ r0<- vB
6460    .if 1
6461    cmp     r1, #0                      @ is second operand zero?
6462    beq     common_errDivideByZero
6463    .endif
6464    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6465
6466    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
6467    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6468    SET_VREG(r0, r9)               @ vAA<- r0
6469    GOTO_OPCODE(ip)                     @ jump to next instruction
6470    /* 10-13 instructions */
6471
6472
6473/* ------------------------------ */
6474    .balign 64
6475.L_OP_REM_INT_LIT16: /* 0xd4 */
6476/* File: armv6t2/OP_REM_INT_LIT16.S */
6477/* idivmod returns quotient in r0 and remainder in r1 */
6478/* File: armv6t2/binopLit16.S */
6479    /*
6480     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6481     * that specifies an instruction that performs "result = r0 op r1".
6482     * This could be an ARM instruction or a function call.  (If the result
6483     * comes back in a register other than r0, you can override "result".)
6484     *
6485     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6486     * vCC (r1).  Useful for integer division and modulus.
6487     *
6488     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6489     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6490     */
6491    /* binop/lit16 vA, vB, #+CCCC */
6492    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6493    mov     r2, rINST, lsr #12          @ r2<- B
6494    ubfx    r9, rINST, #8, #4           @ r9<- A
6495    GET_VREG(r0, r2)                    @ r0<- vB
6496    .if 1
6497    cmp     r1, #0                      @ is second operand zero?
6498    beq     common_errDivideByZero
6499    .endif
6500    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6501
6502    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
6503    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6504    SET_VREG(r1, r9)               @ vAA<- r1
6505    GOTO_OPCODE(ip)                     @ jump to next instruction
6506    /* 10-13 instructions */
6507
6508
6509/* ------------------------------ */
6510    .balign 64
6511.L_OP_AND_INT_LIT16: /* 0xd5 */
6512/* File: armv6t2/OP_AND_INT_LIT16.S */
6513/* File: armv6t2/binopLit16.S */
6514    /*
6515     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6516     * that specifies an instruction that performs "result = r0 op r1".
6517     * This could be an ARM instruction or a function call.  (If the result
6518     * comes back in a register other than r0, you can override "result".)
6519     *
6520     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6521     * vCC (r1).  Useful for integer division and modulus.
6522     *
6523     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6524     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6525     */
6526    /* binop/lit16 vA, vB, #+CCCC */
6527    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6528    mov     r2, rINST, lsr #12          @ r2<- B
6529    ubfx    r9, rINST, #8, #4           @ r9<- A
6530    GET_VREG(r0, r2)                    @ r0<- vB
6531    .if 0
6532    cmp     r1, #0                      @ is second operand zero?
6533    beq     common_errDivideByZero
6534    .endif
6535    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6536
6537    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
6538    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6539    SET_VREG(r0, r9)               @ vAA<- r0
6540    GOTO_OPCODE(ip)                     @ jump to next instruction
6541    /* 10-13 instructions */
6542
6543
6544/* ------------------------------ */
6545    .balign 64
6546.L_OP_OR_INT_LIT16: /* 0xd6 */
6547/* File: armv6t2/OP_OR_INT_LIT16.S */
6548/* File: armv6t2/binopLit16.S */
6549    /*
6550     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6551     * that specifies an instruction that performs "result = r0 op r1".
6552     * This could be an ARM instruction or a function call.  (If the result
6553     * comes back in a register other than r0, you can override "result".)
6554     *
6555     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6556     * vCC (r1).  Useful for integer division and modulus.
6557     *
6558     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6559     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6560     */
6561    /* binop/lit16 vA, vB, #+CCCC */
6562    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6563    mov     r2, rINST, lsr #12          @ r2<- B
6564    ubfx    r9, rINST, #8, #4           @ r9<- A
6565    GET_VREG(r0, r2)                    @ r0<- vB
6566    .if 0
6567    cmp     r1, #0                      @ is second operand zero?
6568    beq     common_errDivideByZero
6569    .endif
6570    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6571
6572    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
6573    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6574    SET_VREG(r0, r9)               @ vAA<- r0
6575    GOTO_OPCODE(ip)                     @ jump to next instruction
6576    /* 10-13 instructions */
6577
6578
6579/* ------------------------------ */
6580    .balign 64
6581.L_OP_XOR_INT_LIT16: /* 0xd7 */
6582/* File: armv6t2/OP_XOR_INT_LIT16.S */
6583/* File: armv6t2/binopLit16.S */
6584    /*
6585     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6586     * that specifies an instruction that performs "result = r0 op r1".
6587     * This could be an ARM instruction or a function call.  (If the result
6588     * comes back in a register other than r0, you can override "result".)
6589     *
6590     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6591     * vCC (r1).  Useful for integer division and modulus.
6592     *
6593     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6594     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6595     */
6596    /* binop/lit16 vA, vB, #+CCCC */
6597    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6598    mov     r2, rINST, lsr #12          @ r2<- B
6599    ubfx    r9, rINST, #8, #4           @ r9<- A
6600    GET_VREG(r0, r2)                    @ r0<- vB
6601    .if 0
6602    cmp     r1, #0                      @ is second operand zero?
6603    beq     common_errDivideByZero
6604    .endif
6605    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6606
6607    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
6608    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6609    SET_VREG(r0, r9)               @ vAA<- r0
6610    GOTO_OPCODE(ip)                     @ jump to next instruction
6611    /* 10-13 instructions */
6612
6613
6614/* ------------------------------ */
6615    .balign 64
6616.L_OP_ADD_INT_LIT8: /* 0xd8 */
6617/* File: armv5te/OP_ADD_INT_LIT8.S */
6618/* File: armv5te/binopLit8.S */
6619    /*
6620     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6621     * that specifies an instruction that performs "result = r0 op r1".
6622     * This could be an ARM instruction or a function call.  (If the result
6623     * comes back in a register other than r0, you can override "result".)
6624     *
6625     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6626     * vCC (r1).  Useful for integer division and modulus.
6627     *
6628     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6629     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6630     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6631     */
6632    /* binop/lit8 vAA, vBB, #+CC */
6633    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6634    mov     r9, rINST, lsr #8           @ r9<- AA
6635    and     r2, r3, #255                @ r2<- BB
6636    GET_VREG(r0, r2)                    @ r0<- vBB
6637    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6638    .if 0
6639    @cmp     r1, #0                      @ is second operand zero?
6640    beq     common_errDivideByZero
6641    .endif
6642    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6643
6644                               @ optional op; may set condition codes
6645    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
6646    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6647    SET_VREG(r0, r9)               @ vAA<- r0
6648    GOTO_OPCODE(ip)                     @ jump to next instruction
6649    /* 10-12 instructions */
6650
6651
6652/* ------------------------------ */
6653    .balign 64
6654.L_OP_RSUB_INT_LIT8: /* 0xd9 */
6655/* File: armv5te/OP_RSUB_INT_LIT8.S */
6656/* File: armv5te/binopLit8.S */
6657    /*
6658     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6659     * that specifies an instruction that performs "result = r0 op r1".
6660     * This could be an ARM instruction or a function call.  (If the result
6661     * comes back in a register other than r0, you can override "result".)
6662     *
6663     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6664     * vCC (r1).  Useful for integer division and modulus.
6665     *
6666     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6667     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6668     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6669     */
6670    /* binop/lit8 vAA, vBB, #+CC */
6671    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6672    mov     r9, rINST, lsr #8           @ r9<- AA
6673    and     r2, r3, #255                @ r2<- BB
6674    GET_VREG(r0, r2)                    @ r0<- vBB
6675    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6676    .if 0
6677    @cmp     r1, #0                      @ is second operand zero?
6678    beq     common_errDivideByZero
6679    .endif
6680    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6681
6682                               @ optional op; may set condition codes
6683    rsb     r0, r0, r1                              @ r0<- op, r0-r3 changed
6684    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6685    SET_VREG(r0, r9)               @ vAA<- r0
6686    GOTO_OPCODE(ip)                     @ jump to next instruction
6687    /* 10-12 instructions */
6688
6689
6690/* ------------------------------ */
6691    .balign 64
6692.L_OP_MUL_INT_LIT8: /* 0xda */
6693/* File: armv5te/OP_MUL_INT_LIT8.S */
6694/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
6695/* File: armv5te/binopLit8.S */
6696    /*
6697     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6698     * that specifies an instruction that performs "result = r0 op r1".
6699     * This could be an ARM instruction or a function call.  (If the result
6700     * comes back in a register other than r0, you can override "result".)
6701     *
6702     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6703     * vCC (r1).  Useful for integer division and modulus.
6704     *
6705     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6706     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6707     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6708     */
6709    /* binop/lit8 vAA, vBB, #+CC */
6710    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6711    mov     r9, rINST, lsr #8           @ r9<- AA
6712    and     r2, r3, #255                @ r2<- BB
6713    GET_VREG(r0, r2)                    @ r0<- vBB
6714    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6715    .if 0
6716    @cmp     r1, #0                      @ is second operand zero?
6717    beq     common_errDivideByZero
6718    .endif
6719    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6720
6721                               @ optional op; may set condition codes
6722    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
6723    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6724    SET_VREG(r0, r9)               @ vAA<- r0
6725    GOTO_OPCODE(ip)                     @ jump to next instruction
6726    /* 10-12 instructions */
6727
6728
6729/* ------------------------------ */
6730    .balign 64
6731.L_OP_DIV_INT_LIT8: /* 0xdb */
6732/* File: armv5te/OP_DIV_INT_LIT8.S */
6733/* File: armv5te/binopLit8.S */
6734    /*
6735     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6736     * that specifies an instruction that performs "result = r0 op r1".
6737     * This could be an ARM instruction or a function call.  (If the result
6738     * comes back in a register other than r0, you can override "result".)
6739     *
6740     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6741     * vCC (r1).  Useful for integer division and modulus.
6742     *
6743     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6744     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6745     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6746     */
6747    /* binop/lit8 vAA, vBB, #+CC */
6748    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6749    mov     r9, rINST, lsr #8           @ r9<- AA
6750    and     r2, r3, #255                @ r2<- BB
6751    GET_VREG(r0, r2)                    @ r0<- vBB
6752    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6753    .if 1
6754    @cmp     r1, #0                      @ is second operand zero?
6755    beq     common_errDivideByZero
6756    .endif
6757    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6758
6759                               @ optional op; may set condition codes
6760    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
6761    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6762    SET_VREG(r0, r9)               @ vAA<- r0
6763    GOTO_OPCODE(ip)                     @ jump to next instruction
6764    /* 10-12 instructions */
6765
6766
6767/* ------------------------------ */
6768    .balign 64
6769.L_OP_REM_INT_LIT8: /* 0xdc */
6770/* File: armv5te/OP_REM_INT_LIT8.S */
6771/* idivmod returns quotient in r0 and remainder in r1 */
6772/* File: armv5te/binopLit8.S */
6773    /*
6774     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6775     * that specifies an instruction that performs "result = r0 op r1".
6776     * This could be an ARM instruction or a function call.  (If the result
6777     * comes back in a register other than r0, you can override "result".)
6778     *
6779     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6780     * vCC (r1).  Useful for integer division and modulus.
6781     *
6782     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6783     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6784     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6785     */
6786    /* binop/lit8 vAA, vBB, #+CC */
6787    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6788    mov     r9, rINST, lsr #8           @ r9<- AA
6789    and     r2, r3, #255                @ r2<- BB
6790    GET_VREG(r0, r2)                    @ r0<- vBB
6791    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6792    .if 1
6793    @cmp     r1, #0                      @ is second operand zero?
6794    beq     common_errDivideByZero
6795    .endif
6796    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6797
6798                               @ optional op; may set condition codes
6799    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
6800    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6801    SET_VREG(r1, r9)               @ vAA<- r1
6802    GOTO_OPCODE(ip)                     @ jump to next instruction
6803    /* 10-12 instructions */
6804
6805
6806/* ------------------------------ */
6807    .balign 64
6808.L_OP_AND_INT_LIT8: /* 0xdd */
6809/* File: armv5te/OP_AND_INT_LIT8.S */
6810/* File: armv5te/binopLit8.S */
6811    /*
6812     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6813     * that specifies an instruction that performs "result = r0 op r1".
6814     * This could be an ARM instruction or a function call.  (If the result
6815     * comes back in a register other than r0, you can override "result".)
6816     *
6817     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6818     * vCC (r1).  Useful for integer division and modulus.
6819     *
6820     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6821     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6822     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6823     */
6824    /* binop/lit8 vAA, vBB, #+CC */
6825    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6826    mov     r9, rINST, lsr #8           @ r9<- AA
6827    and     r2, r3, #255                @ r2<- BB
6828    GET_VREG(r0, r2)                    @ r0<- vBB
6829    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6830    .if 0
6831    @cmp     r1, #0                      @ is second operand zero?
6832    beq     common_errDivideByZero
6833    .endif
6834    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6835
6836                               @ optional op; may set condition codes
6837    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
6838    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6839    SET_VREG(r0, r9)               @ vAA<- r0
6840    GOTO_OPCODE(ip)                     @ jump to next instruction
6841    /* 10-12 instructions */
6842
6843
6844/* ------------------------------ */
6845    .balign 64
6846.L_OP_OR_INT_LIT8: /* 0xde */
6847/* File: armv5te/OP_OR_INT_LIT8.S */
6848/* File: armv5te/binopLit8.S */
6849    /*
6850     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6851     * that specifies an instruction that performs "result = r0 op r1".
6852     * This could be an ARM instruction or a function call.  (If the result
6853     * comes back in a register other than r0, you can override "result".)
6854     *
6855     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6856     * vCC (r1).  Useful for integer division and modulus.
6857     *
6858     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6859     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6860     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6861     */
6862    /* binop/lit8 vAA, vBB, #+CC */
6863    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6864    mov     r9, rINST, lsr #8           @ r9<- AA
6865    and     r2, r3, #255                @ r2<- BB
6866    GET_VREG(r0, r2)                    @ r0<- vBB
6867    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6868    .if 0
6869    @cmp     r1, #0                      @ is second operand zero?
6870    beq     common_errDivideByZero
6871    .endif
6872    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6873
6874                               @ optional op; may set condition codes
6875    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
6876    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6877    SET_VREG(r0, r9)               @ vAA<- r0
6878    GOTO_OPCODE(ip)                     @ jump to next instruction
6879    /* 10-12 instructions */
6880
6881
6882/* ------------------------------ */
6883    .balign 64
6884.L_OP_XOR_INT_LIT8: /* 0xdf */
6885/* File: armv5te/OP_XOR_INT_LIT8.S */
6886/* File: armv5te/binopLit8.S */
6887    /*
6888     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6889     * that specifies an instruction that performs "result = r0 op r1".
6890     * This could be an ARM instruction or a function call.  (If the result
6891     * comes back in a register other than r0, you can override "result".)
6892     *
6893     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6894     * vCC (r1).  Useful for integer division and modulus.
6895     *
6896     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6897     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6898     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6899     */
6900    /* binop/lit8 vAA, vBB, #+CC */
6901    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6902    mov     r9, rINST, lsr #8           @ r9<- AA
6903    and     r2, r3, #255                @ r2<- BB
6904    GET_VREG(r0, r2)                    @ r0<- vBB
6905    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6906    .if 0
6907    @cmp     r1, #0                      @ is second operand zero?
6908    beq     common_errDivideByZero
6909    .endif
6910    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6911
6912                               @ optional op; may set condition codes
6913    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
6914    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6915    SET_VREG(r0, r9)               @ vAA<- r0
6916    GOTO_OPCODE(ip)                     @ jump to next instruction
6917    /* 10-12 instructions */
6918
6919
6920/* ------------------------------ */
6921    .balign 64
6922.L_OP_SHL_INT_LIT8: /* 0xe0 */
6923/* File: armv5te/OP_SHL_INT_LIT8.S */
6924/* File: armv5te/binopLit8.S */
6925    /*
6926     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6927     * that specifies an instruction that performs "result = r0 op r1".
6928     * This could be an ARM instruction or a function call.  (If the result
6929     * comes back in a register other than r0, you can override "result".)
6930     *
6931     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6932     * vCC (r1).  Useful for integer division and modulus.
6933     *
6934     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6935     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6936     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6937     */
6938    /* binop/lit8 vAA, vBB, #+CC */
6939    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6940    mov     r9, rINST, lsr #8           @ r9<- AA
6941    and     r2, r3, #255                @ r2<- BB
6942    GET_VREG(r0, r2)                    @ r0<- vBB
6943    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6944    .if 0
6945    @cmp     r1, #0                      @ is second operand zero?
6946    beq     common_errDivideByZero
6947    .endif
6948    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6949
6950    and     r1, r1, #31                           @ optional op; may set condition codes
6951    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
6952    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6953    SET_VREG(r0, r9)               @ vAA<- r0
6954    GOTO_OPCODE(ip)                     @ jump to next instruction
6955    /* 10-12 instructions */
6956
6957
6958/* ------------------------------ */
6959    .balign 64
6960.L_OP_SHR_INT_LIT8: /* 0xe1 */
6961/* File: armv5te/OP_SHR_INT_LIT8.S */
6962/* File: armv5te/binopLit8.S */
6963    /*
6964     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6965     * that specifies an instruction that performs "result = r0 op r1".
6966     * This could be an ARM instruction or a function call.  (If the result
6967     * comes back in a register other than r0, you can override "result".)
6968     *
6969     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6970     * vCC (r1).  Useful for integer division and modulus.
6971     *
6972     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6973     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6974     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6975     */
6976    /* binop/lit8 vAA, vBB, #+CC */
6977    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6978    mov     r9, rINST, lsr #8           @ r9<- AA
6979    and     r2, r3, #255                @ r2<- BB
6980    GET_VREG(r0, r2)                    @ r0<- vBB
6981    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6982    .if 0
6983    @cmp     r1, #0                      @ is second operand zero?
6984    beq     common_errDivideByZero
6985    .endif
6986    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6987
6988    and     r1, r1, #31                           @ optional op; may set condition codes
6989    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
6990    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6991    SET_VREG(r0, r9)               @ vAA<- r0
6992    GOTO_OPCODE(ip)                     @ jump to next instruction
6993    /* 10-12 instructions */
6994
6995
6996/* ------------------------------ */
6997    .balign 64
6998.L_OP_USHR_INT_LIT8: /* 0xe2 */
6999/* File: armv5te/OP_USHR_INT_LIT8.S */
7000/* File: armv5te/binopLit8.S */
7001    /*
7002     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7003     * that specifies an instruction that performs "result = r0 op r1".
7004     * This could be an ARM instruction or a function call.  (If the result
7005     * comes back in a register other than r0, you can override "result".)
7006     *
7007     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7008     * vCC (r1).  Useful for integer division and modulus.
7009     *
7010     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7011     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7012     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7013     */
7014    /* binop/lit8 vAA, vBB, #+CC */
7015    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7016    mov     r9, rINST, lsr #8           @ r9<- AA
7017    and     r2, r3, #255                @ r2<- BB
7018    GET_VREG(r0, r2)                    @ r0<- vBB
7019    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7020    .if 0
7021    @cmp     r1, #0                      @ is second operand zero?
7022    beq     common_errDivideByZero
7023    .endif
7024    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7025
7026    and     r1, r1, #31                           @ optional op; may set condition codes
7027    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
7028    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7029    SET_VREG(r0, r9)               @ vAA<- r0
7030    GOTO_OPCODE(ip)                     @ jump to next instruction
7031    /* 10-12 instructions */
7032
7033
7034/* ------------------------------ */
7035    .balign 64
7036.L_OP_IGET_VOLATILE: /* 0xe3 */
7037/* File: armv5te/OP_IGET_VOLATILE.S */
7038/* File: armv5te/OP_IGET.S */
7039    /*
7040     * General 32-bit instance field get.
7041     *
7042     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7043     */
7044    /* op vA, vB, field@CCCC */
7045    mov     r0, rINST, lsr #12          @ r0<- B
7046    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7047    FETCH(r1, 1)                        @ r1<- field ref CCCC
7048    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7049    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7050    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7051    cmp     r0, #0                      @ is resolved entry null?
7052    bne     .LOP_IGET_VOLATILE_finish          @ no, already resolved
70538:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7054    EXPORT_PC()                         @ resolve() could throw
7055    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7056    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7057    cmp     r0, #0
7058    bne     .LOP_IGET_VOLATILE_finish
7059    b       common_exceptionThrown
7060
7061
7062/* ------------------------------ */
7063    .balign 64
7064.L_OP_IPUT_VOLATILE: /* 0xe4 */
7065/* File: armv5te/OP_IPUT_VOLATILE.S */
7066/* File: armv5te/OP_IPUT.S */
7067    /*
7068     * General 32-bit instance field put.
7069     *
7070     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
7071     */
7072    /* op vA, vB, field@CCCC */
7073    mov     r0, rINST, lsr #12          @ r0<- B
7074    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7075    FETCH(r1, 1)                        @ r1<- field ref CCCC
7076    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7077    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7078    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7079    cmp     r0, #0                      @ is resolved entry null?
7080    bne     .LOP_IPUT_VOLATILE_finish          @ no, already resolved
70818:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7082    EXPORT_PC()                         @ resolve() could throw
7083    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7084    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7085    cmp     r0, #0                      @ success?
7086    bne     .LOP_IPUT_VOLATILE_finish          @ yes, finish up
7087    b       common_exceptionThrown
7088
7089
7090/* ------------------------------ */
7091    .balign 64
7092.L_OP_SGET_VOLATILE: /* 0xe5 */
7093/* File: armv5te/OP_SGET_VOLATILE.S */
7094/* File: armv5te/OP_SGET.S */
7095    /*
7096     * General 32-bit SGET handler.
7097     *
7098     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7099     */
7100    /* op vAA, field@BBBB */
7101    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7102    FETCH(r1, 1)                        @ r1<- field ref BBBB
7103    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7104    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7105    cmp     r0, #0                      @ is resolved entry null?
7106    beq     .LOP_SGET_VOLATILE_resolve         @ yes, do resolve
7107.LOP_SGET_VOLATILE_finish: @ field ptr in r0
7108    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7109    SMP_DMB                            @ acquiring load
7110    mov     r2, rINST, lsr #8           @ r2<- AA
7111    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7112    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7113    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7114    GOTO_OPCODE(ip)                     @ jump to next instruction
7115
7116
7117/* ------------------------------ */
7118    .balign 64
7119.L_OP_SPUT_VOLATILE: /* 0xe6 */
7120/* File: armv5te/OP_SPUT_VOLATILE.S */
7121/* File: armv5te/OP_SPUT.S */
7122    /*
7123     * General 32-bit SPUT handler.
7124     *
7125     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
7126     */
7127    /* op vAA, field@BBBB */
7128    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7129    FETCH(r1, 1)                        @ r1<- field ref BBBB
7130    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7131    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7132    cmp     r0, #0                      @ is resolved entry null?
7133    beq     .LOP_SPUT_VOLATILE_resolve         @ yes, do resolve
7134.LOP_SPUT_VOLATILE_finish:   @ field ptr in r0
7135    mov     r2, rINST, lsr #8           @ r2<- AA
7136    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7137    GET_VREG(r1, r2)                    @ r1<- fp[AA]
7138    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7139    SMP_DMB                            @ releasing store
7140    str     r1, [r0, #offStaticField_value] @ field<- vAA
7141    GOTO_OPCODE(ip)                     @ jump to next instruction
7142
7143
7144/* ------------------------------ */
7145    .balign 64
7146.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
7147/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */
7148/* File: armv5te/OP_IGET.S */
7149    /*
7150     * General 32-bit instance field get.
7151     *
7152     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7153     */
7154    /* op vA, vB, field@CCCC */
7155    mov     r0, rINST, lsr #12          @ r0<- B
7156    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7157    FETCH(r1, 1)                        @ r1<- field ref CCCC
7158    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7159    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7160    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7161    cmp     r0, #0                      @ is resolved entry null?
7162    bne     .LOP_IGET_OBJECT_VOLATILE_finish          @ no, already resolved
71638:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7164    EXPORT_PC()                         @ resolve() could throw
7165    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7166    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7167    cmp     r0, #0
7168    bne     .LOP_IGET_OBJECT_VOLATILE_finish
7169    b       common_exceptionThrown
7170
7171
7172/* ------------------------------ */
7173    .balign 64
7174.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
7175/* File: armv5te/OP_IGET_WIDE_VOLATILE.S */
7176/* File: armv5te/OP_IGET_WIDE.S */
7177    /*
7178     * Wide 32-bit instance field get.
7179     */
7180    /* iget-wide vA, vB, field@CCCC */
7181    mov     r0, rINST, lsr #12          @ r0<- B
7182    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7183    FETCH(r1, 1)                        @ r1<- field ref CCCC
7184    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7185    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7186    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7187    cmp     r0, #0                      @ is resolved entry null?
7188    bne     .LOP_IGET_WIDE_VOLATILE_finish          @ no, already resolved
71898:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
7190    EXPORT_PC()                         @ resolve() could throw
7191    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7192    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7193    cmp     r0, #0
7194    bne     .LOP_IGET_WIDE_VOLATILE_finish
7195    b       common_exceptionThrown
7196
7197
7198/* ------------------------------ */
7199    .balign 64
7200.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
7201/* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */
7202/* File: armv5te/OP_IPUT_WIDE.S */
7203    /* iput-wide vA, vB, field@CCCC */
7204    mov     r0, rINST, lsr #12          @ r0<- B
7205    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7206    FETCH(r1, 1)                        @ r1<- field ref CCCC
7207    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7208    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7209    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7210    cmp     r0, #0                      @ is resolved entry null?
7211    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ no, already resolved
72128:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
7213    EXPORT_PC()                         @ resolve() could throw
7214    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7215    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7216    cmp     r0, #0                      @ success?
7217    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ yes, finish up
7218    b       common_exceptionThrown
7219
7220
7221/* ------------------------------ */
7222    .balign 64
7223.L_OP_SGET_WIDE_VOLATILE: /* 0xea */
7224/* File: armv5te/OP_SGET_WIDE_VOLATILE.S */
7225/* File: armv5te/OP_SGET_WIDE.S */
7226    /*
7227     * 64-bit SGET handler.
7228     */
7229    /* sget-wide vAA, field@BBBB */
7230    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7231    FETCH(r1, 1)                        @ r1<- field ref BBBB
7232    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7233    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7234    cmp     r0, #0                      @ is resolved entry null?
7235    beq     .LOP_SGET_WIDE_VOLATILE_resolve         @ yes, do resolve
7236.LOP_SGET_WIDE_VOLATILE_finish:
7237    mov     r9, rINST, lsr #8           @ r9<- AA
7238    .if 1
7239    add     r0, r0, #offStaticField_value @ r0<- pointer to data
7240    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
7241    .else
7242    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
7243    .endif
7244    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7245    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7246    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
7247    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7248    GOTO_OPCODE(ip)                     @ jump to next instruction
7249
7250
7251/* ------------------------------ */
7252    .balign 64
7253.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
7254/* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */
7255/* File: armv5te/OP_SPUT_WIDE.S */
7256    /*
7257     * 64-bit SPUT handler.
7258     */
7259    /* sput-wide vAA, field@BBBB */
7260    ldr     r0, [rSELF, #offThread_methodClassDex]  @ r0<- DvmDex
7261    FETCH(r1, 1)                        @ r1<- field ref BBBB
7262    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
7263    mov     r9, rINST, lsr #8           @ r9<- AA
7264    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
7265    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7266    cmp     r2, #0                      @ is resolved entry null?
7267    beq     .LOP_SPUT_WIDE_VOLATILE_resolve         @ yes, do resolve
7268.LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9
7269    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7270    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
7271    GET_INST_OPCODE(r10)                @ extract opcode from rINST
7272    .if 1
7273    add     r2, r2, #offStaticField_value @ r2<- pointer to data
7274    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
7275    .else
7276    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
7277    .endif
7278    GOTO_OPCODE(r10)                    @ jump to next instruction
7279
7280
7281/* ------------------------------ */
7282    .balign 64
7283.L_OP_BREAKPOINT: /* 0xec */
7284/* File: armv5te/OP_BREAKPOINT.S */
7285/* File: armv5te/unused.S */
7286    bl      common_abort
7287
7288
7289/* ------------------------------ */
7290    .balign 64
7291.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
7292/* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */
7293    /*
7294     * Handle a throw-verification-error instruction.  This throws an
7295     * exception for an error discovered during verification.  The
7296     * exception is indicated by AA, with some detail provided by BBBB.
7297     */
7298    /* op AA, ref@BBBB */
7299    ldr     r0, [rSELF, #offThread_method]    @ r0<- self->method
7300    FETCH(r2, 1)                        @ r2<- BBBB
7301    EXPORT_PC()                         @ export the PC
7302    mov     r1, rINST, lsr #8           @ r1<- AA
7303    bl      dvmThrowVerificationError   @ always throws
7304    b       common_exceptionThrown      @ handle exception
7305
7306/* ------------------------------ */
7307    .balign 64
7308.L_OP_EXECUTE_INLINE: /* 0xee */
7309/* File: armv5te/OP_EXECUTE_INLINE.S */
7310    /*
7311     * Execute a "native inline" instruction.
7312     *
7313     * We need to call an InlineOp4Func:
7314     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7315     *
7316     * The first four args are in r0-r3, pointer to return value storage
7317     * is on the stack.  The function's return value is a flag that tells
7318     * us if an exception was thrown.
7319     */
7320    /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
7321    FETCH(r10, 1)                       @ r10<- BBBB
7322    add     r1, rSELF, #offThread_retval  @ r1<- &self->retval
7323    EXPORT_PC()                         @ can throw
7324    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7325    mov     r0, rINST, lsr #12          @ r0<- B
7326    str     r1, [sp]                    @ push &self->retval
7327    bl      .LOP_EXECUTE_INLINE_continue        @ make call; will return after
7328    add     sp, sp, #8                  @ pop stack
7329    cmp     r0, #0                      @ test boolean result of inline
7330    beq     common_exceptionThrown      @ returned false, handle exception
7331    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7332    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7333    GOTO_OPCODE(ip)                     @ jump to next instruction
7334
7335/* ------------------------------ */
7336    .balign 64
7337.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
7338/* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */
7339    /*
7340     * Execute a "native inline" instruction, using "/range" semantics.
7341     * Same idea as execute-inline, but we get the args differently.
7342     *
7343     * We need to call an InlineOp4Func:
7344     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7345     *
7346     * The first four args are in r0-r3, pointer to return value storage
7347     * is on the stack.  The function's return value is a flag that tells
7348     * us if an exception was thrown.
7349     */
7350    /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */
7351    FETCH(r10, 1)                       @ r10<- BBBB
7352    add     r1, rSELF, #offThread_retval  @ r1<- &self->retval
7353    EXPORT_PC()                         @ can throw
7354    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7355    mov     r0, rINST, lsr #8           @ r0<- AA
7356    str     r1, [sp]                    @ push &self->retval
7357    bl      .LOP_EXECUTE_INLINE_RANGE_continue        @ make call; will return after
7358    add     sp, sp, #8                  @ pop stack
7359    cmp     r0, #0                      @ test boolean result of inline
7360    beq     common_exceptionThrown      @ returned false, handle exception
7361    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7362    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7363    GOTO_OPCODE(ip)                     @ jump to next instruction
7364
7365/* ------------------------------ */
7366    .balign 64
7367.L_OP_INVOKE_OBJECT_INIT: /* 0xf0 */
7368/* File: armv5te/OP_INVOKE_OBJECT_INIT.S */
7369    /*
7370     * Invoke Object.<init> on an object.  In practice we know that
7371     * Object's nullary constructor doesn't do anything, so we just
7372     * skip it (we know a debugger isn't active).
7373     */
7374    FETCH(r0, 2)                        @ r0<- GFED
7375    and     r1, r0, #15                 @ r1<- D
7376    GET_VREG(r0, r1)                    @ r0<- "this" ptr
7377    cmp     r0, #0                      @ check for NULL
7378    beq     common_errNullObject        @ export PC and throw NPE
7379    ldr     r1, [r0, #offObject_clazz]  @ r1<- obj->clazz
7380    ldr     r2, [r1, #offClassObject_accessFlags] @ r2<- clazz->accessFlags
7381    tst     r2, #CLASS_ISFINALIZABLE    @ is this class finalizable?
7382    beq     1f                          @ nope, done
7383    bl      dvmSetFinalizable           @ call dvmSetFinalizable(obj)
73841:  FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
7385    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
7386    GOTO_OPCODE(ip)                     @ execute it
7387
7388/* ------------------------------ */
7389    .balign 64
7390.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */
7391/* File: armv5te/OP_RETURN_VOID_BARRIER.S */
7392    SMP_DMB_ST
7393    b       common_returnFromMethod
7394
7395/* ------------------------------ */
7396    .balign 64
7397.L_OP_IGET_QUICK: /* 0xf2 */
7398/* File: armv6t2/OP_IGET_QUICK.S */
7399    /* For: iget-quick, iget-object-quick */
7400    /* op vA, vB, offset@CCCC */
7401    mov     r2, rINST, lsr #12          @ r2<- B
7402    FETCH(r1, 1)                        @ r1<- field byte offset
7403    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7404    ubfx    r2, rINST, #8, #4           @ r2<- A
7405    cmp     r3, #0                      @ check object for null
7406    beq     common_errNullObject        @ object was null
7407    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7408    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7409    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7410    SET_VREG(r0, r2)                    @ fp[A]<- r0
7411    GOTO_OPCODE(ip)                     @ jump to next instruction
7412
7413/* ------------------------------ */
7414    .balign 64
7415.L_OP_IGET_WIDE_QUICK: /* 0xf3 */
7416/* File: armv6t2/OP_IGET_WIDE_QUICK.S */
7417    /* iget-wide-quick vA, vB, offset@CCCC */
7418    mov     r2, rINST, lsr #12          @ r2<- B
7419    FETCH(ip, 1)                        @ ip<- field byte offset
7420    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7421    ubfx    r2, rINST, #8, #4           @ r2<- A
7422    cmp     r3, #0                      @ check object for null
7423    beq     common_errNullObject        @ object was null
7424    ldrd    r0, [r3, ip]                @ r0<- obj.field (64 bits, aligned)
7425    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7426    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
7427    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7428    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
7429    GOTO_OPCODE(ip)                     @ jump to next instruction
7430
7431/* ------------------------------ */
7432    .balign 64
7433.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */
7434/* File: armv5te/OP_IGET_OBJECT_QUICK.S */
7435/* File: armv5te/OP_IGET_QUICK.S */
7436    /* For: iget-quick, iget-object-quick */
7437    /* op vA, vB, offset@CCCC */
7438    mov     r2, rINST, lsr #12          @ r2<- B
7439    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7440    FETCH(r1, 1)                        @ r1<- field byte offset
7441    cmp     r3, #0                      @ check object for null
7442    mov     r2, rINST, lsr #8           @ r2<- A(+)
7443    beq     common_errNullObject        @ object was null
7444    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7445    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7446    and     r2, r2, #15
7447    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7448    SET_VREG(r0, r2)                    @ fp[A]<- r0
7449    GOTO_OPCODE(ip)                     @ jump to next instruction
7450
7451
7452/* ------------------------------ */
7453    .balign 64
7454.L_OP_IPUT_QUICK: /* 0xf5 */
7455/* File: armv6t2/OP_IPUT_QUICK.S */
7456    /* For: iput-quick, iput-object-quick */
7457    /* op vA, vB, offset@CCCC */
7458    mov     r2, rINST, lsr #12          @ r2<- B
7459    FETCH(r1, 1)                        @ r1<- field byte offset
7460    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7461    ubfx    r2, rINST, #8, #4           @ r2<- A
7462    cmp     r3, #0                      @ check object for null
7463    beq     common_errNullObject        @ object was null
7464    GET_VREG(r0, r2)                    @ r0<- fp[A]
7465    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7466    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7467    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7468    GOTO_OPCODE(ip)                     @ jump to next instruction
7469
7470/* ------------------------------ */
7471    .balign 64
7472.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */
7473/* File: armv6t2/OP_IPUT_WIDE_QUICK.S */
7474    /* iput-wide-quick vA, vB, offset@CCCC */
7475    mov     r1, rINST, lsr #12          @ r1<- B
7476    ubfx    r0, rINST, #8, #4           @ r0<- A
7477    GET_VREG(r2, r1)                    @ r2<- fp[B], the object pointer
7478    add     r3, rFP, r0, lsl #2         @ r3<- &fp[A]
7479    cmp     r2, #0                      @ check object for null
7480    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[A]
7481    beq     common_errNullObject        @ object was null
7482    FETCH(r3, 1)                        @ r3<- field byte offset
7483    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7484    strd    r0, [r2, r3]                @ obj.field (64 bits, aligned)<- r0/r1
7485    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7486    GOTO_OPCODE(ip)                     @ jump to next instruction
7487
7488/* ------------------------------ */
7489    .balign 64
7490.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
7491/* File: armv5te/OP_IPUT_OBJECT_QUICK.S */
7492    /* For: iput-object-quick */
7493    /* op vA, vB, offset@CCCC */
7494    mov     r2, rINST, lsr #12          @ r2<- B
7495    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7496    FETCH(r1, 1)                        @ r1<- field byte offset
7497    cmp     r3, #0                      @ check object for null
7498    mov     r2, rINST, lsr #8           @ r2<- A(+)
7499    beq     common_errNullObject        @ object was null
7500    and     r2, r2, #15
7501    GET_VREG(r0, r2)                    @ r0<- fp[A]
7502    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
7503    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7504    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7505    cmp     r0, #0
7506    strneb  r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head
7507    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7508    GOTO_OPCODE(ip)                     @ jump to next instruction
7509
7510/* ------------------------------ */
7511    .balign 64
7512.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
7513/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7514    /*
7515     * Handle an optimized virtual method call.
7516     *
7517     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7518     */
7519    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7520    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7521    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7522    FETCH(r1, 1)                        @ r1<- BBBB
7523    .if     (!0)
7524    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7525    .endif
7526    GET_VREG(r2, r3)                    @ r2<- vC ("this" ptr)
7527    cmp     r2, #0                      @ is "this" null?
7528    beq     common_errNullObject        @ null "this", throw exception
7529    ldr     r2, [r2, #offObject_clazz]  @ r2<- thisPtr->clazz
7530    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7531    EXPORT_PC()                         @ invoke must export
7532    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7533    bl      common_invokeMethodNoRange @ continue on
7534
7535/* ------------------------------ */
7536    .balign 64
7537.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
7538/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */
7539/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7540    /*
7541     * Handle an optimized virtual method call.
7542     *
7543     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7544     */
7545    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7546    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7547    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7548    FETCH(r1, 1)                        @ r1<- BBBB
7549    .if     (!1)
7550    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7551    .endif
7552    GET_VREG(r2, r3)                    @ r2<- vC ("this" ptr)
7553    cmp     r2, #0                      @ is "this" null?
7554    beq     common_errNullObject        @ null "this", throw exception
7555    ldr     r2, [r2, #offObject_clazz]  @ r2<- thisPtr->clazz
7556    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7557    EXPORT_PC()                         @ invoke must export
7558    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7559    bl      common_invokeMethodRange @ continue on
7560
7561
7562/* ------------------------------ */
7563    .balign 64
7564.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */
7565/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7566    /*
7567     * Handle an optimized "super" method call.
7568     *
7569     * for: [opt] invoke-super-quick, invoke-super-quick/range
7570     */
7571    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7572    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7573    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7574    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7575    .if     (!0)
7576    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7577    .endif
7578    FETCH(r1, 1)                        @ r1<- BBBB
7579    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7580    EXPORT_PC()                         @ must export for invoke
7581    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7582    GET_VREG(r3, r10)                   @ r3<- "this"
7583    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7584    cmp     r3, #0                      @ null "this" ref?
7585    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7586    beq     common_errNullObject        @ "this" is null, throw exception
7587    bl      common_invokeMethodNoRange @ continue on
7588
7589/* ------------------------------ */
7590    .balign 64
7591.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
7592/* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */
7593/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7594    /*
7595     * Handle an optimized "super" method call.
7596     *
7597     * for: [opt] invoke-super-quick, invoke-super-quick/range
7598     */
7599    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7600    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7601    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7602    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7603    .if     (!1)
7604    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7605    .endif
7606    FETCH(r1, 1)                        @ r1<- BBBB
7607    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7608    EXPORT_PC()                         @ must export for invoke
7609    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7610    GET_VREG(r3, r10)                   @ r3<- "this"
7611    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7612    cmp     r3, #0                      @ null "this" ref?
7613    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7614    beq     common_errNullObject        @ "this" is null, throw exception
7615    bl      common_invokeMethodRange @ continue on
7616
7617
7618/* ------------------------------ */
7619    .balign 64
7620.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
7621/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */
7622/* File: armv5te/OP_IPUT_OBJECT.S */
7623    /*
7624     * 32-bit instance field put.
7625     *
7626     * for: iput-object, iput-object-volatile
7627     */
7628    /* op vA, vB, field@CCCC */
7629    mov     r0, rINST, lsr #12          @ r0<- B
7630    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7631    FETCH(r1, 1)                        @ r1<- field ref CCCC
7632    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7633    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7634    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7635    cmp     r0, #0                      @ is resolved entry null?
7636    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ no, already resolved
76378:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7638    EXPORT_PC()                         @ resolve() could throw
7639    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7640    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7641    cmp     r0, #0                      @ success?
7642    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ yes, finish up
7643    b       common_exceptionThrown
7644
7645
7646/* ------------------------------ */
7647    .balign 64
7648.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
7649/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */
7650/* File: armv5te/OP_SGET.S */
7651    /*
7652     * General 32-bit SGET handler.
7653     *
7654     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7655     */
7656    /* op vAA, field@BBBB */
7657    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7658    FETCH(r1, 1)                        @ r1<- field ref BBBB
7659    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7660    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7661    cmp     r0, #0                      @ is resolved entry null?
7662    beq     .LOP_SGET_OBJECT_VOLATILE_resolve         @ yes, do resolve
7663.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0
7664    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7665    SMP_DMB                            @ acquiring load
7666    mov     r2, rINST, lsr #8           @ r2<- AA
7667    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7668    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7669    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7670    GOTO_OPCODE(ip)                     @ jump to next instruction
7671
7672
7673/* ------------------------------ */
7674    .balign 64
7675.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
7676/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */
7677/* File: armv5te/OP_SPUT_OBJECT.S */
7678    /*
7679     * 32-bit SPUT handler for objects
7680     *
7681     * for: sput-object, sput-object-volatile
7682     */
7683    /* op vAA, field@BBBB */
7684    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7685    FETCH(r1, 1)                        @ r1<- field ref BBBB
7686    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
7687    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
7688    cmp     r0, #0                      @ is resolved entry null?
7689    bne     .LOP_SPUT_OBJECT_VOLATILE_finish          @ no, continue
7690    ldr     r9, [rSELF, #offThread_method]    @ r9<- current method
7691    EXPORT_PC()                         @ resolve() could throw, so export now
7692    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
7693    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
7694    cmp     r0, #0                      @ success?
7695    bne     .LOP_SPUT_OBJECT_VOLATILE_finish          @ yes, finish
7696    b       common_exceptionThrown      @ no, handle exception
7697
7698
7699
7700/* ------------------------------ */
7701    .balign 64
7702.L_OP_DISPATCH_FF: /* 0xff */
7703/* File: armv5te/OP_DISPATCH_FF.S */
7704    mov     ip, rINST, lsr #8           @ r9<- extended opcode
7705    add     ip, ip, #256                @ add offset for extended opcodes
7706    GOTO_OPCODE(ip)                     @ go to proper extended handler
7707
7708
7709/* ------------------------------ */
7710    .balign 64
7711.L_OP_CONST_CLASS_JUMBO: /* 0x100 */
7712/* File: armv5te/OP_CONST_CLASS_JUMBO.S */
7713    /* const-class/jumbo vBBBB, Class@AAAAAAAA */
7714    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7715    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<-self>methodClassDex
7716    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7717    ldr     r2, [r2, #offDvmDex_pResClasses]   @ r2<- dvmDex->pResClasses
7718    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7719    FETCH(r9, 3)                        @ r9<- BBBB
7720    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResClasses[AAAAaaaa]
7721    cmp     r0, #0                      @ not yet resolved?
7722    beq     .LOP_CONST_CLASS_JUMBO_resolve
7723    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
7724    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7725    SET_VREG(r0, r9)                    @ vBBBB<- r0
7726    GOTO_OPCODE(ip)                     @ jump to next instruction
7727
7728/* ------------------------------ */
7729    .balign 64
7730.L_OP_CHECK_CAST_JUMBO: /* 0x101 */
7731/* File: armv5te/OP_CHECK_CAST_JUMBO.S */
7732    /*
7733     * Check to see if a cast from one class to another is allowed.
7734     */
7735    /* check-cast/jumbo vBBBB, class@AAAAAAAA */
7736    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7737    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7738    FETCH(r3, 3)                        @ r3<- BBBB
7739    orr     r2, r0, r2, lsl #16         @ r2<- AAAAaaaa
7740    GET_VREG(r9, r3)                    @ r9<- object
7741    ldr     r0, [rSELF, #offThread_methodClassDex]    @ r0<- pDvmDex
7742    cmp     r9, #0                      @ is object null?
7743    ldr     r0, [r0, #offDvmDex_pResClasses]    @ r0<- pDvmDex->pResClasses
7744    beq     .LOP_CHECK_CAST_JUMBO_okay            @ null obj, cast always succeeds
7745    ldr     r1, [r0, r2, lsl #2]        @ r1<- resolved class
7746    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
7747    cmp     r1, #0                      @ have we resolved this before?
7748    beq     .LOP_CHECK_CAST_JUMBO_resolve         @ not resolved, do it now
7749.LOP_CHECK_CAST_JUMBO_resolved:
7750    cmp     r0, r1                      @ same class (trivial success)?
7751    bne     .LOP_CHECK_CAST_JUMBO_fullcheck       @ no, do full check
7752    b       .LOP_CHECK_CAST_JUMBO_okay            @ yes, finish up
7753
7754/* ------------------------------ */
7755    .balign 64
7756.L_OP_INSTANCE_OF_JUMBO: /* 0x102 */
7757/* File: armv5te/OP_INSTANCE_OF_JUMBO.S */
7758    /*
7759     * Check to see if an object reference is an instance of a class.
7760     *
7761     * Most common situation is a non-null object, being compared against
7762     * an already-resolved class.
7763     *
7764     * TODO: convert most of this into a common subroutine, shared with
7765     *       OP_INSTANCE_OF.S.
7766     */
7767    /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */
7768    FETCH(r3, 4)                        @ r3<- vCCCC
7769    FETCH(r9, 3)                        @ r9<- vBBBB
7770    GET_VREG(r0, r3)                    @ r0<- vCCCC (object)
7771    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- pDvmDex
7772    cmp     r0, #0                      @ is object null?
7773    beq     .LOP_INSTANCE_OF_JUMBO_store           @ null obj, not an instance, store r0
7774    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7775    FETCH(r3, 2)                        @ r3<- AAAA (hi)
7776    ldr     r2, [r2, #offDvmDex_pResClasses]    @ r2<- pDvmDex->pResClasses
7777    orr     r3, r1, r3, lsl #16         @ r3<- AAAAaaaa
7778    ldr     r1, [r2, r3, lsl #2]        @ r1<- resolved class
7779    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
7780    cmp     r1, #0                      @ have we resolved this before?
7781    beq     .LOP_INSTANCE_OF_JUMBO_resolve         @ not resolved, do it now
7782    b       .LOP_INSTANCE_OF_JUMBO_resolved        @ resolved, continue
7783
7784/* ------------------------------ */
7785    .balign 64
7786.L_OP_NEW_INSTANCE_JUMBO: /* 0x103 */
7787/* File: armv5te/OP_NEW_INSTANCE_JUMBO.S */
7788    /*
7789     * Create a new instance of a class.
7790     */
7791    /* new-instance/jumbo vBBBB, class@AAAAAAAA */
7792    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7793    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7794    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
7795    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7796    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7797    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
7798    EXPORT_PC()                         @ req'd for init, resolve, alloc
7799    cmp     r0, #0                      @ already resolved?
7800    beq     .LOP_NEW_INSTANCE_JUMBO_resolve         @ no, resolve it now
7801.LOP_NEW_INSTANCE_JUMBO_resolved:   @ r0=class
7802    ldrb    r1, [r0, #offClassObject_status]    @ r1<- ClassStatus enum
7803    cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
7804    bne     .LOP_NEW_INSTANCE_JUMBO_needinit        @ no, init class now
7805.LOP_NEW_INSTANCE_JUMBO_initialized: @ r0=class
7806    mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
7807    bl      dvmAllocObject              @ r0<- new object
7808    b       .LOP_NEW_INSTANCE_JUMBO_finish          @ continue
7809
7810/* ------------------------------ */
7811    .balign 64
7812.L_OP_NEW_ARRAY_JUMBO: /* 0x104 */
7813/* File: armv5te/OP_NEW_ARRAY_JUMBO.S */
7814    /*
7815     * Allocate an array of objects, specified with the array class
7816     * and a count.
7817     *
7818     * The verifier guarantees that this is an array class, so we don't
7819     * check for it here.
7820     */
7821    /* new-array/jumbo vBBBB, vCCCC, class@AAAAAAAA */
7822    FETCH(r2, 1)                        @ r2<- aaaa (lo)
7823    FETCH(r3, 2)                        @ r3<- AAAA (hi)
7824    FETCH(r0, 4)                        @ r0<- vCCCC
7825    orr     r2, r2, r3, lsl #16         @ r2<- AAAAaaaa
7826    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
7827    GET_VREG(r1, r0)                    @ r1<- vCCCC (array length)
7828    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7829    cmp     r1, #0                      @ check length
7830    ldr     r0, [r3, r2, lsl #2]        @ r0<- resolved class
7831    bmi     common_errNegativeArraySize @ negative length, bail - len in r1
7832    cmp     r0, #0                      @ already resolved?
7833    EXPORT_PC()                         @ req'd for resolve, alloc
7834    bne     .LOP_NEW_ARRAY_JUMBO_finish          @ resolved, continue
7835    b       .LOP_NEW_ARRAY_JUMBO_resolve         @ do resolve now
7836
7837/* ------------------------------ */
7838    .balign 64
7839.L_OP_FILLED_NEW_ARRAY_JUMBO: /* 0x105 */
7840/* File: armv5te/OP_FILLED_NEW_ARRAY_JUMBO.S */
7841    /*
7842     * Create a new array with elements filled from registers.
7843     *
7844     * TODO: convert most of this into a common subroutine, shared with
7845     *       OP_FILLED_NEW_ARRAY.S.
7846     */
7847    /* filled-new-array/jumbo {vCCCC..v(CCCC+BBBB-1)}, type@AAAAAAAA */
7848    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
7849    FETCH(r0, 1)                        @ r0<- aaaa (lo)
7850    FETCH(r1, 2)                        @ r1<- AAAA (hi)
7851    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
7852    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
7853    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
7854    EXPORT_PC()                         @ need for resolve and alloc
7855    cmp     r0, #0                      @ already resolved?
7856    bne     .LOP_FILLED_NEW_ARRAY_JUMBO_continue        @ yes, continue on
78578:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
7858    mov     r2, #0                      @ r2<- false
7859    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
7860    bl      dvmResolveClass             @ r0<- call(clazz, ref)
7861    cmp     r0, #0                      @ got null?
7862    beq     common_exceptionThrown      @ yes, handle exception
7863    b       .LOP_FILLED_NEW_ARRAY_JUMBO_continue
7864
7865/* ------------------------------ */
7866    .balign 64
7867.L_OP_IGET_JUMBO: /* 0x106 */
7868/* File: armv5te/OP_IGET_JUMBO.S */
7869    /*
7870     * Jumbo 32-bit instance field get.
7871     *
7872     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7873     *      iget-char/jumbo, iget-short/jumbo
7874     */
7875    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7876    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7877    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7878    FETCH(r0, 4)                        @ r0<- CCCC
7879    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7880    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7881    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7882    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7883    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7884    cmp     r0, #0                      @ is resolved entry null?
7885    bne     .LOP_IGET_JUMBO_finish          @ no, already resolved
78868:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7887    EXPORT_PC()                         @ resolve() could throw
7888    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7889    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7890    b       .LOP_IGET_JUMBO_resolved        @ resolved, continue
7891
7892/* ------------------------------ */
7893    .balign 64
7894.L_OP_IGET_WIDE_JUMBO: /* 0x107 */
7895/* File: armv5te/OP_IGET_WIDE_JUMBO.S */
7896    /*
7897     * Jumbo 64-bit instance field get.
7898     */
7899    /* iget-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
7900    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7901    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7902    FETCH(r0, 4)                        @ r0<- CCCC
7903    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7904    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7905    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7906    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7907    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7908    cmp     r0, #0                      @ is resolved entry null?
7909    bne     .LOP_IGET_WIDE_JUMBO_finish          @ no, already resolved
79108:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
7911    EXPORT_PC()                         @ resolve() could throw
7912    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7913    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7914    b       .LOP_IGET_WIDE_JUMBO_resolved        @ resolved, continue
7915
7916/* ------------------------------ */
7917    .balign 64
7918.L_OP_IGET_OBJECT_JUMBO: /* 0x108 */
7919/* File: armv5te/OP_IGET_OBJECT_JUMBO.S */
7920/* File: armv5te/OP_IGET_JUMBO.S */
7921    /*
7922     * Jumbo 32-bit instance field get.
7923     *
7924     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7925     *      iget-char/jumbo, iget-short/jumbo
7926     */
7927    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7928    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7929    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7930    FETCH(r0, 4)                        @ r0<- CCCC
7931    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7932    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7933    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7934    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7935    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7936    cmp     r0, #0                      @ is resolved entry null?
7937    bne     .LOP_IGET_OBJECT_JUMBO_finish          @ no, already resolved
79388:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7939    EXPORT_PC()                         @ resolve() could throw
7940    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7941    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7942    b       .LOP_IGET_OBJECT_JUMBO_resolved        @ resolved, continue
7943
7944
7945/* ------------------------------ */
7946    .balign 64
7947.L_OP_IGET_BOOLEAN_JUMBO: /* 0x109 */
7948/* File: armv5te/OP_IGET_BOOLEAN_JUMBO.S */
7949@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrb", "sqnum":"1" }
7950/* File: armv5te/OP_IGET_JUMBO.S */
7951    /*
7952     * Jumbo 32-bit instance field get.
7953     *
7954     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7955     *      iget-char/jumbo, iget-short/jumbo
7956     */
7957    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7958    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7959    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7960    FETCH(r0, 4)                        @ r0<- CCCC
7961    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7962    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7963    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7964    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7965    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7966    cmp     r0, #0                      @ is resolved entry null?
7967    bne     .LOP_IGET_BOOLEAN_JUMBO_finish          @ no, already resolved
79688:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7969    EXPORT_PC()                         @ resolve() could throw
7970    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7971    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7972    b       .LOP_IGET_BOOLEAN_JUMBO_resolved        @ resolved, continue
7973
7974
7975/* ------------------------------ */
7976    .balign 64
7977.L_OP_IGET_BYTE_JUMBO: /* 0x10a */
7978/* File: armv5te/OP_IGET_BYTE_JUMBO.S */
7979@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsb", "sqnum":"2" }
7980/* File: armv5te/OP_IGET_JUMBO.S */
7981    /*
7982     * Jumbo 32-bit instance field get.
7983     *
7984     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
7985     *      iget-char/jumbo, iget-short/jumbo
7986     */
7987    /* exop vBBBB, vCCCC, field@AAAAAAAA */
7988    FETCH(r1, 1)                        @ r1<- aaaa (lo)
7989    FETCH(r2, 2)                        @ r2<- AAAA (hi)
7990    FETCH(r0, 4)                        @ r0<- CCCC
7991    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7992    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
7993    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7994    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
7995    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7996    cmp     r0, #0                      @ is resolved entry null?
7997    bne     .LOP_IGET_BYTE_JUMBO_finish          @ no, already resolved
79988:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7999    EXPORT_PC()                         @ resolve() could throw
8000    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8001    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8002    b       .LOP_IGET_BYTE_JUMBO_resolved        @ resolved, continue
8003
8004
8005/* ------------------------------ */
8006    .balign 64
8007.L_OP_IGET_CHAR_JUMBO: /* 0x10b */
8008/* File: armv5te/OP_IGET_CHAR_JUMBO.S */
8009@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrh", "sqnum":"3" }
8010/* File: armv5te/OP_IGET_JUMBO.S */
8011    /*
8012     * Jumbo 32-bit instance field get.
8013     *
8014     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8015     *      iget-char/jumbo, iget-short/jumbo
8016     */
8017    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8018    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8019    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8020    FETCH(r0, 4)                        @ r0<- CCCC
8021    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8022    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8023    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8024    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8025    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8026    cmp     r0, #0                      @ is resolved entry null?
8027    bne     .LOP_IGET_CHAR_JUMBO_finish          @ no, already resolved
80288:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8029    EXPORT_PC()                         @ resolve() could throw
8030    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8031    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8032    b       .LOP_IGET_CHAR_JUMBO_resolved        @ resolved, continue
8033
8034
8035/* ------------------------------ */
8036    .balign 64
8037.L_OP_IGET_SHORT_JUMBO: /* 0x10c */
8038/* File: armv5te/OP_IGET_SHORT_JUMBO.S */
8039@include "armv5te/OP_IGET_JUMBO.S" { "load":"ldrsh", "sqnum":"4" }
8040/* File: armv5te/OP_IGET_JUMBO.S */
8041    /*
8042     * Jumbo 32-bit instance field get.
8043     *
8044     * for: iget/jumbo, iget-object/jumbo, iget-boolean/jumbo, iget-byte/jumbo,
8045     *      iget-char/jumbo, iget-short/jumbo
8046     */
8047    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8048    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8049    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8050    FETCH(r0, 4)                        @ r0<- CCCC
8051    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8052    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8053    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8054    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8055    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8056    cmp     r0, #0                      @ is resolved entry null?
8057    bne     .LOP_IGET_SHORT_JUMBO_finish          @ no, already resolved
80588:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8059    EXPORT_PC()                         @ resolve() could throw
8060    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8061    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8062    b       .LOP_IGET_SHORT_JUMBO_resolved        @ resolved, continue
8063
8064
8065/* ------------------------------ */
8066    .balign 64
8067.L_OP_IPUT_JUMBO: /* 0x10d */
8068/* File: armv5te/OP_IPUT_JUMBO.S */
8069    /*
8070     * Jumbo 32-bit instance field put.
8071     *
8072     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8073     *      iput-short/jumbo
8074     */
8075    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8076    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8077    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8078    FETCH(r0, 4)                        @ r0<- CCCC
8079    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8080    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8081    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8082    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8083    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8084    cmp     r0, #0                      @ is resolved entry null?
8085    bne     .LOP_IPUT_JUMBO_finish          @ no, already resolved
80868:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8087    EXPORT_PC()                         @ resolve() could throw
8088    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8089    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8090    b       .LOP_IPUT_JUMBO_resolved        @ resolved, continue
8091
8092/* ------------------------------ */
8093    .balign 64
8094.L_OP_IPUT_WIDE_JUMBO: /* 0x10e */
8095/* File: armv5te/OP_IPUT_WIDE_JUMBO.S */
8096    /* iput-wide/jumbo vBBBB, vCCCC, field@AAAAAAAA */
8097    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8098    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8099    FETCH(r0, 4)                        @ r0<- CCCC
8100    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8101    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8102    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
8103    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
8104    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8105    cmp     r0, #0                      @ is resolved entry null?
8106    bne     .LOP_IPUT_WIDE_JUMBO_finish          @ no, already resolved
81078:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
8108    EXPORT_PC()                         @ resolve() could throw
8109    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8110    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8111    b       .LOP_IPUT_WIDE_JUMBO_resolved        @ resolved, continue
8112
8113/* ------------------------------ */
8114    .balign 64
8115.L_OP_IPUT_OBJECT_JUMBO: /* 0x10f */
8116/* File: armv5te/OP_IPUT_OBJECT_JUMBO.S */
8117    /*
8118     * Jumbo 32-bit instance field put.
8119     */
8120    /* iput-object/jumbo vBBBB, vCCCC, field@AAAAAAAA */
8121    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8122    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8123    FETCH(r0, 4)                        @ r0<- CCCC
8124    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8125    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8126    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8127    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8128    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8129    cmp     r0, #0                      @ is resolved entry null?
8130    bne     .LOP_IPUT_OBJECT_JUMBO_finish          @ no, already resolved
81318:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8132    EXPORT_PC()                         @ resolve() could throw
8133    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8134    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8135    b       .LOP_IPUT_OBJECT_JUMBO_resolved        @ resolved, continue
8136
8137/* ------------------------------ */
8138    .balign 64
8139.L_OP_IPUT_BOOLEAN_JUMBO: /* 0x110 */
8140/* File: armv5te/OP_IPUT_BOOLEAN_JUMBO.S */
8141@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"1" }
8142/* File: armv5te/OP_IPUT_JUMBO.S */
8143    /*
8144     * Jumbo 32-bit instance field put.
8145     *
8146     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8147     *      iput-short/jumbo
8148     */
8149    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8150    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8151    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8152    FETCH(r0, 4)                        @ r0<- CCCC
8153    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8154    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8155    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8156    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8157    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8158    cmp     r0, #0                      @ is resolved entry null?
8159    bne     .LOP_IPUT_BOOLEAN_JUMBO_finish          @ no, already resolved
81608:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8161    EXPORT_PC()                         @ resolve() could throw
8162    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8163    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8164    b       .LOP_IPUT_BOOLEAN_JUMBO_resolved        @ resolved, continue
8165
8166
8167/* ------------------------------ */
8168    .balign 64
8169.L_OP_IPUT_BYTE_JUMBO: /* 0x111 */
8170/* File: armv5te/OP_IPUT_BYTE_JUMBO.S */
8171@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strb", "sqnum":"2" }
8172/* File: armv5te/OP_IPUT_JUMBO.S */
8173    /*
8174     * Jumbo 32-bit instance field put.
8175     *
8176     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8177     *      iput-short/jumbo
8178     */
8179    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8180    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8181    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8182    FETCH(r0, 4)                        @ r0<- CCCC
8183    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8184    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8185    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8186    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8187    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8188    cmp     r0, #0                      @ is resolved entry null?
8189    bne     .LOP_IPUT_BYTE_JUMBO_finish          @ no, already resolved
81908:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8191    EXPORT_PC()                         @ resolve() could throw
8192    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8193    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8194    b       .LOP_IPUT_BYTE_JUMBO_resolved        @ resolved, continue
8195
8196
8197/* ------------------------------ */
8198    .balign 64
8199.L_OP_IPUT_CHAR_JUMBO: /* 0x112 */
8200/* File: armv5te/OP_IPUT_CHAR_JUMBO.S */
8201@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"3" }
8202/* File: armv5te/OP_IPUT_JUMBO.S */
8203    /*
8204     * Jumbo 32-bit instance field put.
8205     *
8206     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8207     *      iput-short/jumbo
8208     */
8209    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8210    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8211    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8212    FETCH(r0, 4)                        @ r0<- CCCC
8213    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8214    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8215    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8216    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8217    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8218    cmp     r0, #0                      @ is resolved entry null?
8219    bne     .LOP_IPUT_CHAR_JUMBO_finish          @ no, already resolved
82208:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8221    EXPORT_PC()                         @ resolve() could throw
8222    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8223    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8224    b       .LOP_IPUT_CHAR_JUMBO_resolved        @ resolved, continue
8225
8226
8227/* ------------------------------ */
8228    .balign 64
8229.L_OP_IPUT_SHORT_JUMBO: /* 0x113 */
8230/* File: armv5te/OP_IPUT_SHORT_JUMBO.S */
8231@include "armv5te/OP_IPUT_JUMBO.S" { "store":"strh", "sqnum":"4" }
8232/* File: armv5te/OP_IPUT_JUMBO.S */
8233    /*
8234     * Jumbo 32-bit instance field put.
8235     *
8236     * for: iput/jumbo, iput-boolean/jumbo, iput-byte/jumbo, iput-char/jumbo,
8237     *      iput-short/jumbo
8238     */
8239    /* exop vBBBB, vCCCC, field@AAAAAAAA */
8240    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8241    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8242    FETCH(r0, 4)                        @ r0<- CCCC
8243    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
8244    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8245    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
8246    GET_VREG(r9, r0)                    @ r9<- fp[CCCC], the object pointer
8247    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
8248    cmp     r0, #0                      @ is resolved entry null?
8249    bne     .LOP_IPUT_SHORT_JUMBO_finish          @ no, already resolved
82508:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8251    EXPORT_PC()                         @ resolve() could throw
8252    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8253    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
8254    b       .LOP_IPUT_SHORT_JUMBO_resolved        @ resolved, continue
8255
8256
8257/* ------------------------------ */
8258    .balign 64
8259.L_OP_SGET_JUMBO: /* 0x114 */
8260/* File: armv5te/OP_SGET_JUMBO.S */
8261    /*
8262     * Jumbo 32-bit SGET handler.
8263     *
8264     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8265     *      sget-char/jumbo, sget-short/jumbo
8266     */
8267    /* exop vBBBB, field@AAAAAAAA */
8268    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8269    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8270    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8271    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8272    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8273    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8274    cmp     r0, #0                      @ is resolved entry null?
8275    beq     .LOP_SGET_JUMBO_resolve         @ yes, do resolve
8276.LOP_SGET_JUMBO_finish: @ field ptr in r0
8277    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8278    @ no-op                             @ acquiring load
8279    FETCH(r2, 3)                        @ r2<- BBBB
8280    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8281    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8282    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8283    GOTO_OPCODE(ip)                     @ jump to next instruction
8284
8285/* ------------------------------ */
8286    .balign 64
8287.L_OP_SGET_WIDE_JUMBO: /* 0x115 */
8288/* File: armv5te/OP_SGET_WIDE_JUMBO.S */
8289    /*
8290     * Jumbo 64-bit SGET handler.
8291     */
8292    /* sget-wide/jumbo vBBBB, field@AAAAAAAA */
8293    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8294    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8295    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8296    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8297    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8298    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8299    cmp     r0, #0                      @ is resolved entry null?
8300    beq     .LOP_SGET_WIDE_JUMBO_resolve         @ yes, do resolve
8301.LOP_SGET_WIDE_JUMBO_finish:
8302    FETCH(r9, 3)                        @ r9<- BBBB
8303    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
8304    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BBBB]
8305    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8306    stmia   r9, {r0-r1}                 @ vBBBB/vBBBB+1<- r0/r1
8307    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8308    GOTO_OPCODE(ip)                     @ jump to next instruction
8309
8310/* ------------------------------ */
8311    .balign 64
8312.L_OP_SGET_OBJECT_JUMBO: /* 0x116 */
8313/* File: armv5te/OP_SGET_OBJECT_JUMBO.S */
8314/* File: armv5te/OP_SGET_JUMBO.S */
8315    /*
8316     * Jumbo 32-bit SGET handler.
8317     *
8318     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8319     *      sget-char/jumbo, sget-short/jumbo
8320     */
8321    /* exop vBBBB, field@AAAAAAAA */
8322    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8323    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8324    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8325    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8326    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8327    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8328    cmp     r0, #0                      @ is resolved entry null?
8329    beq     .LOP_SGET_OBJECT_JUMBO_resolve         @ yes, do resolve
8330.LOP_SGET_OBJECT_JUMBO_finish: @ field ptr in r0
8331    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8332    @ no-op                             @ acquiring load
8333    FETCH(r2, 3)                        @ r2<- BBBB
8334    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8335    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8336    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8337    GOTO_OPCODE(ip)                     @ jump to next instruction
8338
8339
8340/* ------------------------------ */
8341    .balign 64
8342.L_OP_SGET_BOOLEAN_JUMBO: /* 0x117 */
8343/* File: armv5te/OP_SGET_BOOLEAN_JUMBO.S */
8344/* File: armv5te/OP_SGET_JUMBO.S */
8345    /*
8346     * Jumbo 32-bit SGET handler.
8347     *
8348     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8349     *      sget-char/jumbo, sget-short/jumbo
8350     */
8351    /* exop vBBBB, field@AAAAAAAA */
8352    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8353    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8354    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8355    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8356    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8357    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8358    cmp     r0, #0                      @ is resolved entry null?
8359    beq     .LOP_SGET_BOOLEAN_JUMBO_resolve         @ yes, do resolve
8360.LOP_SGET_BOOLEAN_JUMBO_finish: @ field ptr in r0
8361    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8362    @ no-op                             @ acquiring load
8363    FETCH(r2, 3)                        @ r2<- BBBB
8364    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8365    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8366    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8367    GOTO_OPCODE(ip)                     @ jump to next instruction
8368
8369
8370/* ------------------------------ */
8371    .balign 64
8372.L_OP_SGET_BYTE_JUMBO: /* 0x118 */
8373/* File: armv5te/OP_SGET_BYTE_JUMBO.S */
8374/* File: armv5te/OP_SGET_JUMBO.S */
8375    /*
8376     * Jumbo 32-bit SGET handler.
8377     *
8378     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8379     *      sget-char/jumbo, sget-short/jumbo
8380     */
8381    /* exop vBBBB, field@AAAAAAAA */
8382    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8383    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8384    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8385    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8386    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8387    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8388    cmp     r0, #0                      @ is resolved entry null?
8389    beq     .LOP_SGET_BYTE_JUMBO_resolve         @ yes, do resolve
8390.LOP_SGET_BYTE_JUMBO_finish: @ field ptr in r0
8391    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8392    @ no-op                             @ acquiring load
8393    FETCH(r2, 3)                        @ r2<- BBBB
8394    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8395    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8396    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8397    GOTO_OPCODE(ip)                     @ jump to next instruction
8398
8399
8400/* ------------------------------ */
8401    .balign 64
8402.L_OP_SGET_CHAR_JUMBO: /* 0x119 */
8403/* File: armv5te/OP_SGET_CHAR_JUMBO.S */
8404/* File: armv5te/OP_SGET_JUMBO.S */
8405    /*
8406     * Jumbo 32-bit SGET handler.
8407     *
8408     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8409     *      sget-char/jumbo, sget-short/jumbo
8410     */
8411    /* exop vBBBB, field@AAAAAAAA */
8412    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8413    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8414    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8415    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8416    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8417    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8418    cmp     r0, #0                      @ is resolved entry null?
8419    beq     .LOP_SGET_CHAR_JUMBO_resolve         @ yes, do resolve
8420.LOP_SGET_CHAR_JUMBO_finish: @ field ptr in r0
8421    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8422    @ no-op                             @ acquiring load
8423    FETCH(r2, 3)                        @ r2<- BBBB
8424    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8425    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8426    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8427    GOTO_OPCODE(ip)                     @ jump to next instruction
8428
8429
8430/* ------------------------------ */
8431    .balign 64
8432.L_OP_SGET_SHORT_JUMBO: /* 0x11a */
8433/* File: armv5te/OP_SGET_SHORT_JUMBO.S */
8434/* File: armv5te/OP_SGET_JUMBO.S */
8435    /*
8436     * Jumbo 32-bit SGET handler.
8437     *
8438     * for: sget/jumbo, sget-object/jumbo, sget-boolean/jumbo, sget-byte/jumbo,
8439     *      sget-char/jumbo, sget-short/jumbo
8440     */
8441    /* exop vBBBB, field@AAAAAAAA */
8442    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8443    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8444    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8445    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8446    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8447    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8448    cmp     r0, #0                      @ is resolved entry null?
8449    beq     .LOP_SGET_SHORT_JUMBO_resolve         @ yes, do resolve
8450.LOP_SGET_SHORT_JUMBO_finish: @ field ptr in r0
8451    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
8452    @ no-op                             @ acquiring load
8453    FETCH(r2, 3)                        @ r2<- BBBB
8454    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8455    SET_VREG(r1, r2)                    @ fp[BBBB]<- r1
8456    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8457    GOTO_OPCODE(ip)                     @ jump to next instruction
8458
8459
8460/* ------------------------------ */
8461    .balign 64
8462.L_OP_SPUT_JUMBO: /* 0x11b */
8463/* File: armv5te/OP_SPUT_JUMBO.S */
8464    /*
8465     * Jumbo 32-bit SPUT handler.
8466     *
8467     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8468     *      sput-short/jumbo
8469     */
8470    /* exop vBBBB, field@AAAAAAAA */
8471    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8472    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8473    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8474    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8475    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8476    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8477    cmp     r0, #0                      @ is resolved entry null?
8478    beq     .LOP_SPUT_JUMBO_resolve         @ yes, do resolve
8479.LOP_SPUT_JUMBO_finish:   @ field ptr in r0
8480    FETCH(r2, 3)                        @ r2<- BBBB
8481    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8482    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8483    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8484    @ no-op                             @ releasing store
8485    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8486    GOTO_OPCODE(ip)                     @ jump to next instruction
8487
8488/* ------------------------------ */
8489    .balign 64
8490.L_OP_SPUT_WIDE_JUMBO: /* 0x11c */
8491/* File: armv5te/OP_SPUT_WIDE_JUMBO.S */
8492    /*
8493     * Jumbo 64-bit SPUT handler.
8494     */
8495    /* sput-wide/jumbo vBBBB, field@AAAAAAAA */
8496    ldr     r0, [rSELF, #offThread_methodClassDex]  @ r0<- DvmDex
8497    FETCH(r1, 1)                        @ r1<- aaaa (lo)
8498    FETCH(r2, 2)                        @ r2<- AAAA (hi)
8499    ldr     r0, [r0, #offDvmDex_pResFields] @ r0<- dvmDex->pResFields
8500    orr     r1, r1, r2, lsl #16         @ r1<- AAAAaaaa
8501    FETCH(r9, 3)                        @ r9<- BBBB
8502    ldr     r2, [r0, r1, lsl #2]        @ r2<- resolved StaticField ptr
8503    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BBBB]
8504    cmp     r2, #0                      @ is resolved entry null?
8505    beq     .LOP_SPUT_WIDE_JUMBO_resolve         @ yes, do resolve
8506.LOP_SPUT_WIDE_JUMBO_finish: @ field ptr in r2, BBBB in r9
8507    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8508    ldmia   r9, {r0-r1}                 @ r0/r1<- vBBBB/vBBBB+1
8509    GET_INST_OPCODE(r10)                @ extract opcode from rINST
8510    strd    r0, [r2, #offStaticField_value] @ field<- vBBBB/vBBBB+1
8511    GOTO_OPCODE(r10)                    @ jump to next instruction
8512
8513/* ------------------------------ */
8514    .balign 64
8515.L_OP_SPUT_OBJECT_JUMBO: /* 0x11d */
8516/* File: armv5te/OP_SPUT_OBJECT_JUMBO.S */
8517    /*
8518     * Jumbo 32-bit SPUT handler for objects
8519     */
8520    /* sput-object/jumbo vBBBB, field@AAAAAAAA */
8521    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8522    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8523    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8524    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8525    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8526    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8527    cmp     r0, #0                      @ is resolved entry null?
8528    bne     .LOP_SPUT_OBJECT_JUMBO_finish          @ no, continue
8529    ldr     r9, [rSELF, #offThread_method]    @ r9<- current method
8530    EXPORT_PC()                         @ resolve() could throw, so export now
8531    ldr     r0, [r9, #offMethod_clazz]  @ r0<- method->clazz
8532    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8533    cmp     r0, #0                      @ success?
8534    bne     .LOP_SPUT_OBJECT_JUMBO_finish          @ yes, finish
8535    b       common_exceptionThrown      @ no, handle exception
8536
8537/* ------------------------------ */
8538    .balign 64
8539.L_OP_SPUT_BOOLEAN_JUMBO: /* 0x11e */
8540/* File: armv5te/OP_SPUT_BOOLEAN_JUMBO.S */
8541/* File: armv5te/OP_SPUT_JUMBO.S */
8542    /*
8543     * Jumbo 32-bit SPUT handler.
8544     *
8545     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8546     *      sput-short/jumbo
8547     */
8548    /* exop vBBBB, field@AAAAAAAA */
8549    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8550    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8551    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8552    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8553    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8554    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8555    cmp     r0, #0                      @ is resolved entry null?
8556    beq     .LOP_SPUT_BOOLEAN_JUMBO_resolve         @ yes, do resolve
8557.LOP_SPUT_BOOLEAN_JUMBO_finish:   @ field ptr in r0
8558    FETCH(r2, 3)                        @ r2<- BBBB
8559    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8560    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8561    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8562    @ no-op                             @ releasing store
8563    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8564    GOTO_OPCODE(ip)                     @ jump to next instruction
8565
8566
8567/* ------------------------------ */
8568    .balign 64
8569.L_OP_SPUT_BYTE_JUMBO: /* 0x11f */
8570/* File: armv5te/OP_SPUT_BYTE_JUMBO.S */
8571/* File: armv5te/OP_SPUT_JUMBO.S */
8572    /*
8573     * Jumbo 32-bit SPUT handler.
8574     *
8575     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8576     *      sput-short/jumbo
8577     */
8578    /* exop vBBBB, field@AAAAAAAA */
8579    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8580    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8581    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8582    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8583    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8584    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8585    cmp     r0, #0                      @ is resolved entry null?
8586    beq     .LOP_SPUT_BYTE_JUMBO_resolve         @ yes, do resolve
8587.LOP_SPUT_BYTE_JUMBO_finish:   @ field ptr in r0
8588    FETCH(r2, 3)                        @ r2<- BBBB
8589    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8590    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8591    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8592    @ no-op                             @ releasing store
8593    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8594    GOTO_OPCODE(ip)                     @ jump to next instruction
8595
8596
8597/* ------------------------------ */
8598    .balign 64
8599.L_OP_SPUT_CHAR_JUMBO: /* 0x120 */
8600/* File: armv5te/OP_SPUT_CHAR_JUMBO.S */
8601/* File: armv5te/OP_SPUT_JUMBO.S */
8602    /*
8603     * Jumbo 32-bit SPUT handler.
8604     *
8605     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8606     *      sput-short/jumbo
8607     */
8608    /* exop vBBBB, field@AAAAAAAA */
8609    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8610    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8611    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8612    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8613    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8614    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8615    cmp     r0, #0                      @ is resolved entry null?
8616    beq     .LOP_SPUT_CHAR_JUMBO_resolve         @ yes, do resolve
8617.LOP_SPUT_CHAR_JUMBO_finish:   @ field ptr in r0
8618    FETCH(r2, 3)                        @ r2<- BBBB
8619    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8620    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8621    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8622    @ no-op                             @ releasing store
8623    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8624    GOTO_OPCODE(ip)                     @ jump to next instruction
8625
8626
8627/* ------------------------------ */
8628    .balign 64
8629.L_OP_SPUT_SHORT_JUMBO: /* 0x121 */
8630/* File: armv5te/OP_SPUT_SHORT_JUMBO.S */
8631/* File: armv5te/OP_SPUT_JUMBO.S */
8632    /*
8633     * Jumbo 32-bit SPUT handler.
8634     *
8635     * for: sput/jumbo, sput-boolean/jumbo, sput-byte/jumbo, sput-char/jumbo,
8636     *      sput-short/jumbo
8637     */
8638    /* exop vBBBB, field@AAAAAAAA */
8639    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8640    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8641    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8642    ldr     r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
8643    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8644    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved StaticField ptr
8645    cmp     r0, #0                      @ is resolved entry null?
8646    beq     .LOP_SPUT_SHORT_JUMBO_resolve         @ yes, do resolve
8647.LOP_SPUT_SHORT_JUMBO_finish:   @ field ptr in r0
8648    FETCH(r2, 3)                        @ r2<- BBBB
8649    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
8650    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
8651    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8652    @ no-op                             @ releasing store
8653    str     r1, [r0, #offStaticField_value] @ field<- vBBBB
8654    GOTO_OPCODE(ip)                     @ jump to next instruction
8655
8656
8657/* ------------------------------ */
8658    .balign 64
8659.L_OP_INVOKE_VIRTUAL_JUMBO: /* 0x122 */
8660/* File: armv5te/OP_INVOKE_VIRTUAL_JUMBO.S */
8661    /*
8662     * Handle a virtual method call.
8663     */
8664    /* invoke-virtual/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8665    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
8666    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8667    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8668    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8669    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8670    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
8671    cmp     r0, #0                      @ already resolved?
8672    EXPORT_PC()                         @ must export for invoke
8673    bne     .LOP_INVOKE_VIRTUAL_JUMBO_continue        @ yes, continue on
8674    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
8675    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8676    mov     r2, #METHOD_VIRTUAL         @ resolver method type
8677    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8678    cmp     r0, #0                      @ got null?
8679    bne     .LOP_INVOKE_VIRTUAL_JUMBO_continue        @ no, continue
8680    b       common_exceptionThrown      @ yes, handle exception
8681
8682/* ------------------------------ */
8683    .balign 64
8684.L_OP_INVOKE_SUPER_JUMBO: /* 0x123 */
8685/* File: armv5te/OP_INVOKE_SUPER_JUMBO.S */
8686    /*
8687     * Handle a "super" method call.
8688     */
8689    /* invoke-super/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8690    FETCH(r10, 4)                       @ r10<- CCCC
8691    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
8692    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8693    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8694    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8695    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8696    GET_VREG(r2, r10)                   @ r2<- "this" ptr
8697    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
8698    cmp     r2, #0                      @ null "this"?
8699    ldr     r9, [rSELF, #offThread_method] @ r9<- current method
8700    beq     common_errNullObject        @ null "this", throw exception
8701    cmp     r0, #0                      @ already resolved?
8702    ldr     r9, [r9, #offMethod_clazz]  @ r9<- method->clazz
8703    EXPORT_PC()                         @ must export for invoke
8704    bne     .LOP_INVOKE_SUPER_JUMBO_continue        @ resolved, continue on
8705    b       .LOP_INVOKE_SUPER_JUMBO_resolve         @ do resolve now
8706
8707/* ------------------------------ */
8708    .balign 64
8709.L_OP_INVOKE_DIRECT_JUMBO: /* 0x124 */
8710/* File: armv5te/OP_INVOKE_DIRECT_JUMBO.S */
8711    /*
8712     * Handle a direct method call.
8713     *
8714     * (We could defer the "is 'this' pointer null" test to the common
8715     * method invocation code, and use a flag to indicate that static
8716     * calls don't count.  If we do this as part of copying the arguments
8717     * out we could avoiding loading the first arg twice.)
8718     *
8719     */
8720    /* invoke-direct/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8721    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
8722    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8723    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8724    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8725    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8726    FETCH(r10, 4)                       @ r10<- CCCC
8727    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
8728    cmp     r0, #0                      @ already resolved?
8729    EXPORT_PC()                         @ must export for invoke
8730    GET_VREG(r2, r10)                   @ r2<- "this" ptr
8731    beq     .LOP_INVOKE_DIRECT_JUMBO_resolve         @ not resolved, do it now
8732.LOP_INVOKE_DIRECT_JUMBO_finish:
8733    cmp     r2, #0                      @ null "this" ref?
8734    bne     common_invokeMethodJumbo    @ no, continue on
8735    b       common_errNullObject        @ yes, throw exception
8736
8737/* ------------------------------ */
8738    .balign 64
8739.L_OP_INVOKE_STATIC_JUMBO: /* 0x125 */
8740/* File: armv5te/OP_INVOKE_STATIC_JUMBO.S */
8741    /*
8742     * Handle a static method call.
8743     */
8744    /* invoke-static/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8745    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
8746    FETCH(r0, 1)                        @ r1<- aaaa (lo)
8747    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8748    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
8749    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8750    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
8751    cmp     r0, #0                      @ already resolved?
8752    EXPORT_PC()                         @ must export for invoke
8753    bne     common_invokeMethodJumbo    @ yes, continue on
87540:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
8755    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8756    mov     r2, #METHOD_STATIC          @ resolver method type
8757    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8758    cmp     r0, #0                      @ got null?
8759    bne     common_invokeMethodJumbo    @ no, continue
8760    b       common_exceptionThrown      @ yes, handle exception
8761
8762/* ------------------------------ */
8763    .balign 64
8764.L_OP_INVOKE_INTERFACE_JUMBO: /* 0x126 */
8765/* File: armv5te/OP_INVOKE_INTERFACE_JUMBO.S */
8766    /*
8767     * Handle an interface method call.
8768     */
8769    /* invoke-interface/jumbo {vCCCC..v(CCCC+BBBB-1)}, meth@AAAAAAAA */
8770    FETCH(r2, 4)                        @ r2<- CCCC
8771    FETCH(r0, 1)                        @ r0<- aaaa (lo)
8772    FETCH(r1, 2)                        @ r1<- AAAA (hi)
8773    EXPORT_PC()                         @ must export for invoke
8774    orr     r1, r0, r1, lsl #16         @ r1<- AAAAaaaa
8775    GET_VREG(r0, r2)                    @ r0<- first arg ("this")
8776    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- methodClassDex
8777    cmp     r0, #0                      @ null obj?
8778    ldr     r2, [rSELF, #offThread_method]  @ r2<- method
8779    beq     common_errNullObject        @ yes, fail
8780    ldr     r0, [r0, #offObject_clazz]  @ r0<- thisPtr->clazz
8781    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
8782    cmp     r0, #0                      @ failed?
8783    beq     common_exceptionThrown      @ yes, handle exception
8784    b       common_invokeMethodJumbo    @ jump to common handler
8785
8786/* ------------------------------ */
8787    .balign 64
8788.L_OP_UNUSED_27FF: /* 0x127 */
8789/* File: armv5te/OP_UNUSED_27FF.S */
8790/* File: armv5te/unused.S */
8791    bl      common_abort
8792
8793
8794/* ------------------------------ */
8795    .balign 64
8796.L_OP_UNUSED_28FF: /* 0x128 */
8797/* File: armv5te/OP_UNUSED_28FF.S */
8798/* File: armv5te/unused.S */
8799    bl      common_abort
8800
8801
8802/* ------------------------------ */
8803    .balign 64
8804.L_OP_UNUSED_29FF: /* 0x129 */
8805/* File: armv5te/OP_UNUSED_29FF.S */
8806/* File: armv5te/unused.S */
8807    bl      common_abort
8808
8809
8810/* ------------------------------ */
8811    .balign 64
8812.L_OP_UNUSED_2AFF: /* 0x12a */
8813/* File: armv5te/OP_UNUSED_2AFF.S */
8814/* File: armv5te/unused.S */
8815    bl      common_abort
8816
8817
8818/* ------------------------------ */
8819    .balign 64
8820.L_OP_UNUSED_2BFF: /* 0x12b */
8821/* File: armv5te/OP_UNUSED_2BFF.S */
8822/* File: armv5te/unused.S */
8823    bl      common_abort
8824
8825
8826/* ------------------------------ */
8827    .balign 64
8828.L_OP_UNUSED_2CFF: /* 0x12c */
8829/* File: armv5te/OP_UNUSED_2CFF.S */
8830/* File: armv5te/unused.S */
8831    bl      common_abort
8832
8833
8834/* ------------------------------ */
8835    .balign 64
8836.L_OP_UNUSED_2DFF: /* 0x12d */
8837/* File: armv5te/OP_UNUSED_2DFF.S */
8838/* File: armv5te/unused.S */
8839    bl      common_abort
8840
8841
8842/* ------------------------------ */
8843    .balign 64
8844.L_OP_UNUSED_2EFF: /* 0x12e */
8845/* File: armv5te/OP_UNUSED_2EFF.S */
8846/* File: armv5te/unused.S */
8847    bl      common_abort
8848
8849
8850/* ------------------------------ */
8851    .balign 64
8852.L_OP_UNUSED_2FFF: /* 0x12f */
8853/* File: armv5te/OP_UNUSED_2FFF.S */
8854/* File: armv5te/unused.S */
8855    bl      common_abort
8856
8857
8858/* ------------------------------ */
8859    .balign 64
8860.L_OP_UNUSED_30FF: /* 0x130 */
8861/* File: armv5te/OP_UNUSED_30FF.S */
8862/* File: armv5te/unused.S */
8863    bl      common_abort
8864
8865
8866/* ------------------------------ */
8867    .balign 64
8868.L_OP_UNUSED_31FF: /* 0x131 */
8869/* File: armv5te/OP_UNUSED_31FF.S */
8870/* File: armv5te/unused.S */
8871    bl      common_abort
8872
8873
8874/* ------------------------------ */
8875    .balign 64
8876.L_OP_UNUSED_32FF: /* 0x132 */
8877/* File: armv5te/OP_UNUSED_32FF.S */
8878/* File: armv5te/unused.S */
8879    bl      common_abort
8880
8881
8882/* ------------------------------ */
8883    .balign 64
8884.L_OP_UNUSED_33FF: /* 0x133 */
8885/* File: armv5te/OP_UNUSED_33FF.S */
8886/* File: armv5te/unused.S */
8887    bl      common_abort
8888
8889
8890/* ------------------------------ */
8891    .balign 64
8892.L_OP_UNUSED_34FF: /* 0x134 */
8893/* File: armv5te/OP_UNUSED_34FF.S */
8894/* File: armv5te/unused.S */
8895    bl      common_abort
8896
8897
8898/* ------------------------------ */
8899    .balign 64
8900.L_OP_UNUSED_35FF: /* 0x135 */
8901/* File: armv5te/OP_UNUSED_35FF.S */
8902/* File: armv5te/unused.S */
8903    bl      common_abort
8904
8905
8906/* ------------------------------ */
8907    .balign 64
8908.L_OP_UNUSED_36FF: /* 0x136 */
8909/* File: armv5te/OP_UNUSED_36FF.S */
8910/* File: armv5te/unused.S */
8911    bl      common_abort
8912
8913
8914/* ------------------------------ */
8915    .balign 64
8916.L_OP_UNUSED_37FF: /* 0x137 */
8917/* File: armv5te/OP_UNUSED_37FF.S */
8918/* File: armv5te/unused.S */
8919    bl      common_abort
8920
8921
8922/* ------------------------------ */
8923    .balign 64
8924.L_OP_UNUSED_38FF: /* 0x138 */
8925/* File: armv5te/OP_UNUSED_38FF.S */
8926/* File: armv5te/unused.S */
8927    bl      common_abort
8928
8929
8930/* ------------------------------ */
8931    .balign 64
8932.L_OP_UNUSED_39FF: /* 0x139 */
8933/* File: armv5te/OP_UNUSED_39FF.S */
8934/* File: armv5te/unused.S */
8935    bl      common_abort
8936
8937
8938/* ------------------------------ */
8939    .balign 64
8940.L_OP_UNUSED_3AFF: /* 0x13a */
8941/* File: armv5te/OP_UNUSED_3AFF.S */
8942/* File: armv5te/unused.S */
8943    bl      common_abort
8944
8945
8946/* ------------------------------ */
8947    .balign 64
8948.L_OP_UNUSED_3BFF: /* 0x13b */
8949/* File: armv5te/OP_UNUSED_3BFF.S */
8950/* File: armv5te/unused.S */
8951    bl      common_abort
8952
8953
8954/* ------------------------------ */
8955    .balign 64
8956.L_OP_UNUSED_3CFF: /* 0x13c */
8957/* File: armv5te/OP_UNUSED_3CFF.S */
8958/* File: armv5te/unused.S */
8959    bl      common_abort
8960
8961
8962/* ------------------------------ */
8963    .balign 64
8964.L_OP_UNUSED_3DFF: /* 0x13d */
8965/* File: armv5te/OP_UNUSED_3DFF.S */
8966/* File: armv5te/unused.S */
8967    bl      common_abort
8968
8969
8970/* ------------------------------ */
8971    .balign 64
8972.L_OP_UNUSED_3EFF: /* 0x13e */
8973/* File: armv5te/OP_UNUSED_3EFF.S */
8974/* File: armv5te/unused.S */
8975    bl      common_abort
8976
8977
8978/* ------------------------------ */
8979    .balign 64
8980.L_OP_UNUSED_3FFF: /* 0x13f */
8981/* File: armv5te/OP_UNUSED_3FFF.S */
8982/* File: armv5te/unused.S */
8983    bl      common_abort
8984
8985
8986/* ------------------------------ */
8987    .balign 64
8988.L_OP_UNUSED_40FF: /* 0x140 */
8989/* File: armv5te/OP_UNUSED_40FF.S */
8990/* File: armv5te/unused.S */
8991    bl      common_abort
8992
8993
8994/* ------------------------------ */
8995    .balign 64
8996.L_OP_UNUSED_41FF: /* 0x141 */
8997/* File: armv5te/OP_UNUSED_41FF.S */
8998/* File: armv5te/unused.S */
8999    bl      common_abort
9000
9001
9002/* ------------------------------ */
9003    .balign 64
9004.L_OP_UNUSED_42FF: /* 0x142 */
9005/* File: armv5te/OP_UNUSED_42FF.S */
9006/* File: armv5te/unused.S */
9007    bl      common_abort
9008
9009
9010/* ------------------------------ */
9011    .balign 64
9012.L_OP_UNUSED_43FF: /* 0x143 */
9013/* File: armv5te/OP_UNUSED_43FF.S */
9014/* File: armv5te/unused.S */
9015    bl      common_abort
9016
9017
9018/* ------------------------------ */
9019    .balign 64
9020.L_OP_UNUSED_44FF: /* 0x144 */
9021/* File: armv5te/OP_UNUSED_44FF.S */
9022/* File: armv5te/unused.S */
9023    bl      common_abort
9024
9025
9026/* ------------------------------ */
9027    .balign 64
9028.L_OP_UNUSED_45FF: /* 0x145 */
9029/* File: armv5te/OP_UNUSED_45FF.S */
9030/* File: armv5te/unused.S */
9031    bl      common_abort
9032
9033
9034/* ------------------------------ */
9035    .balign 64
9036.L_OP_UNUSED_46FF: /* 0x146 */
9037/* File: armv5te/OP_UNUSED_46FF.S */
9038/* File: armv5te/unused.S */
9039    bl      common_abort
9040
9041
9042/* ------------------------------ */
9043    .balign 64
9044.L_OP_UNUSED_47FF: /* 0x147 */
9045/* File: armv5te/OP_UNUSED_47FF.S */
9046/* File: armv5te/unused.S */
9047    bl      common_abort
9048
9049
9050/* ------------------------------ */
9051    .balign 64
9052.L_OP_UNUSED_48FF: /* 0x148 */
9053/* File: armv5te/OP_UNUSED_48FF.S */
9054/* File: armv5te/unused.S */
9055    bl      common_abort
9056
9057
9058/* ------------------------------ */
9059    .balign 64
9060.L_OP_UNUSED_49FF: /* 0x149 */
9061/* File: armv5te/OP_UNUSED_49FF.S */
9062/* File: armv5te/unused.S */
9063    bl      common_abort
9064
9065
9066/* ------------------------------ */
9067    .balign 64
9068.L_OP_UNUSED_4AFF: /* 0x14a */
9069/* File: armv5te/OP_UNUSED_4AFF.S */
9070/* File: armv5te/unused.S */
9071    bl      common_abort
9072
9073
9074/* ------------------------------ */
9075    .balign 64
9076.L_OP_UNUSED_4BFF: /* 0x14b */
9077/* File: armv5te/OP_UNUSED_4BFF.S */
9078/* File: armv5te/unused.S */
9079    bl      common_abort
9080
9081
9082/* ------------------------------ */
9083    .balign 64
9084.L_OP_UNUSED_4CFF: /* 0x14c */
9085/* File: armv5te/OP_UNUSED_4CFF.S */
9086/* File: armv5te/unused.S */
9087    bl      common_abort
9088
9089
9090/* ------------------------------ */
9091    .balign 64
9092.L_OP_UNUSED_4DFF: /* 0x14d */
9093/* File: armv5te/OP_UNUSED_4DFF.S */
9094/* File: armv5te/unused.S */
9095    bl      common_abort
9096
9097
9098/* ------------------------------ */
9099    .balign 64
9100.L_OP_UNUSED_4EFF: /* 0x14e */
9101/* File: armv5te/OP_UNUSED_4EFF.S */
9102/* File: armv5te/unused.S */
9103    bl      common_abort
9104
9105
9106/* ------------------------------ */
9107    .balign 64
9108.L_OP_UNUSED_4FFF: /* 0x14f */
9109/* File: armv5te/OP_UNUSED_4FFF.S */
9110/* File: armv5te/unused.S */
9111    bl      common_abort
9112
9113
9114/* ------------------------------ */
9115    .balign 64
9116.L_OP_UNUSED_50FF: /* 0x150 */
9117/* File: armv5te/OP_UNUSED_50FF.S */
9118/* File: armv5te/unused.S */
9119    bl      common_abort
9120
9121
9122/* ------------------------------ */
9123    .balign 64
9124.L_OP_UNUSED_51FF: /* 0x151 */
9125/* File: armv5te/OP_UNUSED_51FF.S */
9126/* File: armv5te/unused.S */
9127    bl      common_abort
9128
9129
9130/* ------------------------------ */
9131    .balign 64
9132.L_OP_UNUSED_52FF: /* 0x152 */
9133/* File: armv5te/OP_UNUSED_52FF.S */
9134/* File: armv5te/unused.S */
9135    bl      common_abort
9136
9137
9138/* ------------------------------ */
9139    .balign 64
9140.L_OP_UNUSED_53FF: /* 0x153 */
9141/* File: armv5te/OP_UNUSED_53FF.S */
9142/* File: armv5te/unused.S */
9143    bl      common_abort
9144
9145
9146/* ------------------------------ */
9147    .balign 64
9148.L_OP_UNUSED_54FF: /* 0x154 */
9149/* File: armv5te/OP_UNUSED_54FF.S */
9150/* File: armv5te/unused.S */
9151    bl      common_abort
9152
9153
9154/* ------------------------------ */
9155    .balign 64
9156.L_OP_UNUSED_55FF: /* 0x155 */
9157/* File: armv5te/OP_UNUSED_55FF.S */
9158/* File: armv5te/unused.S */
9159    bl      common_abort
9160
9161
9162/* ------------------------------ */
9163    .balign 64
9164.L_OP_UNUSED_56FF: /* 0x156 */
9165/* File: armv5te/OP_UNUSED_56FF.S */
9166/* File: armv5te/unused.S */
9167    bl      common_abort
9168
9169
9170/* ------------------------------ */
9171    .balign 64
9172.L_OP_UNUSED_57FF: /* 0x157 */
9173/* File: armv5te/OP_UNUSED_57FF.S */
9174/* File: armv5te/unused.S */
9175    bl      common_abort
9176
9177
9178/* ------------------------------ */
9179    .balign 64
9180.L_OP_UNUSED_58FF: /* 0x158 */
9181/* File: armv5te/OP_UNUSED_58FF.S */
9182/* File: armv5te/unused.S */
9183    bl      common_abort
9184
9185
9186/* ------------------------------ */
9187    .balign 64
9188.L_OP_UNUSED_59FF: /* 0x159 */
9189/* File: armv5te/OP_UNUSED_59FF.S */
9190/* File: armv5te/unused.S */
9191    bl      common_abort
9192
9193
9194/* ------------------------------ */
9195    .balign 64
9196.L_OP_UNUSED_5AFF: /* 0x15a */
9197/* File: armv5te/OP_UNUSED_5AFF.S */
9198/* File: armv5te/unused.S */
9199    bl      common_abort
9200
9201
9202/* ------------------------------ */
9203    .balign 64
9204.L_OP_UNUSED_5BFF: /* 0x15b */
9205/* File: armv5te/OP_UNUSED_5BFF.S */
9206/* File: armv5te/unused.S */
9207    bl      common_abort
9208
9209
9210/* ------------------------------ */
9211    .balign 64
9212.L_OP_UNUSED_5CFF: /* 0x15c */
9213/* File: armv5te/OP_UNUSED_5CFF.S */
9214/* File: armv5te/unused.S */
9215    bl      common_abort
9216
9217
9218/* ------------------------------ */
9219    .balign 64
9220.L_OP_UNUSED_5DFF: /* 0x15d */
9221/* File: armv5te/OP_UNUSED_5DFF.S */
9222/* File: armv5te/unused.S */
9223    bl      common_abort
9224
9225
9226/* ------------------------------ */
9227    .balign 64
9228.L_OP_UNUSED_5EFF: /* 0x15e */
9229/* File: armv5te/OP_UNUSED_5EFF.S */
9230/* File: armv5te/unused.S */
9231    bl      common_abort
9232
9233
9234/* ------------------------------ */
9235    .balign 64
9236.L_OP_UNUSED_5FFF: /* 0x15f */
9237/* File: armv5te/OP_UNUSED_5FFF.S */
9238/* File: armv5te/unused.S */
9239    bl      common_abort
9240
9241
9242/* ------------------------------ */
9243    .balign 64
9244.L_OP_UNUSED_60FF: /* 0x160 */
9245/* File: armv5te/OP_UNUSED_60FF.S */
9246/* File: armv5te/unused.S */
9247    bl      common_abort
9248
9249
9250/* ------------------------------ */
9251    .balign 64
9252.L_OP_UNUSED_61FF: /* 0x161 */
9253/* File: armv5te/OP_UNUSED_61FF.S */
9254/* File: armv5te/unused.S */
9255    bl      common_abort
9256
9257
9258/* ------------------------------ */
9259    .balign 64
9260.L_OP_UNUSED_62FF: /* 0x162 */
9261/* File: armv5te/OP_UNUSED_62FF.S */
9262/* File: armv5te/unused.S */
9263    bl      common_abort
9264
9265
9266/* ------------------------------ */
9267    .balign 64
9268.L_OP_UNUSED_63FF: /* 0x163 */
9269/* File: armv5te/OP_UNUSED_63FF.S */
9270/* File: armv5te/unused.S */
9271    bl      common_abort
9272
9273
9274/* ------------------------------ */
9275    .balign 64
9276.L_OP_UNUSED_64FF: /* 0x164 */
9277/* File: armv5te/OP_UNUSED_64FF.S */
9278/* File: armv5te/unused.S */
9279    bl      common_abort
9280
9281
9282/* ------------------------------ */
9283    .balign 64
9284.L_OP_UNUSED_65FF: /* 0x165 */
9285/* File: armv5te/OP_UNUSED_65FF.S */
9286/* File: armv5te/unused.S */
9287    bl      common_abort
9288
9289
9290/* ------------------------------ */
9291    .balign 64
9292.L_OP_UNUSED_66FF: /* 0x166 */
9293/* File: armv5te/OP_UNUSED_66FF.S */
9294/* File: armv5te/unused.S */
9295    bl      common_abort
9296
9297
9298/* ------------------------------ */
9299    .balign 64
9300.L_OP_UNUSED_67FF: /* 0x167 */
9301/* File: armv5te/OP_UNUSED_67FF.S */
9302/* File: armv5te/unused.S */
9303    bl      common_abort
9304
9305
9306/* ------------------------------ */
9307    .balign 64
9308.L_OP_UNUSED_68FF: /* 0x168 */
9309/* File: armv5te/OP_UNUSED_68FF.S */
9310/* File: armv5te/unused.S */
9311    bl      common_abort
9312
9313
9314/* ------------------------------ */
9315    .balign 64
9316.L_OP_UNUSED_69FF: /* 0x169 */
9317/* File: armv5te/OP_UNUSED_69FF.S */
9318/* File: armv5te/unused.S */
9319    bl      common_abort
9320
9321
9322/* ------------------------------ */
9323    .balign 64
9324.L_OP_UNUSED_6AFF: /* 0x16a */
9325/* File: armv5te/OP_UNUSED_6AFF.S */
9326/* File: armv5te/unused.S */
9327    bl      common_abort
9328
9329
9330/* ------------------------------ */
9331    .balign 64
9332.L_OP_UNUSED_6BFF: /* 0x16b */
9333/* File: armv5te/OP_UNUSED_6BFF.S */
9334/* File: armv5te/unused.S */
9335    bl      common_abort
9336
9337
9338/* ------------------------------ */
9339    .balign 64
9340.L_OP_UNUSED_6CFF: /* 0x16c */
9341/* File: armv5te/OP_UNUSED_6CFF.S */
9342/* File: armv5te/unused.S */
9343    bl      common_abort
9344
9345
9346/* ------------------------------ */
9347    .balign 64
9348.L_OP_UNUSED_6DFF: /* 0x16d */
9349/* File: armv5te/OP_UNUSED_6DFF.S */
9350/* File: armv5te/unused.S */
9351    bl      common_abort
9352
9353
9354/* ------------------------------ */
9355    .balign 64
9356.L_OP_UNUSED_6EFF: /* 0x16e */
9357/* File: armv5te/OP_UNUSED_6EFF.S */
9358/* File: armv5te/unused.S */
9359    bl      common_abort
9360
9361
9362/* ------------------------------ */
9363    .balign 64
9364.L_OP_UNUSED_6FFF: /* 0x16f */
9365/* File: armv5te/OP_UNUSED_6FFF.S */
9366/* File: armv5te/unused.S */
9367    bl      common_abort
9368
9369
9370/* ------------------------------ */
9371    .balign 64
9372.L_OP_UNUSED_70FF: /* 0x170 */
9373/* File: armv5te/OP_UNUSED_70FF.S */
9374/* File: armv5te/unused.S */
9375    bl      common_abort
9376
9377
9378/* ------------------------------ */
9379    .balign 64
9380.L_OP_UNUSED_71FF: /* 0x171 */
9381/* File: armv5te/OP_UNUSED_71FF.S */
9382/* File: armv5te/unused.S */
9383    bl      common_abort
9384
9385
9386/* ------------------------------ */
9387    .balign 64
9388.L_OP_UNUSED_72FF: /* 0x172 */
9389/* File: armv5te/OP_UNUSED_72FF.S */
9390/* File: armv5te/unused.S */
9391    bl      common_abort
9392
9393
9394/* ------------------------------ */
9395    .balign 64
9396.L_OP_UNUSED_73FF: /* 0x173 */
9397/* File: armv5te/OP_UNUSED_73FF.S */
9398/* File: armv5te/unused.S */
9399    bl      common_abort
9400
9401
9402/* ------------------------------ */
9403    .balign 64
9404.L_OP_UNUSED_74FF: /* 0x174 */
9405/* File: armv5te/OP_UNUSED_74FF.S */
9406/* File: armv5te/unused.S */
9407    bl      common_abort
9408
9409
9410/* ------------------------------ */
9411    .balign 64
9412.L_OP_UNUSED_75FF: /* 0x175 */
9413/* File: armv5te/OP_UNUSED_75FF.S */
9414/* File: armv5te/unused.S */
9415    bl      common_abort
9416
9417
9418/* ------------------------------ */
9419    .balign 64
9420.L_OP_UNUSED_76FF: /* 0x176 */
9421/* File: armv5te/OP_UNUSED_76FF.S */
9422/* File: armv5te/unused.S */
9423    bl      common_abort
9424
9425
9426/* ------------------------------ */
9427    .balign 64
9428.L_OP_UNUSED_77FF: /* 0x177 */
9429/* File: armv5te/OP_UNUSED_77FF.S */
9430/* File: armv5te/unused.S */
9431    bl      common_abort
9432
9433
9434/* ------------------------------ */
9435    .balign 64
9436.L_OP_UNUSED_78FF: /* 0x178 */
9437/* File: armv5te/OP_UNUSED_78FF.S */
9438/* File: armv5te/unused.S */
9439    bl      common_abort
9440
9441
9442/* ------------------------------ */
9443    .balign 64
9444.L_OP_UNUSED_79FF: /* 0x179 */
9445/* File: armv5te/OP_UNUSED_79FF.S */
9446/* File: armv5te/unused.S */
9447    bl      common_abort
9448
9449
9450/* ------------------------------ */
9451    .balign 64
9452.L_OP_UNUSED_7AFF: /* 0x17a */
9453/* File: armv5te/OP_UNUSED_7AFF.S */
9454/* File: armv5te/unused.S */
9455    bl      common_abort
9456
9457
9458/* ------------------------------ */
9459    .balign 64
9460.L_OP_UNUSED_7BFF: /* 0x17b */
9461/* File: armv5te/OP_UNUSED_7BFF.S */
9462/* File: armv5te/unused.S */
9463    bl      common_abort
9464
9465
9466/* ------------------------------ */
9467    .balign 64
9468.L_OP_UNUSED_7CFF: /* 0x17c */
9469/* File: armv5te/OP_UNUSED_7CFF.S */
9470/* File: armv5te/unused.S */
9471    bl      common_abort
9472
9473
9474/* ------------------------------ */
9475    .balign 64
9476.L_OP_UNUSED_7DFF: /* 0x17d */
9477/* File: armv5te/OP_UNUSED_7DFF.S */
9478/* File: armv5te/unused.S */
9479    bl      common_abort
9480
9481
9482/* ------------------------------ */
9483    .balign 64
9484.L_OP_UNUSED_7EFF: /* 0x17e */
9485/* File: armv5te/OP_UNUSED_7EFF.S */
9486/* File: armv5te/unused.S */
9487    bl      common_abort
9488
9489
9490/* ------------------------------ */
9491    .balign 64
9492.L_OP_UNUSED_7FFF: /* 0x17f */
9493/* File: armv5te/OP_UNUSED_7FFF.S */
9494/* File: armv5te/unused.S */
9495    bl      common_abort
9496
9497
9498/* ------------------------------ */
9499    .balign 64
9500.L_OP_UNUSED_80FF: /* 0x180 */
9501/* File: armv5te/OP_UNUSED_80FF.S */
9502/* File: armv5te/unused.S */
9503    bl      common_abort
9504
9505
9506/* ------------------------------ */
9507    .balign 64
9508.L_OP_UNUSED_81FF: /* 0x181 */
9509/* File: armv5te/OP_UNUSED_81FF.S */
9510/* File: armv5te/unused.S */
9511    bl      common_abort
9512
9513
9514/* ------------------------------ */
9515    .balign 64
9516.L_OP_UNUSED_82FF: /* 0x182 */
9517/* File: armv5te/OP_UNUSED_82FF.S */
9518/* File: armv5te/unused.S */
9519    bl      common_abort
9520
9521
9522/* ------------------------------ */
9523    .balign 64
9524.L_OP_UNUSED_83FF: /* 0x183 */
9525/* File: armv5te/OP_UNUSED_83FF.S */
9526/* File: armv5te/unused.S */
9527    bl      common_abort
9528
9529
9530/* ------------------------------ */
9531    .balign 64
9532.L_OP_UNUSED_84FF: /* 0x184 */
9533/* File: armv5te/OP_UNUSED_84FF.S */
9534/* File: armv5te/unused.S */
9535    bl      common_abort
9536
9537
9538/* ------------------------------ */
9539    .balign 64
9540.L_OP_UNUSED_85FF: /* 0x185 */
9541/* File: armv5te/OP_UNUSED_85FF.S */
9542/* File: armv5te/unused.S */
9543    bl      common_abort
9544
9545
9546/* ------------------------------ */
9547    .balign 64
9548.L_OP_UNUSED_86FF: /* 0x186 */
9549/* File: armv5te/OP_UNUSED_86FF.S */
9550/* File: armv5te/unused.S */
9551    bl      common_abort
9552
9553
9554/* ------------------------------ */
9555    .balign 64
9556.L_OP_UNUSED_87FF: /* 0x187 */
9557/* File: armv5te/OP_UNUSED_87FF.S */
9558/* File: armv5te/unused.S */
9559    bl      common_abort
9560
9561
9562/* ------------------------------ */
9563    .balign 64
9564.L_OP_UNUSED_88FF: /* 0x188 */
9565/* File: armv5te/OP_UNUSED_88FF.S */
9566/* File: armv5te/unused.S */
9567    bl      common_abort
9568
9569
9570/* ------------------------------ */
9571    .balign 64
9572.L_OP_UNUSED_89FF: /* 0x189 */
9573/* File: armv5te/OP_UNUSED_89FF.S */
9574/* File: armv5te/unused.S */
9575    bl      common_abort
9576
9577
9578/* ------------------------------ */
9579    .balign 64
9580.L_OP_UNUSED_8AFF: /* 0x18a */
9581/* File: armv5te/OP_UNUSED_8AFF.S */
9582/* File: armv5te/unused.S */
9583    bl      common_abort
9584
9585
9586/* ------------------------------ */
9587    .balign 64
9588.L_OP_UNUSED_8BFF: /* 0x18b */
9589/* File: armv5te/OP_UNUSED_8BFF.S */
9590/* File: armv5te/unused.S */
9591    bl      common_abort
9592
9593
9594/* ------------------------------ */
9595    .balign 64
9596.L_OP_UNUSED_8CFF: /* 0x18c */
9597/* File: armv5te/OP_UNUSED_8CFF.S */
9598/* File: armv5te/unused.S */
9599    bl      common_abort
9600
9601
9602/* ------------------------------ */
9603    .balign 64
9604.L_OP_UNUSED_8DFF: /* 0x18d */
9605/* File: armv5te/OP_UNUSED_8DFF.S */
9606/* File: armv5te/unused.S */
9607    bl      common_abort
9608
9609
9610/* ------------------------------ */
9611    .balign 64
9612.L_OP_UNUSED_8EFF: /* 0x18e */
9613/* File: armv5te/OP_UNUSED_8EFF.S */
9614/* File: armv5te/unused.S */
9615    bl      common_abort
9616
9617
9618/* ------------------------------ */
9619    .balign 64
9620.L_OP_UNUSED_8FFF: /* 0x18f */
9621/* File: armv5te/OP_UNUSED_8FFF.S */
9622/* File: armv5te/unused.S */
9623    bl      common_abort
9624
9625
9626/* ------------------------------ */
9627    .balign 64
9628.L_OP_UNUSED_90FF: /* 0x190 */
9629/* File: armv5te/OP_UNUSED_90FF.S */
9630/* File: armv5te/unused.S */
9631    bl      common_abort
9632
9633
9634/* ------------------------------ */
9635    .balign 64
9636.L_OP_UNUSED_91FF: /* 0x191 */
9637/* File: armv5te/OP_UNUSED_91FF.S */
9638/* File: armv5te/unused.S */
9639    bl      common_abort
9640
9641
9642/* ------------------------------ */
9643    .balign 64
9644.L_OP_UNUSED_92FF: /* 0x192 */
9645/* File: armv5te/OP_UNUSED_92FF.S */
9646/* File: armv5te/unused.S */
9647    bl      common_abort
9648
9649
9650/* ------------------------------ */
9651    .balign 64
9652.L_OP_UNUSED_93FF: /* 0x193 */
9653/* File: armv5te/OP_UNUSED_93FF.S */
9654/* File: armv5te/unused.S */
9655    bl      common_abort
9656
9657
9658/* ------------------------------ */
9659    .balign 64
9660.L_OP_UNUSED_94FF: /* 0x194 */
9661/* File: armv5te/OP_UNUSED_94FF.S */
9662/* File: armv5te/unused.S */
9663    bl      common_abort
9664
9665
9666/* ------------------------------ */
9667    .balign 64
9668.L_OP_UNUSED_95FF: /* 0x195 */
9669/* File: armv5te/OP_UNUSED_95FF.S */
9670/* File: armv5te/unused.S */
9671    bl      common_abort
9672
9673
9674/* ------------------------------ */
9675    .balign 64
9676.L_OP_UNUSED_96FF: /* 0x196 */
9677/* File: armv5te/OP_UNUSED_96FF.S */
9678/* File: armv5te/unused.S */
9679    bl      common_abort
9680
9681
9682/* ------------------------------ */
9683    .balign 64
9684.L_OP_UNUSED_97FF: /* 0x197 */
9685/* File: armv5te/OP_UNUSED_97FF.S */
9686/* File: armv5te/unused.S */
9687    bl      common_abort
9688
9689
9690/* ------------------------------ */
9691    .balign 64
9692.L_OP_UNUSED_98FF: /* 0x198 */
9693/* File: armv5te/OP_UNUSED_98FF.S */
9694/* File: armv5te/unused.S */
9695    bl      common_abort
9696
9697
9698/* ------------------------------ */
9699    .balign 64
9700.L_OP_UNUSED_99FF: /* 0x199 */
9701/* File: armv5te/OP_UNUSED_99FF.S */
9702/* File: armv5te/unused.S */
9703    bl      common_abort
9704
9705
9706/* ------------------------------ */
9707    .balign 64
9708.L_OP_UNUSED_9AFF: /* 0x19a */
9709/* File: armv5te/OP_UNUSED_9AFF.S */
9710/* File: armv5te/unused.S */
9711    bl      common_abort
9712
9713
9714/* ------------------------------ */
9715    .balign 64
9716.L_OP_UNUSED_9BFF: /* 0x19b */
9717/* File: armv5te/OP_UNUSED_9BFF.S */
9718/* File: armv5te/unused.S */
9719    bl      common_abort
9720
9721
9722/* ------------------------------ */
9723    .balign 64
9724.L_OP_UNUSED_9CFF: /* 0x19c */
9725/* File: armv5te/OP_UNUSED_9CFF.S */
9726/* File: armv5te/unused.S */
9727    bl      common_abort
9728
9729
9730/* ------------------------------ */
9731    .balign 64
9732.L_OP_UNUSED_9DFF: /* 0x19d */
9733/* File: armv5te/OP_UNUSED_9DFF.S */
9734/* File: armv5te/unused.S */
9735    bl      common_abort
9736
9737
9738/* ------------------------------ */
9739    .balign 64
9740.L_OP_UNUSED_9EFF: /* 0x19e */
9741/* File: armv5te/OP_UNUSED_9EFF.S */
9742/* File: armv5te/unused.S */
9743    bl      common_abort
9744
9745
9746/* ------------------------------ */
9747    .balign 64
9748.L_OP_UNUSED_9FFF: /* 0x19f */
9749/* File: armv5te/OP_UNUSED_9FFF.S */
9750/* File: armv5te/unused.S */
9751    bl      common_abort
9752
9753
9754/* ------------------------------ */
9755    .balign 64
9756.L_OP_UNUSED_A0FF: /* 0x1a0 */
9757/* File: armv5te/OP_UNUSED_A0FF.S */
9758/* File: armv5te/unused.S */
9759    bl      common_abort
9760
9761
9762/* ------------------------------ */
9763    .balign 64
9764.L_OP_UNUSED_A1FF: /* 0x1a1 */
9765/* File: armv5te/OP_UNUSED_A1FF.S */
9766/* File: armv5te/unused.S */
9767    bl      common_abort
9768
9769
9770/* ------------------------------ */
9771    .balign 64
9772.L_OP_UNUSED_A2FF: /* 0x1a2 */
9773/* File: armv5te/OP_UNUSED_A2FF.S */
9774/* File: armv5te/unused.S */
9775    bl      common_abort
9776
9777
9778/* ------------------------------ */
9779    .balign 64
9780.L_OP_UNUSED_A3FF: /* 0x1a3 */
9781/* File: armv5te/OP_UNUSED_A3FF.S */
9782/* File: armv5te/unused.S */
9783    bl      common_abort
9784
9785
9786/* ------------------------------ */
9787    .balign 64
9788.L_OP_UNUSED_A4FF: /* 0x1a4 */
9789/* File: armv5te/OP_UNUSED_A4FF.S */
9790/* File: armv5te/unused.S */
9791    bl      common_abort
9792
9793
9794/* ------------------------------ */
9795    .balign 64
9796.L_OP_UNUSED_A5FF: /* 0x1a5 */
9797/* File: armv5te/OP_UNUSED_A5FF.S */
9798/* File: armv5te/unused.S */
9799    bl      common_abort
9800
9801
9802/* ------------------------------ */
9803    .balign 64
9804.L_OP_UNUSED_A6FF: /* 0x1a6 */
9805/* File: armv5te/OP_UNUSED_A6FF.S */
9806/* File: armv5te/unused.S */
9807    bl      common_abort
9808
9809
9810/* ------------------------------ */
9811    .balign 64
9812.L_OP_UNUSED_A7FF: /* 0x1a7 */
9813/* File: armv5te/OP_UNUSED_A7FF.S */
9814/* File: armv5te/unused.S */
9815    bl      common_abort
9816
9817
9818/* ------------------------------ */
9819    .balign 64
9820.L_OP_UNUSED_A8FF: /* 0x1a8 */
9821/* File: armv5te/OP_UNUSED_A8FF.S */
9822/* File: armv5te/unused.S */
9823    bl      common_abort
9824
9825
9826/* ------------------------------ */
9827    .balign 64
9828.L_OP_UNUSED_A9FF: /* 0x1a9 */
9829/* File: armv5te/OP_UNUSED_A9FF.S */
9830/* File: armv5te/unused.S */
9831    bl      common_abort
9832
9833
9834/* ------------------------------ */
9835    .balign 64
9836.L_OP_UNUSED_AAFF: /* 0x1aa */
9837/* File: armv5te/OP_UNUSED_AAFF.S */
9838/* File: armv5te/unused.S */
9839    bl      common_abort
9840
9841
9842/* ------------------------------ */
9843    .balign 64
9844.L_OP_UNUSED_ABFF: /* 0x1ab */
9845/* File: armv5te/OP_UNUSED_ABFF.S */
9846/* File: armv5te/unused.S */
9847    bl      common_abort
9848
9849
9850/* ------------------------------ */
9851    .balign 64
9852.L_OP_UNUSED_ACFF: /* 0x1ac */
9853/* File: armv5te/OP_UNUSED_ACFF.S */
9854/* File: armv5te/unused.S */
9855    bl      common_abort
9856
9857
9858/* ------------------------------ */
9859    .balign 64
9860.L_OP_UNUSED_ADFF: /* 0x1ad */
9861/* File: armv5te/OP_UNUSED_ADFF.S */
9862/* File: armv5te/unused.S */
9863    bl      common_abort
9864
9865
9866/* ------------------------------ */
9867    .balign 64
9868.L_OP_UNUSED_AEFF: /* 0x1ae */
9869/* File: armv5te/OP_UNUSED_AEFF.S */
9870/* File: armv5te/unused.S */
9871    bl      common_abort
9872
9873
9874/* ------------------------------ */
9875    .balign 64
9876.L_OP_UNUSED_AFFF: /* 0x1af */
9877/* File: armv5te/OP_UNUSED_AFFF.S */
9878/* File: armv5te/unused.S */
9879    bl      common_abort
9880
9881
9882/* ------------------------------ */
9883    .balign 64
9884.L_OP_UNUSED_B0FF: /* 0x1b0 */
9885/* File: armv5te/OP_UNUSED_B0FF.S */
9886/* File: armv5te/unused.S */
9887    bl      common_abort
9888
9889
9890/* ------------------------------ */
9891    .balign 64
9892.L_OP_UNUSED_B1FF: /* 0x1b1 */
9893/* File: armv5te/OP_UNUSED_B1FF.S */
9894/* File: armv5te/unused.S */
9895    bl      common_abort
9896
9897
9898/* ------------------------------ */
9899    .balign 64
9900.L_OP_UNUSED_B2FF: /* 0x1b2 */
9901/* File: armv5te/OP_UNUSED_B2FF.S */
9902/* File: armv5te/unused.S */
9903    bl      common_abort
9904
9905
9906/* ------------------------------ */
9907    .balign 64
9908.L_OP_UNUSED_B3FF: /* 0x1b3 */
9909/* File: armv5te/OP_UNUSED_B3FF.S */
9910/* File: armv5te/unused.S */
9911    bl      common_abort
9912
9913
9914/* ------------------------------ */
9915    .balign 64
9916.L_OP_UNUSED_B4FF: /* 0x1b4 */
9917/* File: armv5te/OP_UNUSED_B4FF.S */
9918/* File: armv5te/unused.S */
9919    bl      common_abort
9920
9921
9922/* ------------------------------ */
9923    .balign 64
9924.L_OP_UNUSED_B5FF: /* 0x1b5 */
9925/* File: armv5te/OP_UNUSED_B5FF.S */
9926/* File: armv5te/unused.S */
9927    bl      common_abort
9928
9929
9930/* ------------------------------ */
9931    .balign 64
9932.L_OP_UNUSED_B6FF: /* 0x1b6 */
9933/* File: armv5te/OP_UNUSED_B6FF.S */
9934/* File: armv5te/unused.S */
9935    bl      common_abort
9936
9937
9938/* ------------------------------ */
9939    .balign 64
9940.L_OP_UNUSED_B7FF: /* 0x1b7 */
9941/* File: armv5te/OP_UNUSED_B7FF.S */
9942/* File: armv5te/unused.S */
9943    bl      common_abort
9944
9945
9946/* ------------------------------ */
9947    .balign 64
9948.L_OP_UNUSED_B8FF: /* 0x1b8 */
9949/* File: armv5te/OP_UNUSED_B8FF.S */
9950/* File: armv5te/unused.S */
9951    bl      common_abort
9952
9953
9954/* ------------------------------ */
9955    .balign 64
9956.L_OP_UNUSED_B9FF: /* 0x1b9 */
9957/* File: armv5te/OP_UNUSED_B9FF.S */
9958/* File: armv5te/unused.S */
9959    bl      common_abort
9960
9961
9962/* ------------------------------ */
9963    .balign 64
9964.L_OP_UNUSED_BAFF: /* 0x1ba */
9965/* File: armv5te/OP_UNUSED_BAFF.S */
9966/* File: armv5te/unused.S */
9967    bl      common_abort
9968
9969
9970/* ------------------------------ */
9971    .balign 64
9972.L_OP_UNUSED_BBFF: /* 0x1bb */
9973/* File: armv5te/OP_UNUSED_BBFF.S */
9974/* File: armv5te/unused.S */
9975    bl      common_abort
9976
9977
9978/* ------------------------------ */
9979    .balign 64
9980.L_OP_UNUSED_BCFF: /* 0x1bc */
9981/* File: armv5te/OP_UNUSED_BCFF.S */
9982/* File: armv5te/unused.S */
9983    bl      common_abort
9984
9985
9986/* ------------------------------ */
9987    .balign 64
9988.L_OP_UNUSED_BDFF: /* 0x1bd */
9989/* File: armv5te/OP_UNUSED_BDFF.S */
9990/* File: armv5te/unused.S */
9991    bl      common_abort
9992
9993
9994/* ------------------------------ */
9995    .balign 64
9996.L_OP_UNUSED_BEFF: /* 0x1be */
9997/* File: armv5te/OP_UNUSED_BEFF.S */
9998/* File: armv5te/unused.S */
9999    bl      common_abort
10000
10001
10002/* ------------------------------ */
10003    .balign 64
10004.L_OP_UNUSED_BFFF: /* 0x1bf */
10005/* File: armv5te/OP_UNUSED_BFFF.S */
10006/* File: armv5te/unused.S */
10007    bl      common_abort
10008
10009
10010/* ------------------------------ */
10011    .balign 64
10012.L_OP_UNUSED_C0FF: /* 0x1c0 */
10013/* File: armv5te/OP_UNUSED_C0FF.S */
10014/* File: armv5te/unused.S */
10015    bl      common_abort
10016
10017
10018/* ------------------------------ */
10019    .balign 64
10020.L_OP_UNUSED_C1FF: /* 0x1c1 */
10021/* File: armv5te/OP_UNUSED_C1FF.S */
10022/* File: armv5te/unused.S */
10023    bl      common_abort
10024
10025
10026/* ------------------------------ */
10027    .balign 64
10028.L_OP_UNUSED_C2FF: /* 0x1c2 */
10029/* File: armv5te/OP_UNUSED_C2FF.S */
10030/* File: armv5te/unused.S */
10031    bl      common_abort
10032
10033
10034/* ------------------------------ */
10035    .balign 64
10036.L_OP_UNUSED_C3FF: /* 0x1c3 */
10037/* File: armv5te/OP_UNUSED_C3FF.S */
10038/* File: armv5te/unused.S */
10039    bl      common_abort
10040
10041
10042/* ------------------------------ */
10043    .balign 64
10044.L_OP_UNUSED_C4FF: /* 0x1c4 */
10045/* File: armv5te/OP_UNUSED_C4FF.S */
10046/* File: armv5te/unused.S */
10047    bl      common_abort
10048
10049
10050/* ------------------------------ */
10051    .balign 64
10052.L_OP_UNUSED_C5FF: /* 0x1c5 */
10053/* File: armv5te/OP_UNUSED_C5FF.S */
10054/* File: armv5te/unused.S */
10055    bl      common_abort
10056
10057
10058/* ------------------------------ */
10059    .balign 64
10060.L_OP_UNUSED_C6FF: /* 0x1c6 */
10061/* File: armv5te/OP_UNUSED_C6FF.S */
10062/* File: armv5te/unused.S */
10063    bl      common_abort
10064
10065
10066/* ------------------------------ */
10067    .balign 64
10068.L_OP_UNUSED_C7FF: /* 0x1c7 */
10069/* File: armv5te/OP_UNUSED_C7FF.S */
10070/* File: armv5te/unused.S */
10071    bl      common_abort
10072
10073
10074/* ------------------------------ */
10075    .balign 64
10076.L_OP_UNUSED_C8FF: /* 0x1c8 */
10077/* File: armv5te/OP_UNUSED_C8FF.S */
10078/* File: armv5te/unused.S */
10079    bl      common_abort
10080
10081
10082/* ------------------------------ */
10083    .balign 64
10084.L_OP_UNUSED_C9FF: /* 0x1c9 */
10085/* File: armv5te/OP_UNUSED_C9FF.S */
10086/* File: armv5te/unused.S */
10087    bl      common_abort
10088
10089
10090/* ------------------------------ */
10091    .balign 64
10092.L_OP_UNUSED_CAFF: /* 0x1ca */
10093/* File: armv5te/OP_UNUSED_CAFF.S */
10094/* File: armv5te/unused.S */
10095    bl      common_abort
10096
10097
10098/* ------------------------------ */
10099    .balign 64
10100.L_OP_UNUSED_CBFF: /* 0x1cb */
10101/* File: armv5te/OP_UNUSED_CBFF.S */
10102/* File: armv5te/unused.S */
10103    bl      common_abort
10104
10105
10106/* ------------------------------ */
10107    .balign 64
10108.L_OP_UNUSED_CCFF: /* 0x1cc */
10109/* File: armv5te/OP_UNUSED_CCFF.S */
10110/* File: armv5te/unused.S */
10111    bl      common_abort
10112
10113
10114/* ------------------------------ */
10115    .balign 64
10116.L_OP_UNUSED_CDFF: /* 0x1cd */
10117/* File: armv5te/OP_UNUSED_CDFF.S */
10118/* File: armv5te/unused.S */
10119    bl      common_abort
10120
10121
10122/* ------------------------------ */
10123    .balign 64
10124.L_OP_UNUSED_CEFF: /* 0x1ce */
10125/* File: armv5te/OP_UNUSED_CEFF.S */
10126/* File: armv5te/unused.S */
10127    bl      common_abort
10128
10129
10130/* ------------------------------ */
10131    .balign 64
10132.L_OP_UNUSED_CFFF: /* 0x1cf */
10133/* File: armv5te/OP_UNUSED_CFFF.S */
10134/* File: armv5te/unused.S */
10135    bl      common_abort
10136
10137
10138/* ------------------------------ */
10139    .balign 64
10140.L_OP_UNUSED_D0FF: /* 0x1d0 */
10141/* File: armv5te/OP_UNUSED_D0FF.S */
10142/* File: armv5te/unused.S */
10143    bl      common_abort
10144
10145
10146/* ------------------------------ */
10147    .balign 64
10148.L_OP_UNUSED_D1FF: /* 0x1d1 */
10149/* File: armv5te/OP_UNUSED_D1FF.S */
10150/* File: armv5te/unused.S */
10151    bl      common_abort
10152
10153
10154/* ------------------------------ */
10155    .balign 64
10156.L_OP_UNUSED_D2FF: /* 0x1d2 */
10157/* File: armv5te/OP_UNUSED_D2FF.S */
10158/* File: armv5te/unused.S */
10159    bl      common_abort
10160
10161
10162/* ------------------------------ */
10163    .balign 64
10164.L_OP_UNUSED_D3FF: /* 0x1d3 */
10165/* File: armv5te/OP_UNUSED_D3FF.S */
10166/* File: armv5te/unused.S */
10167    bl      common_abort
10168
10169
10170/* ------------------------------ */
10171    .balign 64
10172.L_OP_UNUSED_D4FF: /* 0x1d4 */
10173/* File: armv5te/OP_UNUSED_D4FF.S */
10174/* File: armv5te/unused.S */
10175    bl      common_abort
10176
10177
10178/* ------------------------------ */
10179    .balign 64
10180.L_OP_UNUSED_D5FF: /* 0x1d5 */
10181/* File: armv5te/OP_UNUSED_D5FF.S */
10182/* File: armv5te/unused.S */
10183    bl      common_abort
10184
10185
10186/* ------------------------------ */
10187    .balign 64
10188.L_OP_UNUSED_D6FF: /* 0x1d6 */
10189/* File: armv5te/OP_UNUSED_D6FF.S */
10190/* File: armv5te/unused.S */
10191    bl      common_abort
10192
10193
10194/* ------------------------------ */
10195    .balign 64
10196.L_OP_UNUSED_D7FF: /* 0x1d7 */
10197/* File: armv5te/OP_UNUSED_D7FF.S */
10198/* File: armv5te/unused.S */
10199    bl      common_abort
10200
10201
10202/* ------------------------------ */
10203    .balign 64
10204.L_OP_UNUSED_D8FF: /* 0x1d8 */
10205/* File: armv5te/OP_UNUSED_D8FF.S */
10206/* File: armv5te/unused.S */
10207    bl      common_abort
10208
10209
10210/* ------------------------------ */
10211    .balign 64
10212.L_OP_UNUSED_D9FF: /* 0x1d9 */
10213/* File: armv5te/OP_UNUSED_D9FF.S */
10214/* File: armv5te/unused.S */
10215    bl      common_abort
10216
10217
10218/* ------------------------------ */
10219    .balign 64
10220.L_OP_UNUSED_DAFF: /* 0x1da */
10221/* File: armv5te/OP_UNUSED_DAFF.S */
10222/* File: armv5te/unused.S */
10223    bl      common_abort
10224
10225
10226/* ------------------------------ */
10227    .balign 64
10228.L_OP_UNUSED_DBFF: /* 0x1db */
10229/* File: armv5te/OP_UNUSED_DBFF.S */
10230/* File: armv5te/unused.S */
10231    bl      common_abort
10232
10233
10234/* ------------------------------ */
10235    .balign 64
10236.L_OP_UNUSED_DCFF: /* 0x1dc */
10237/* File: armv5te/OP_UNUSED_DCFF.S */
10238/* File: armv5te/unused.S */
10239    bl      common_abort
10240
10241
10242/* ------------------------------ */
10243    .balign 64
10244.L_OP_UNUSED_DDFF: /* 0x1dd */
10245/* File: armv5te/OP_UNUSED_DDFF.S */
10246/* File: armv5te/unused.S */
10247    bl      common_abort
10248
10249
10250/* ------------------------------ */
10251    .balign 64
10252.L_OP_UNUSED_DEFF: /* 0x1de */
10253/* File: armv5te/OP_UNUSED_DEFF.S */
10254/* File: armv5te/unused.S */
10255    bl      common_abort
10256
10257
10258/* ------------------------------ */
10259    .balign 64
10260.L_OP_UNUSED_DFFF: /* 0x1df */
10261/* File: armv5te/OP_UNUSED_DFFF.S */
10262/* File: armv5te/unused.S */
10263    bl      common_abort
10264
10265
10266/* ------------------------------ */
10267    .balign 64
10268.L_OP_UNUSED_E0FF: /* 0x1e0 */
10269/* File: armv5te/OP_UNUSED_E0FF.S */
10270/* File: armv5te/unused.S */
10271    bl      common_abort
10272
10273
10274/* ------------------------------ */
10275    .balign 64
10276.L_OP_UNUSED_E1FF: /* 0x1e1 */
10277/* File: armv5te/OP_UNUSED_E1FF.S */
10278/* File: armv5te/unused.S */
10279    bl      common_abort
10280
10281
10282/* ------------------------------ */
10283    .balign 64
10284.L_OP_UNUSED_E2FF: /* 0x1e2 */
10285/* File: armv5te/OP_UNUSED_E2FF.S */
10286/* File: armv5te/unused.S */
10287    bl      common_abort
10288
10289
10290/* ------------------------------ */
10291    .balign 64
10292.L_OP_UNUSED_E3FF: /* 0x1e3 */
10293/* File: armv5te/OP_UNUSED_E3FF.S */
10294/* File: armv5te/unused.S */
10295    bl      common_abort
10296
10297
10298/* ------------------------------ */
10299    .balign 64
10300.L_OP_UNUSED_E4FF: /* 0x1e4 */
10301/* File: armv5te/OP_UNUSED_E4FF.S */
10302/* File: armv5te/unused.S */
10303    bl      common_abort
10304
10305
10306/* ------------------------------ */
10307    .balign 64
10308.L_OP_UNUSED_E5FF: /* 0x1e5 */
10309/* File: armv5te/OP_UNUSED_E5FF.S */
10310/* File: armv5te/unused.S */
10311    bl      common_abort
10312
10313
10314/* ------------------------------ */
10315    .balign 64
10316.L_OP_UNUSED_E6FF: /* 0x1e6 */
10317/* File: armv5te/OP_UNUSED_E6FF.S */
10318/* File: armv5te/unused.S */
10319    bl      common_abort
10320
10321
10322/* ------------------------------ */
10323    .balign 64
10324.L_OP_UNUSED_E7FF: /* 0x1e7 */
10325/* File: armv5te/OP_UNUSED_E7FF.S */
10326/* File: armv5te/unused.S */
10327    bl      common_abort
10328
10329
10330/* ------------------------------ */
10331    .balign 64
10332.L_OP_UNUSED_E8FF: /* 0x1e8 */
10333/* File: armv5te/OP_UNUSED_E8FF.S */
10334/* File: armv5te/unused.S */
10335    bl      common_abort
10336
10337
10338/* ------------------------------ */
10339    .balign 64
10340.L_OP_UNUSED_E9FF: /* 0x1e9 */
10341/* File: armv5te/OP_UNUSED_E9FF.S */
10342/* File: armv5te/unused.S */
10343    bl      common_abort
10344
10345
10346/* ------------------------------ */
10347    .balign 64
10348.L_OP_UNUSED_EAFF: /* 0x1ea */
10349/* File: armv5te/OP_UNUSED_EAFF.S */
10350/* File: armv5te/unused.S */
10351    bl      common_abort
10352
10353
10354/* ------------------------------ */
10355    .balign 64
10356.L_OP_UNUSED_EBFF: /* 0x1eb */
10357/* File: armv5te/OP_UNUSED_EBFF.S */
10358/* File: armv5te/unused.S */
10359    bl      common_abort
10360
10361
10362/* ------------------------------ */
10363    .balign 64
10364.L_OP_UNUSED_ECFF: /* 0x1ec */
10365/* File: armv5te/OP_UNUSED_ECFF.S */
10366/* File: armv5te/unused.S */
10367    bl      common_abort
10368
10369
10370/* ------------------------------ */
10371    .balign 64
10372.L_OP_UNUSED_EDFF: /* 0x1ed */
10373/* File: armv5te/OP_UNUSED_EDFF.S */
10374/* File: armv5te/unused.S */
10375    bl      common_abort
10376
10377
10378/* ------------------------------ */
10379    .balign 64
10380.L_OP_UNUSED_EEFF: /* 0x1ee */
10381/* File: armv5te/OP_UNUSED_EEFF.S */
10382/* File: armv5te/unused.S */
10383    bl      common_abort
10384
10385
10386/* ------------------------------ */
10387    .balign 64
10388.L_OP_UNUSED_EFFF: /* 0x1ef */
10389/* File: armv5te/OP_UNUSED_EFFF.S */
10390/* File: armv5te/unused.S */
10391    bl      common_abort
10392
10393
10394/* ------------------------------ */
10395    .balign 64
10396.L_OP_UNUSED_F0FF: /* 0x1f0 */
10397/* File: armv5te/OP_UNUSED_F0FF.S */
10398/* File: armv5te/unused.S */
10399    bl      common_abort
10400
10401
10402/* ------------------------------ */
10403    .balign 64
10404.L_OP_UNUSED_F1FF: /* 0x1f1 */
10405/* File: armv5te/OP_UNUSED_F1FF.S */
10406/* File: armv5te/unused.S */
10407    bl      common_abort
10408
10409
10410/* ------------------------------ */
10411    .balign 64
10412.L_OP_UNUSED_F2FF: /* 0x1f2 */
10413/* File: armv5te/OP_UNUSED_F2FF.S */
10414/* File: armv5te/unused.S */
10415    bl      common_abort
10416
10417
10418/* ------------------------------ */
10419    .balign 64
10420.L_OP_UNUSED_F3FF: /* 0x1f3 */
10421/* File: armv5te/OP_UNUSED_F3FF.S */
10422/* File: armv5te/unused.S */
10423    bl      common_abort
10424
10425
10426/* ------------------------------ */
10427    .balign 64
10428.L_OP_UNUSED_F4FF: /* 0x1f4 */
10429/* File: armv5te/OP_UNUSED_F4FF.S */
10430/* File: armv5te/unused.S */
10431    bl      common_abort
10432
10433
10434/* ------------------------------ */
10435    .balign 64
10436.L_OP_UNUSED_F5FF: /* 0x1f5 */
10437/* File: armv5te/OP_UNUSED_F5FF.S */
10438/* File: armv5te/unused.S */
10439    bl      common_abort
10440
10441
10442/* ------------------------------ */
10443    .balign 64
10444.L_OP_UNUSED_F6FF: /* 0x1f6 */
10445/* File: armv5te/OP_UNUSED_F6FF.S */
10446/* File: armv5te/unused.S */
10447    bl      common_abort
10448
10449
10450/* ------------------------------ */
10451    .balign 64
10452.L_OP_UNUSED_F7FF: /* 0x1f7 */
10453/* File: armv5te/OP_UNUSED_F7FF.S */
10454/* File: armv5te/unused.S */
10455    bl      common_abort
10456
10457
10458/* ------------------------------ */
10459    .balign 64
10460.L_OP_UNUSED_F8FF: /* 0x1f8 */
10461/* File: armv5te/OP_UNUSED_F8FF.S */
10462/* File: armv5te/unused.S */
10463    bl      common_abort
10464
10465
10466/* ------------------------------ */
10467    .balign 64
10468.L_OP_UNUSED_F9FF: /* 0x1f9 */
10469/* File: armv5te/OP_UNUSED_F9FF.S */
10470/* File: armv5te/unused.S */
10471    bl      common_abort
10472
10473
10474/* ------------------------------ */
10475    .balign 64
10476.L_OP_UNUSED_FAFF: /* 0x1fa */
10477/* File: armv5te/OP_UNUSED_FAFF.S */
10478/* File: armv5te/unused.S */
10479    bl      common_abort
10480
10481
10482/* ------------------------------ */
10483    .balign 64
10484.L_OP_UNUSED_FBFF: /* 0x1fb */
10485/* File: armv5te/OP_UNUSED_FBFF.S */
10486/* File: armv5te/unused.S */
10487    bl      common_abort
10488
10489
10490/* ------------------------------ */
10491    .balign 64
10492.L_OP_UNUSED_FCFF: /* 0x1fc */
10493/* File: armv5te/OP_UNUSED_FCFF.S */
10494/* File: armv5te/unused.S */
10495    bl      common_abort
10496
10497
10498/* ------------------------------ */
10499    .balign 64
10500.L_OP_UNUSED_FDFF: /* 0x1fd */
10501/* File: armv5te/OP_UNUSED_FDFF.S */
10502/* File: armv5te/unused.S */
10503    bl      common_abort
10504
10505
10506/* ------------------------------ */
10507    .balign 64
10508.L_OP_UNUSED_FEFF: /* 0x1fe */
10509/* File: armv5te/OP_UNUSED_FEFF.S */
10510/* File: armv5te/unused.S */
10511    bl      common_abort
10512
10513
10514/* ------------------------------ */
10515    .balign 64
10516.L_OP_THROW_VERIFICATION_ERROR_JUMBO: /* 0x1ff */
10517/* File: armv5te/OP_THROW_VERIFICATION_ERROR_JUMBO.S */
10518    /*
10519     * Handle a jumbo throw-verification-error instruction.  This throws an
10520     * exception for an error discovered during verification.  The
10521     * exception is indicated by BBBB, with some detail provided by AAAAAAAA.
10522     */
10523    /* exop BBBB, Class@AAAAAAAA */
10524    FETCH(r1, 1)                        @ r1<- aaaa (lo)
10525    FETCH(r2, 2)                        @ r2<- AAAA (hi)
10526    ldr     r0, [rSELF, #offThread_method]    @ r0<- self->method
10527    orr     r2, r1, r2, lsl #16         @ r2<- AAAAaaaa
10528    EXPORT_PC()                         @ export the PC
10529    FETCH(r1, 3)                        @ r1<- BBBB
10530    bl      dvmThrowVerificationError   @ always throws
10531    b       common_exceptionThrown      @ handle exception
10532
10533
10534    .balign 64
10535    .size   .L_OP_NOP, .-.L_OP_NOP
10536    .global dvmAsmInstructionEnd
10537dvmAsmInstructionEnd:
10538
10539/*
10540 * ===========================================================================
10541 *  Sister implementations
10542 * ===========================================================================
10543 */
10544    .global dvmAsmSisterStart
10545    .type   dvmAsmSisterStart, %function
10546    .text
10547    .balign 4
10548dvmAsmSisterStart:
10549
10550/* continuation for OP_CONST_STRING */
10551
10552    /*
10553     * Continuation if the String has not yet been resolved.
10554     *  r1: BBBB (String ref)
10555     *  r9: target register
10556     */
10557.LOP_CONST_STRING_resolve:
10558    EXPORT_PC()
10559    ldr     r0, [rSELF, #offThread_method] @ r0<- self->method
10560    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10561    bl      dvmResolveString            @ r0<- String reference
10562    cmp     r0, #0                      @ failed?
10563    beq     common_exceptionThrown      @ yup, handle the exception
10564    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10565    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10566    SET_VREG(r0, r9)                    @ vAA<- r0
10567    GOTO_OPCODE(ip)                     @ jump to next instruction
10568
10569/* continuation for OP_CONST_STRING_JUMBO */
10570
10571    /*
10572     * Continuation if the String has not yet been resolved.
10573     *  r1: BBBBBBBB (String ref)
10574     *  r9: target register
10575     */
10576.LOP_CONST_STRING_JUMBO_resolve:
10577    EXPORT_PC()
10578    ldr     r0, [rSELF, #offThread_method] @ r0<- self->method
10579    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10580    bl      dvmResolveString            @ r0<- String reference
10581    cmp     r0, #0                      @ failed?
10582    beq     common_exceptionThrown      @ yup, handle the exception
10583    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
10584    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10585    SET_VREG(r0, r9)                    @ vAA<- r0
10586    GOTO_OPCODE(ip)                     @ jump to next instruction
10587
10588/* continuation for OP_CONST_CLASS */
10589
10590    /*
10591     * Continuation if the Class has not yet been resolved.
10592     *  r1: BBBB (Class ref)
10593     *  r9: target register
10594     */
10595.LOP_CONST_CLASS_resolve:
10596    EXPORT_PC()
10597    ldr     r0, [rSELF, #offThread_method] @ r0<- self->method
10598    mov     r2, #1                      @ r2<- true
10599    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10600    bl      dvmResolveClass             @ r0<- Class reference
10601    cmp     r0, #0                      @ failed?
10602    beq     common_exceptionThrown      @ yup, handle the exception
10603    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10604    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10605    SET_VREG(r0, r9)                    @ vAA<- r0
10606    GOTO_OPCODE(ip)                     @ jump to next instruction
10607
10608/* continuation for OP_CHECK_CAST */
10609
10610    /*
10611     * Trivial test failed, need to perform full check.  This is common.
10612     *  r0 holds obj->clazz
10613     *  r1 holds desired class resolved from BBBB
10614     *  r9 holds object
10615     */
10616.LOP_CHECK_CAST_fullcheck:
10617    mov     r10, r1                     @ avoid ClassObject getting clobbered
10618    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
10619    cmp     r0, #0                      @ failed?
10620    bne     .LOP_CHECK_CAST_okay            @ no, success
10621
10622    @ A cast has failed.  We need to throw a ClassCastException.
10623    EXPORT_PC()                         @ about to throw
10624    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
10625    mov     r1, r10                     @ r1<- desired class
10626    bl      dvmThrowClassCastException
10627    b       common_exceptionThrown
10628
10629    /*
10630     * Resolution required.  This is the least-likely path.
10631     *
10632     *  r2 holds BBBB
10633     *  r9 holds object
10634     */
10635.LOP_CHECK_CAST_resolve:
10636    EXPORT_PC()                         @ resolve() could throw
10637    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
10638    mov     r1, r2                      @ r1<- BBBB
10639    mov     r2, #0                      @ r2<- false
10640    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10641    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10642    cmp     r0, #0                      @ got null?
10643    beq     common_exceptionThrown      @ yes, handle exception
10644    mov     r1, r0                      @ r1<- class resolved from BBB
10645    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
10646    b       .LOP_CHECK_CAST_resolved        @ pick up where we left off
10647
10648/* continuation for OP_INSTANCE_OF */
10649
10650    /*
10651     * Trivial test failed, need to perform full check.  This is common.
10652     *  r0 holds obj->clazz
10653     *  r1 holds class resolved from BBBB
10654     *  r9 holds A
10655     */
10656.LOP_INSTANCE_OF_fullcheck:
10657    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
10658    @ fall through to OP_INSTANCE_OF_store
10659
10660    /*
10661     * r0 holds boolean result
10662     * r9 holds A
10663     */
10664.LOP_INSTANCE_OF_store:
10665    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10666    SET_VREG(r0, r9)                    @ vA<- r0
10667    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10668    GOTO_OPCODE(ip)                     @ jump to next instruction
10669
10670    /*
10671     * Trivial test succeeded, save and bail.
10672     *  r9 holds A
10673     */
10674.LOP_INSTANCE_OF_trivial:
10675    mov     r0, #1                      @ indicate success
10676    @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper
10677    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10678    SET_VREG(r0, r9)                    @ vA<- r0
10679    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10680    GOTO_OPCODE(ip)                     @ jump to next instruction
10681
10682    /*
10683     * Resolution required.  This is the least-likely path.
10684     *
10685     *  r3 holds BBBB
10686     *  r9 holds A
10687     */
10688.LOP_INSTANCE_OF_resolve:
10689    EXPORT_PC()                         @ resolve() could throw
10690    ldr     r0, [rSELF, #offThread_method]    @ r0<- self->method
10691    mov     r1, r3                      @ r1<- BBBB
10692    mov     r2, #1                      @ r2<- true
10693    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
10694    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10695    cmp     r0, #0                      @ got null?
10696    beq     common_exceptionThrown      @ yes, handle exception
10697    mov     r1, r0                      @ r1<- class resolved from BBB
10698    mov     r3, rINST, lsr #12          @ r3<- B
10699    GET_VREG(r0, r3)                    @ r0<- vB (object)
10700    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
10701    b       .LOP_INSTANCE_OF_resolved        @ pick up where we left off
10702
10703/* continuation for OP_NEW_INSTANCE */
10704
10705    .balign 32                          @ minimize cache lines
10706.LOP_NEW_INSTANCE_finish: @ r0=new object
10707    mov     r3, rINST, lsr #8           @ r3<- AA
10708    cmp     r0, #0                      @ failed?
10709    beq     common_exceptionThrown      @ yes, handle the exception
10710    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10711    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10712    SET_VREG(r0, r3)                    @ vAA<- r0
10713    GOTO_OPCODE(ip)                     @ jump to next instruction
10714
10715    /*
10716     * Class initialization required.
10717     *
10718     *  r0 holds class object
10719     */
10720.LOP_NEW_INSTANCE_needinit:
10721    mov     r9, r0                      @ save r0
10722    bl      dvmInitClass                @ initialize class
10723    cmp     r0, #0                      @ check boolean result
10724    mov     r0, r9                      @ restore r0
10725    bne     .LOP_NEW_INSTANCE_initialized     @ success, continue
10726    b       common_exceptionThrown      @ failed, deal with init exception
10727
10728    /*
10729     * Resolution required.  This is the least-likely path.
10730     *
10731     *  r1 holds BBBB
10732     */
10733.LOP_NEW_INSTANCE_resolve:
10734    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
10735    mov     r2, #0                      @ r2<- false
10736    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10737    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
10738    cmp     r0, #0                      @ got null?
10739    bne     .LOP_NEW_INSTANCE_resolved        @ no, continue
10740    b       common_exceptionThrown      @ yes, handle exception
10741
10742.LstrInstantiationErrorPtr:
10743    .word   .LstrInstantiationError
10744
10745/* continuation for OP_NEW_ARRAY */
10746
10747
10748    /*
10749     * Resolve class.  (This is an uncommon case.)
10750     *
10751     *  r1 holds array length
10752     *  r2 holds class ref CCCC
10753     */
10754.LOP_NEW_ARRAY_resolve:
10755    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
10756    mov     r9, r1                      @ r9<- length (save)
10757    mov     r1, r2                      @ r1<- CCCC
10758    mov     r2, #0                      @ r2<- false
10759    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
10760    bl      dvmResolveClass             @ r0<- call(clazz, ref)
10761    cmp     r0, #0                      @ got null?
10762    mov     r1, r9                      @ r1<- length (restore)
10763    beq     common_exceptionThrown      @ yes, handle exception
10764    @ fall through to OP_NEW_ARRAY_finish
10765
10766    /*
10767     * Finish allocation.
10768     *
10769     *  r0 holds class
10770     *  r1 holds array length
10771     */
10772.LOP_NEW_ARRAY_finish:
10773    mov     r2, #ALLOC_DONT_TRACK       @ don't track in local refs table
10774    bl      dvmAllocArrayByClass        @ r0<- call(clazz, length, flags)
10775    cmp     r0, #0                      @ failed?
10776    mov     r2, rINST, lsr #8           @ r2<- A+
10777    beq     common_exceptionThrown      @ yes, handle the exception
10778    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10779    and     r2, r2, #15                 @ r2<- A
10780    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10781    SET_VREG(r0, r2)                    @ vA<- r0
10782    GOTO_OPCODE(ip)                     @ jump to next instruction
10783
10784/* continuation for OP_FILLED_NEW_ARRAY */
10785
10786    /*
10787     * On entry:
10788     *  r0 holds array class
10789     *  r10 holds AA or BA
10790     */
10791.LOP_FILLED_NEW_ARRAY_continue:
10792    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
10793    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
10794    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
10795    .if     0
10796    mov     r1, r10                     @ r1<- AA (length)
10797    .else
10798    mov     r1, r10, lsr #4             @ r1<- B (length)
10799    .endif
10800    cmp     rINST, #'I'                 @ array of ints?
10801    cmpne   rINST, #'L'                 @ array of objects?
10802    cmpne   rINST, #'['                 @ array of arrays?
10803    mov     r9, r1                      @ save length in r9
10804    bne     .LOP_FILLED_NEW_ARRAY_notimpl         @ no, not handled yet
10805    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
10806    cmp     r0, #0                      @ null return?
10807    beq     common_exceptionThrown      @ alloc failed, handle exception
10808
10809    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
10810    str     r0, [rSELF, #offThread_retval]      @ retval.l <- new array
10811    str     rINST, [rSELF, #offThread_retval+4] @ retval.h <- type
10812    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
10813    subs    r9, r9, #1                  @ length--, check for neg
10814    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
10815    bmi     2f                          @ was zero, bail
10816
10817    @ copy values from registers into the array
10818    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
10819    .if     0
10820    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
108211:  ldr     r3, [r2], #4                @ r3<- *r2++
10822    subs    r9, r9, #1                  @ count--
10823    str     r3, [r0], #4                @ *contents++ = vX
10824    bpl     1b
10825    @ continue at 2
10826    .else
10827    cmp     r9, #4                      @ length was initially 5?
10828    and     r2, r10, #15                @ r2<- A
10829    bne     1f                          @ <= 4 args, branch
10830    GET_VREG(r3, r2)                    @ r3<- vA
10831    sub     r9, r9, #1                  @ count--
10832    str     r3, [r0, #16]               @ contents[4] = vA
108331:  and     r2, r1, #15                 @ r2<- F/E/D/C
10834    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
10835    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
10836    subs    r9, r9, #1                  @ count--
10837    str     r3, [r0], #4                @ *contents++ = vX
10838    bpl     1b
10839    @ continue at 2
10840    .endif
10841
108422:
10843    ldr     r0, [rSELF, #offThread_retval]     @ r0<- object
10844    ldr     r1, [rSELF, #offThread_retval+4]   @ r1<- type
10845    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
10846    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
10847    cmp     r1, #'I'                         @ Is int array?
10848    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
10849    GOTO_OPCODE(ip)                          @ execute it
10850
10851    /*
10852     * Throw an exception indicating that we have not implemented this
10853     * mode of filled-new-array.
10854     */
10855.LOP_FILLED_NEW_ARRAY_notimpl:
10856    ldr     r0, .L_strInternalError
10857    ldr     r1, .L_strFilledNewArrayNotImpl
10858    bl      dvmThrowException
10859    b       common_exceptionThrown
10860
10861    .if     (!0)                 @ define in one or the other, not both
10862.L_strFilledNewArrayNotImpl:
10863    .word   .LstrFilledNewArrayNotImpl
10864.L_strInternalError:
10865    .word   .LstrInternalError
10866    .endif
10867
10868/* continuation for OP_FILLED_NEW_ARRAY_RANGE */
10869
10870    /*
10871     * On entry:
10872     *  r0 holds array class
10873     *  r10 holds AA or BA
10874     */
10875.LOP_FILLED_NEW_ARRAY_RANGE_continue:
10876    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
10877    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
10878    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
10879    .if     1
10880    mov     r1, r10                     @ r1<- AA (length)
10881    .else
10882    mov     r1, r10, lsr #4             @ r1<- B (length)
10883    .endif
10884    cmp     rINST, #'I'                 @ array of ints?
10885    cmpne   rINST, #'L'                 @ array of objects?
10886    cmpne   rINST, #'['                 @ array of arrays?
10887    mov     r9, r1                      @ save length in r9
10888    bne     .LOP_FILLED_NEW_ARRAY_RANGE_notimpl         @ no, not handled yet
10889    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
10890    cmp     r0, #0                      @ null return?
10891    beq     common_exceptionThrown      @ alloc failed, handle exception
10892
10893    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
10894    str     r0, [rSELF, #offThread_retval]      @ retval.l <- new array
10895    str     rINST, [rSELF, #offThread_retval+4] @ retval.h <- type
10896    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
10897    subs    r9, r9, #1                  @ length--, check for neg
10898    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
10899    bmi     2f                          @ was zero, bail
10900
10901    @ copy values from registers into the array
10902    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
10903    .if     1
10904    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
109051:  ldr     r3, [r2], #4                @ r3<- *r2++
10906    subs    r9, r9, #1                  @ count--
10907    str     r3, [r0], #4                @ *contents++ = vX
10908    bpl     1b
10909    @ continue at 2
10910    .else
10911    cmp     r9, #4                      @ length was initially 5?
10912    and     r2, r10, #15                @ r2<- A
10913    bne     1f                          @ <= 4 args, branch
10914    GET_VREG(r3, r2)                    @ r3<- vA
10915    sub     r9, r9, #1                  @ count--
10916    str     r3, [r0, #16]               @ contents[4] = vA
109171:  and     r2, r1, #15                 @ r2<- F/E/D/C
10918    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
10919    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
10920    subs    r9, r9, #1                  @ count--
10921    str     r3, [r0], #4                @ *contents++ = vX
10922    bpl     1b
10923    @ continue at 2
10924    .endif
10925
109262:
10927    ldr     r0, [rSELF, #offThread_retval]     @ r0<- object
10928    ldr     r1, [rSELF, #offThread_retval+4]   @ r1<- type
10929    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
10930    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
10931    cmp     r1, #'I'                         @ Is int array?
10932    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
10933    GOTO_OPCODE(ip)                          @ execute it
10934
10935    /*
10936     * Throw an exception indicating that we have not implemented this
10937     * mode of filled-new-array.
10938     */
10939.LOP_FILLED_NEW_ARRAY_RANGE_notimpl:
10940    ldr     r0, .L_strInternalError
10941    ldr     r1, .L_strFilledNewArrayNotImpl
10942    bl      dvmThrowException
10943    b       common_exceptionThrown
10944
10945    .if     (!1)                 @ define in one or the other, not both
10946.L_strFilledNewArrayNotImpl:
10947    .word   .LstrFilledNewArrayNotImpl
10948.L_strInternalError:
10949    .word   .LstrInternalError
10950    .endif
10951
10952/* continuation for OP_CMPL_FLOAT */
10953.LOP_CMPL_FLOAT_finish:
10954    SET_VREG(r0, r9)                    @ vAA<- r0
10955    GOTO_OPCODE(ip)                     @ jump to next instruction
10956
10957/* continuation for OP_CMPG_FLOAT */
10958.LOP_CMPG_FLOAT_finish:
10959    SET_VREG(r0, r9)                    @ vAA<- r0
10960    GOTO_OPCODE(ip)                     @ jump to next instruction
10961
10962/* continuation for OP_CMPL_DOUBLE */
10963.LOP_CMPL_DOUBLE_finish:
10964    SET_VREG(r0, r9)                    @ vAA<- r0
10965    GOTO_OPCODE(ip)                     @ jump to next instruction
10966
10967/* continuation for OP_CMPG_DOUBLE */
10968.LOP_CMPG_DOUBLE_finish:
10969    SET_VREG(r0, r9)                    @ vAA<- r0
10970    GOTO_OPCODE(ip)                     @ jump to next instruction
10971
10972/* continuation for OP_CMP_LONG */
10973
10974.LOP_CMP_LONG_less:
10975    mvn     r1, #0                      @ r1<- -1
10976    @ Want to cond code the next mov so we can avoid branch, but don't see it;
10977    @ instead, we just replicate the tail end.
10978    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10979    SET_VREG(r1, r9)                    @ vAA<- r1
10980    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10981    GOTO_OPCODE(ip)                     @ jump to next instruction
10982
10983.LOP_CMP_LONG_greater:
10984    mov     r1, #1                      @ r1<- 1
10985    @ fall through to _finish
10986
10987.LOP_CMP_LONG_finish:
10988    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10989    SET_VREG(r1, r9)                    @ vAA<- r1
10990    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10991    GOTO_OPCODE(ip)                     @ jump to next instruction
10992
10993/* continuation for OP_AGET_WIDE */
10994
10995.LOP_AGET_WIDE_finish:
10996    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10997    ldrd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
10998    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
10999    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11000    stmia   r9, {r2-r3}                 @ vAA/vAA+1<- r2/r3
11001    GOTO_OPCODE(ip)                     @ jump to next instruction
11002
11003/* continuation for OP_APUT_WIDE */
11004
11005.LOP_APUT_WIDE_finish:
11006    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11007    ldmia   r9, {r2-r3}                 @ r2/r3<- vAA/vAA+1
11008    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11009    strd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
11010    GOTO_OPCODE(ip)                     @ jump to next instruction
11011
11012/* continuation for OP_APUT_OBJECT */
11013    /*
11014     * On entry:
11015     *  rINST = vBB (arrayObj)
11016     *  r9 = vAA (obj)
11017     *  r10 = offset into array (vBB + vCC * width)
11018     */
11019.LOP_APUT_OBJECT_finish:
11020    cmp     r9, #0                      @ storing null reference?
11021    beq     .LOP_APUT_OBJECT_skip_check      @ yes, skip type checks
11022    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
11023    ldr     r1, [rINST, #offObject_clazz]  @ r1<- arrayObj->clazz
11024    bl      dvmCanPutArrayElement       @ test object type vs. array type
11025    cmp     r0, #0                      @ okay?
11026    beq     .LOP_APUT_OBJECT_throw           @ no
11027    mov     r1, rINST                   @ r1<- arrayObj
11028    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11029    ldr     r2, [rSELF, #offThread_cardTable]     @ get biased CT base
11030    add     r10, #offArrayObject_contents   @ r0<- pointer to slot
11031    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11032    str     r9, [r10]                   @ vBB[vCC]<- vAA
11033    strb    r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head
11034    GOTO_OPCODE(ip)                     @ jump to next instruction
11035.LOP_APUT_OBJECT_skip_check:
11036    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11037    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11038    str     r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA
11039    GOTO_OPCODE(ip)                     @ jump to next instruction
11040.LOP_APUT_OBJECT_throw:
11041    @ The types don't match.  We need to throw an ArrayStoreException.
11042    ldr     r0, [r9, #offObject_clazz]
11043    ldr     r1, [rINST, #offObject_clazz]
11044    EXPORT_PC()
11045    bl      dvmThrowArrayStoreException
11046    b       common_exceptionThrown
11047
11048/* continuation for OP_IGET */
11049
11050    /*
11051     * Currently:
11052     *  r0 holds resolved field
11053     *  r9 holds object
11054     */
11055.LOP_IGET_finish:
11056    @bl      common_squeak0
11057    cmp     r9, #0                      @ check object for null
11058    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11059    beq     common_errNullObject        @ object was null
11060    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11061    ubfx    r2, rINST, #8, #4           @ r2<- A
11062    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11063    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11064    SET_VREG(r0, r2)                    @ fp[A]<- r0
11065    GOTO_OPCODE(ip)                     @ jump to next instruction
11066
11067/* continuation for OP_IGET_WIDE */
11068
11069    /*
11070     * Currently:
11071     *  r0 holds resolved field
11072     *  r9 holds object
11073     */
11074.LOP_IGET_WIDE_finish:
11075    cmp     r9, #0                      @ check object for null
11076    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11077    beq     common_errNullObject        @ object was null
11078    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
11079    ubfx    r2, rINST, #8, #4           @ r2<- A
11080    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11081    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
11082    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11083    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
11084    GOTO_OPCODE(ip)                     @ jump to next instruction
11085
11086/* continuation for OP_IGET_OBJECT */
11087
11088    /*
11089     * Currently:
11090     *  r0 holds resolved field
11091     *  r9 holds object
11092     */
11093.LOP_IGET_OBJECT_finish:
11094    @bl      common_squeak0
11095    cmp     r9, #0                      @ check object for null
11096    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11097    beq     common_errNullObject        @ object was null
11098    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11099    @ no-op                             @ acquiring load
11100    mov     r2, rINST, lsr #8           @ r2<- A+
11101    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11102    and     r2, r2, #15                 @ r2<- A
11103    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11104    SET_VREG(r0, r2)                    @ fp[A]<- r0
11105    GOTO_OPCODE(ip)                     @ jump to next instruction
11106
11107/* continuation for OP_IGET_BOOLEAN */
11108
11109    /*
11110     * Currently:
11111     *  r0 holds resolved field
11112     *  r9 holds object
11113     */
11114.LOP_IGET_BOOLEAN_finish:
11115    @bl      common_squeak1
11116    cmp     r9, #0                      @ check object for null
11117    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11118    beq     common_errNullObject        @ object was null
11119    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11120    @ no-op                             @ acquiring load
11121    mov     r2, rINST, lsr #8           @ r2<- A+
11122    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11123    and     r2, r2, #15                 @ r2<- A
11124    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11125    SET_VREG(r0, r2)                    @ fp[A]<- r0
11126    GOTO_OPCODE(ip)                     @ jump to next instruction
11127
11128/* continuation for OP_IGET_BYTE */
11129
11130    /*
11131     * Currently:
11132     *  r0 holds resolved field
11133     *  r9 holds object
11134     */
11135.LOP_IGET_BYTE_finish:
11136    @bl      common_squeak2
11137    cmp     r9, #0                      @ check object for null
11138    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11139    beq     common_errNullObject        @ object was null
11140    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11141    @ no-op                             @ acquiring load
11142    mov     r2, rINST, lsr #8           @ r2<- A+
11143    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11144    and     r2, r2, #15                 @ r2<- A
11145    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11146    SET_VREG(r0, r2)                    @ fp[A]<- r0
11147    GOTO_OPCODE(ip)                     @ jump to next instruction
11148
11149/* continuation for OP_IGET_CHAR */
11150
11151    /*
11152     * Currently:
11153     *  r0 holds resolved field
11154     *  r9 holds object
11155     */
11156.LOP_IGET_CHAR_finish:
11157    @bl      common_squeak3
11158    cmp     r9, #0                      @ check object for null
11159    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11160    beq     common_errNullObject        @ object was null
11161    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11162    @ no-op                             @ acquiring load
11163    mov     r2, rINST, lsr #8           @ r2<- A+
11164    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11165    and     r2, r2, #15                 @ r2<- A
11166    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11167    SET_VREG(r0, r2)                    @ fp[A]<- r0
11168    GOTO_OPCODE(ip)                     @ jump to next instruction
11169
11170/* continuation for OP_IGET_SHORT */
11171
11172    /*
11173     * Currently:
11174     *  r0 holds resolved field
11175     *  r9 holds object
11176     */
11177.LOP_IGET_SHORT_finish:
11178    @bl      common_squeak4
11179    cmp     r9, #0                      @ check object for null
11180    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11181    beq     common_errNullObject        @ object was null
11182    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11183    @ no-op                             @ acquiring load
11184    mov     r2, rINST, lsr #8           @ r2<- A+
11185    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11186    and     r2, r2, #15                 @ r2<- A
11187    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11188    SET_VREG(r0, r2)                    @ fp[A]<- r0
11189    GOTO_OPCODE(ip)                     @ jump to next instruction
11190
11191/* continuation for OP_IPUT */
11192
11193    /*
11194     * Currently:
11195     *  r0 holds resolved field
11196     *  r9 holds object
11197     */
11198.LOP_IPUT_finish:
11199    @bl      common_squeak0
11200    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11201    ubfx    r1, rINST, #8, #4           @ r1<- A
11202    cmp     r9, #0                      @ check object for null
11203    GET_VREG(r0, r1)                    @ r0<- fp[A]
11204    beq     common_errNullObject        @ object was null
11205    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11206    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11207    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11208    GOTO_OPCODE(ip)                     @ jump to next instruction
11209
11210/* continuation for OP_IPUT_WIDE */
11211
11212    /*
11213     * Currently:
11214     *  r0 holds resolved field
11215     *  r9 holds object
11216     */
11217.LOP_IPUT_WIDE_finish:
11218    ubfx    r2, rINST, #8, #4           @ r2<- A
11219    cmp     r9, #0                      @ check object for null
11220    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11221    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
11222    beq     common_errNullObject        @ object was null
11223    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11224    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
11225    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11226    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0
11227    GOTO_OPCODE(ip)                     @ jump to next instruction
11228
11229/* continuation for OP_IPUT_OBJECT */
11230
11231    /*
11232     * Currently:
11233     *  r0 holds resolved field
11234     *  r9 holds object
11235     */
11236.LOP_IPUT_OBJECT_finish:
11237    @bl      common_squeak0
11238    mov     r1, rINST, lsr #8           @ r1<- A+
11239    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11240    and     r1, r1, #15                 @ r1<- A
11241    cmp     r9, #0                      @ check object for null
11242    GET_VREG(r0, r1)                    @ r0<- fp[A]
11243    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
11244    beq     common_errNullObject        @ object was null
11245    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11246    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11247    @ no-op                             @ releasing store
11248    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
11249    cmp     r0, #0                      @ stored a null reference?
11250    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
11251    GOTO_OPCODE(ip)                     @ jump to next instruction
11252
11253/* continuation for OP_IPUT_BOOLEAN */
11254
11255    /*
11256     * Currently:
11257     *  r0 holds resolved field
11258     *  r9 holds object
11259     */
11260.LOP_IPUT_BOOLEAN_finish:
11261    @bl      common_squeak1
11262    mov     r1, rINST, lsr #8           @ r1<- A+
11263    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11264    and     r1, r1, #15                 @ r1<- A
11265    cmp     r9, #0                      @ check object for null
11266    GET_VREG(r0, r1)                    @ r0<- fp[A]
11267    beq     common_errNullObject        @ object was null
11268    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11269    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11270    @ no-op                             @ releasing store
11271    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11272    GOTO_OPCODE(ip)                     @ jump to next instruction
11273
11274/* continuation for OP_IPUT_BYTE */
11275
11276    /*
11277     * Currently:
11278     *  r0 holds resolved field
11279     *  r9 holds object
11280     */
11281.LOP_IPUT_BYTE_finish:
11282    @bl      common_squeak2
11283    mov     r1, rINST, lsr #8           @ r1<- A+
11284    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11285    and     r1, r1, #15                 @ r1<- A
11286    cmp     r9, #0                      @ check object for null
11287    GET_VREG(r0, r1)                    @ r0<- fp[A]
11288    beq     common_errNullObject        @ object was null
11289    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11290    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11291    @ no-op                             @ releasing store
11292    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11293    GOTO_OPCODE(ip)                     @ jump to next instruction
11294
11295/* continuation for OP_IPUT_CHAR */
11296
11297    /*
11298     * Currently:
11299     *  r0 holds resolved field
11300     *  r9 holds object
11301     */
11302.LOP_IPUT_CHAR_finish:
11303    @bl      common_squeak3
11304    mov     r1, rINST, lsr #8           @ r1<- A+
11305    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11306    and     r1, r1, #15                 @ r1<- A
11307    cmp     r9, #0                      @ check object for null
11308    GET_VREG(r0, r1)                    @ r0<- fp[A]
11309    beq     common_errNullObject        @ object was null
11310    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11311    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11312    @ no-op                             @ releasing store
11313    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11314    GOTO_OPCODE(ip)                     @ jump to next instruction
11315
11316/* continuation for OP_IPUT_SHORT */
11317
11318    /*
11319     * Currently:
11320     *  r0 holds resolved field
11321     *  r9 holds object
11322     */
11323.LOP_IPUT_SHORT_finish:
11324    @bl      common_squeak4
11325    mov     r1, rINST, lsr #8           @ r1<- A+
11326    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11327    and     r1, r1, #15                 @ r1<- A
11328    cmp     r9, #0                      @ check object for null
11329    GET_VREG(r0, r1)                    @ r0<- fp[A]
11330    beq     common_errNullObject        @ object was null
11331    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11332    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11333    @ no-op                             @ releasing store
11334    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11335    GOTO_OPCODE(ip)                     @ jump to next instruction
11336
11337/* continuation for OP_SGET */
11338
11339    /*
11340     * Continuation if the field has not yet been resolved.
11341     *  r1: BBBB field ref
11342     */
11343.LOP_SGET_resolve:
11344    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11345    EXPORT_PC()                         @ resolve() could throw, so export now
11346    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11347    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11348    cmp     r0, #0                      @ success?
11349    bne     .LOP_SGET_finish          @ yes, finish
11350    b       common_exceptionThrown      @ no, handle exception
11351
11352/* continuation for OP_SGET_WIDE */
11353
11354    /*
11355     * Continuation if the field has not yet been resolved.
11356     *  r1: BBBB field ref
11357     *
11358     * Returns StaticField pointer in r0.
11359     */
11360.LOP_SGET_WIDE_resolve:
11361    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11362    EXPORT_PC()                         @ resolve() could throw, so export now
11363    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11364    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11365    cmp     r0, #0                      @ success?
11366    bne     .LOP_SGET_WIDE_finish          @ yes, finish
11367    b       common_exceptionThrown      @ no, handle exception
11368
11369/* continuation for OP_SGET_OBJECT */
11370
11371    /*
11372     * Continuation if the field has not yet been resolved.
11373     *  r1: BBBB field ref
11374     */
11375.LOP_SGET_OBJECT_resolve:
11376    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11377    EXPORT_PC()                         @ resolve() could throw, so export now
11378    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11379    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11380    cmp     r0, #0                      @ success?
11381    bne     .LOP_SGET_OBJECT_finish          @ yes, finish
11382    b       common_exceptionThrown      @ no, handle exception
11383
11384/* continuation for OP_SGET_BOOLEAN */
11385
11386    /*
11387     * Continuation if the field has not yet been resolved.
11388     *  r1: BBBB field ref
11389     */
11390.LOP_SGET_BOOLEAN_resolve:
11391    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11392    EXPORT_PC()                         @ resolve() could throw, so export now
11393    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11394    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11395    cmp     r0, #0                      @ success?
11396    bne     .LOP_SGET_BOOLEAN_finish          @ yes, finish
11397    b       common_exceptionThrown      @ no, handle exception
11398
11399/* continuation for OP_SGET_BYTE */
11400
11401    /*
11402     * Continuation if the field has not yet been resolved.
11403     *  r1: BBBB field ref
11404     */
11405.LOP_SGET_BYTE_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_BYTE_finish          @ yes, finish
11412    b       common_exceptionThrown      @ no, handle exception
11413
11414/* continuation for OP_SGET_CHAR */
11415
11416    /*
11417     * Continuation if the field has not yet been resolved.
11418     *  r1: BBBB field ref
11419     */
11420.LOP_SGET_CHAR_resolve:
11421    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11422    EXPORT_PC()                         @ resolve() could throw, so export now
11423    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11424    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11425    cmp     r0, #0                      @ success?
11426    bne     .LOP_SGET_CHAR_finish          @ yes, finish
11427    b       common_exceptionThrown      @ no, handle exception
11428
11429/* continuation for OP_SGET_SHORT */
11430
11431    /*
11432     * Continuation if the field has not yet been resolved.
11433     *  r1: BBBB field ref
11434     */
11435.LOP_SGET_SHORT_resolve:
11436    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11437    EXPORT_PC()                         @ resolve() could throw, so export now
11438    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11439    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11440    cmp     r0, #0                      @ success?
11441    bne     .LOP_SGET_SHORT_finish          @ yes, finish
11442    b       common_exceptionThrown      @ no, handle exception
11443
11444/* continuation for OP_SPUT */
11445
11446    /*
11447     * Continuation if the field has not yet been resolved.
11448     *  r1: BBBB field ref
11449     */
11450.LOP_SPUT_resolve:
11451    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11452    EXPORT_PC()                         @ resolve() could throw, so export now
11453    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11454    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11455    cmp     r0, #0                      @ success?
11456    bne     .LOP_SPUT_finish          @ yes, finish
11457    b       common_exceptionThrown      @ no, handle exception
11458
11459/* continuation for OP_SPUT_WIDE */
11460
11461    /*
11462     * Continuation if the field has not yet been resolved.
11463     *  r1: BBBB field ref
11464     *  r9: &fp[AA]
11465     *
11466     * Returns StaticField pointer in r2.
11467     */
11468.LOP_SPUT_WIDE_resolve:
11469    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11470    EXPORT_PC()                         @ resolve() could throw, so export now
11471    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11472    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11473    cmp     r0, #0                      @ success?
11474    mov     r2, r0                      @ copy to r2
11475    bne     .LOP_SPUT_WIDE_finish          @ yes, finish
11476    b       common_exceptionThrown      @ no, handle exception
11477
11478/* continuation for OP_SPUT_OBJECT */
11479.LOP_SPUT_OBJECT_finish:   @ field ptr in r0
11480    mov     r2, rINST, lsr #8           @ r2<- AA
11481    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11482    GET_VREG(r1, r2)                    @ r1<- fp[AA]
11483    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
11484    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
11485    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11486    @ no-op                             @ releasing store
11487    str     r1, [r0, #offStaticField_value]  @ field<- vAA
11488    cmp     r1, #0                      @ stored a null object?
11489    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
11490    GOTO_OPCODE(ip)                     @ jump to next instruction
11491
11492/* continuation for OP_SPUT_BOOLEAN */
11493
11494    /*
11495     * Continuation if the field has not yet been resolved.
11496     *  r1: BBBB field ref
11497     */
11498.LOP_SPUT_BOOLEAN_resolve:
11499    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11500    EXPORT_PC()                         @ resolve() could throw, so export now
11501    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11502    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11503    cmp     r0, #0                      @ success?
11504    bne     .LOP_SPUT_BOOLEAN_finish          @ yes, finish
11505    b       common_exceptionThrown      @ no, handle exception
11506
11507/* continuation for OP_SPUT_BYTE */
11508
11509    /*
11510     * Continuation if the field has not yet been resolved.
11511     *  r1: BBBB field ref
11512     */
11513.LOP_SPUT_BYTE_resolve:
11514    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11515    EXPORT_PC()                         @ resolve() could throw, so export now
11516    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11517    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11518    cmp     r0, #0                      @ success?
11519    bne     .LOP_SPUT_BYTE_finish          @ yes, finish
11520    b       common_exceptionThrown      @ no, handle exception
11521
11522/* continuation for OP_SPUT_CHAR */
11523
11524    /*
11525     * Continuation if the field has not yet been resolved.
11526     *  r1: BBBB field ref
11527     */
11528.LOP_SPUT_CHAR_resolve:
11529    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11530    EXPORT_PC()                         @ resolve() could throw, so export now
11531    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11532    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11533    cmp     r0, #0                      @ success?
11534    bne     .LOP_SPUT_CHAR_finish          @ yes, finish
11535    b       common_exceptionThrown      @ no, handle exception
11536
11537/* continuation for OP_SPUT_SHORT */
11538
11539    /*
11540     * Continuation if the field has not yet been resolved.
11541     *  r1: BBBB field ref
11542     */
11543.LOP_SPUT_SHORT_resolve:
11544    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11545    EXPORT_PC()                         @ resolve() could throw, so export now
11546    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11547    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11548    cmp     r0, #0                      @ success?
11549    bne     .LOP_SPUT_SHORT_finish          @ yes, finish
11550    b       common_exceptionThrown      @ no, handle exception
11551
11552/* continuation for OP_INVOKE_VIRTUAL */
11553
11554    /*
11555     * At this point:
11556     *  r0 = resolved base method
11557     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
11558     */
11559.LOP_INVOKE_VIRTUAL_continue:
11560    GET_VREG(r1, r10)                   @ r1<- "this" ptr
11561    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11562    cmp     r1, #0                      @ is "this" null?
11563    beq     common_errNullObject        @ null "this", throw exception
11564    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
11565    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
11566    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
11567    bl      common_invokeMethodNoRange @ continue on
11568
11569/* continuation for OP_INVOKE_SUPER */
11570
11571    /*
11572     * At this point:
11573     *  r0 = resolved base method
11574     *  r9 = method->clazz
11575     */
11576.LOP_INVOKE_SUPER_continue:
11577    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
11578    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11579    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
11580    EXPORT_PC()                         @ must export for invoke
11581    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
11582    bcs     .LOP_INVOKE_SUPER_nsm             @ method not present in superclass
11583    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
11584    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
11585    bl      common_invokeMethodNoRange @ continue on
11586
11587.LOP_INVOKE_SUPER_resolve:
11588    mov     r0, r9                      @ r0<- method->clazz
11589    mov     r2, #METHOD_VIRTUAL         @ resolver method type
11590    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11591    cmp     r0, #0                      @ got null?
11592    bne     .LOP_INVOKE_SUPER_continue        @ no, continue
11593    b       common_exceptionThrown      @ yes, handle exception
11594
11595    /*
11596     * Throw a NoSuchMethodError with the method name as the message.
11597     *  r0 = resolved base method
11598     */
11599.LOP_INVOKE_SUPER_nsm:
11600    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
11601    b       common_errNoSuchMethod
11602
11603/* continuation for OP_INVOKE_DIRECT */
11604
11605    /*
11606     * On entry:
11607     *  r1 = reference (BBBB or CCCC)
11608     *  r10 = "this" register
11609     */
11610.LOP_INVOKE_DIRECT_resolve:
11611    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
11612    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
11613    mov     r2, #METHOD_DIRECT          @ resolver method type
11614    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11615    cmp     r0, #0                      @ got null?
11616    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
11617    bne     .LOP_INVOKE_DIRECT_finish          @ no, continue
11618    b       common_exceptionThrown      @ yes, handle exception
11619
11620/* continuation for OP_INVOKE_VIRTUAL_RANGE */
11621
11622    /*
11623     * At this point:
11624     *  r0 = resolved base method
11625     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
11626     */
11627.LOP_INVOKE_VIRTUAL_RANGE_continue:
11628    GET_VREG(r1, r10)                   @ r1<- "this" ptr
11629    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11630    cmp     r1, #0                      @ is "this" null?
11631    beq     common_errNullObject        @ null "this", throw exception
11632    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
11633    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
11634    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
11635    bl      common_invokeMethodRange @ continue on
11636
11637/* continuation for OP_INVOKE_SUPER_RANGE */
11638
11639    /*
11640     * At this point:
11641     *  r0 = resolved base method
11642     *  r9 = method->clazz
11643     */
11644.LOP_INVOKE_SUPER_RANGE_continue:
11645    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
11646    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
11647    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
11648    EXPORT_PC()                         @ must export for invoke
11649    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
11650    bcs     .LOP_INVOKE_SUPER_RANGE_nsm             @ method not present in superclass
11651    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
11652    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
11653    bl      common_invokeMethodRange @ continue on
11654
11655.LOP_INVOKE_SUPER_RANGE_resolve:
11656    mov     r0, r9                      @ r0<- method->clazz
11657    mov     r2, #METHOD_VIRTUAL         @ resolver method type
11658    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11659    cmp     r0, #0                      @ got null?
11660    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ no, continue
11661    b       common_exceptionThrown      @ yes, handle exception
11662
11663    /*
11664     * Throw a NoSuchMethodError with the method name as the message.
11665     *  r0 = resolved base method
11666     */
11667.LOP_INVOKE_SUPER_RANGE_nsm:
11668    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
11669    b       common_errNoSuchMethod
11670
11671/* continuation for OP_INVOKE_DIRECT_RANGE */
11672
11673    /*
11674     * On entry:
11675     *  r1 = reference (BBBB or CCCC)
11676     *  r10 = "this" register
11677     */
11678.LOP_INVOKE_DIRECT_RANGE_resolve:
11679    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
11680    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
11681    mov     r2, #METHOD_DIRECT          @ resolver method type
11682    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
11683    cmp     r0, #0                      @ got null?
11684    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
11685    bne     .LOP_INVOKE_DIRECT_RANGE_finish          @ no, continue
11686    b       common_exceptionThrown      @ yes, handle exception
11687
11688/* continuation for OP_FLOAT_TO_LONG */
11689/*
11690 * Convert the float in r0 to a long in r0/r1.
11691 *
11692 * We have to clip values to long min/max per the specification.  The
11693 * expected common case is a "reasonable" value that converts directly
11694 * to modest integer.  The EABI convert function isn't doing this for us.
11695 */
11696f2l_doconv:
11697    stmfd   sp!, {r4, lr}
11698    mov     r1, #0x5f000000             @ (float)maxlong
11699    mov     r4, r0
11700    bl      __aeabi_fcmpge              @ is arg >= maxlong?
11701    cmp     r0, #0                      @ nonzero == yes
11702    mvnne   r0, #0                      @ return maxlong (7fffffff)
11703    mvnne   r1, #0x80000000
11704    ldmnefd sp!, {r4, pc}
11705
11706    mov     r0, r4                      @ recover arg
11707    mov     r1, #0xdf000000             @ (float)minlong
11708    bl      __aeabi_fcmple              @ is arg <= minlong?
11709    cmp     r0, #0                      @ nonzero == yes
11710    movne   r0, #0                      @ return minlong (80000000)
11711    movne   r1, #0x80000000
11712    ldmnefd sp!, {r4, pc}
11713
11714    mov     r0, r4                      @ recover arg
11715    mov     r1, r4
11716    bl      __aeabi_fcmpeq              @ is arg == self?
11717    cmp     r0, #0                      @ zero == no
11718    moveq   r1, #0                      @ return zero for NaN
11719    ldmeqfd sp!, {r4, pc}
11720
11721    mov     r0, r4                      @ recover arg
11722    bl      __aeabi_f2lz                @ convert float to long
11723    ldmfd   sp!, {r4, pc}
11724
11725/* continuation for OP_DOUBLE_TO_LONG */
11726/*
11727 * Convert the double in r0/r1 to a long in r0/r1.
11728 *
11729 * We have to clip values to long min/max per the specification.  The
11730 * expected common case is a "reasonable" value that converts directly
11731 * to modest integer.  The EABI convert function isn't doing this for us.
11732 */
11733d2l_doconv:
11734    stmfd   sp!, {r4, r5, lr}           @ save regs
11735    mov     r3, #0x43000000             @ maxlong, as a double (high word)
11736    add     r3, #0x00e00000             @  0x43e00000
11737    mov     r2, #0                      @ maxlong, as a double (low word)
11738    sub     sp, sp, #4                  @ align for EABI
11739    mov     r4, r0                      @ save a copy of r0
11740    mov     r5, r1                      @  and r1
11741    bl      __aeabi_dcmpge              @ is arg >= maxlong?
11742    cmp     r0, #0                      @ nonzero == yes
11743    mvnne   r0, #0                      @ return maxlong (7fffffffffffffff)
11744    mvnne   r1, #0x80000000
11745    bne     1f
11746
11747    mov     r0, r4                      @ recover arg
11748    mov     r1, r5
11749    mov     r3, #0xc3000000             @ minlong, as a double (high word)
11750    add     r3, #0x00e00000             @  0xc3e00000
11751    mov     r2, #0                      @ minlong, as a double (low word)
11752    bl      __aeabi_dcmple              @ is arg <= minlong?
11753    cmp     r0, #0                      @ nonzero == yes
11754    movne   r0, #0                      @ return minlong (8000000000000000)
11755    movne   r1, #0x80000000
11756    bne     1f
11757
11758    mov     r0, r4                      @ recover arg
11759    mov     r1, r5
11760    mov     r2, r4                      @ compare against self
11761    mov     r3, r5
11762    bl      __aeabi_dcmpeq              @ is arg == self?
11763    cmp     r0, #0                      @ zero == no
11764    moveq   r1, #0                      @ return zero for NaN
11765    beq     1f
11766
11767    mov     r0, r4                      @ recover arg
11768    mov     r1, r5
11769    bl      __aeabi_d2lz                @ convert double to long
11770
117711:
11772    add     sp, sp, #4
11773    ldmfd   sp!, {r4, r5, pc}
11774
11775/* continuation for OP_MUL_LONG */
11776
11777.LOP_MUL_LONG_finish:
11778    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11779    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
11780    GOTO_OPCODE(ip)                     @ jump to next instruction
11781
11782/* continuation for OP_SHL_LONG */
11783
11784.LOP_SHL_LONG_finish:
11785    mov     r0, r0, asl r2              @  r0<- r0 << r2
11786    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11787    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11788    GOTO_OPCODE(ip)                     @ jump to next instruction
11789
11790/* continuation for OP_SHR_LONG */
11791
11792.LOP_SHR_LONG_finish:
11793    mov     r1, r1, asr r2              @  r1<- r1 >> r2
11794    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11795    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11796    GOTO_OPCODE(ip)                     @ jump to next instruction
11797
11798/* continuation for OP_USHR_LONG */
11799
11800.LOP_USHR_LONG_finish:
11801    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
11802    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11803    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11804    GOTO_OPCODE(ip)                     @ jump to next instruction
11805
11806/* continuation for OP_SHL_LONG_2ADDR */
11807
11808.LOP_SHL_LONG_2ADDR_finish:
11809    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11810    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11811    GOTO_OPCODE(ip)                     @ jump to next instruction
11812
11813/* continuation for OP_SHR_LONG_2ADDR */
11814
11815.LOP_SHR_LONG_2ADDR_finish:
11816    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11817    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11818    GOTO_OPCODE(ip)                     @ jump to next instruction
11819
11820/* continuation for OP_USHR_LONG_2ADDR */
11821
11822.LOP_USHR_LONG_2ADDR_finish:
11823    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11824    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
11825    GOTO_OPCODE(ip)                     @ jump to next instruction
11826
11827/* continuation for OP_IGET_VOLATILE */
11828
11829    /*
11830     * Currently:
11831     *  r0 holds resolved field
11832     *  r9 holds object
11833     */
11834.LOP_IGET_VOLATILE_finish:
11835    @bl      common_squeak0
11836    cmp     r9, #0                      @ check object for null
11837    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11838    beq     common_errNullObject        @ object was null
11839    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11840    SMP_DMB                            @ acquiring load
11841    mov     r2, rINST, lsr #8           @ r2<- A+
11842    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11843    and     r2, r2, #15                 @ r2<- A
11844    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11845    SET_VREG(r0, r2)                    @ fp[A]<- r0
11846    GOTO_OPCODE(ip)                     @ jump to next instruction
11847
11848/* continuation for OP_IPUT_VOLATILE */
11849
11850    /*
11851     * Currently:
11852     *  r0 holds resolved field
11853     *  r9 holds object
11854     */
11855.LOP_IPUT_VOLATILE_finish:
11856    @bl      common_squeak0
11857    mov     r1, rINST, lsr #8           @ r1<- A+
11858    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11859    and     r1, r1, #15                 @ r1<- A
11860    cmp     r9, #0                      @ check object for null
11861    GET_VREG(r0, r1)                    @ r0<- fp[A]
11862    beq     common_errNullObject        @ object was null
11863    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11864    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11865    SMP_DMB                            @ releasing store
11866    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
11867    GOTO_OPCODE(ip)                     @ jump to next instruction
11868
11869/* continuation for OP_SGET_VOLATILE */
11870
11871    /*
11872     * Continuation if the field has not yet been resolved.
11873     *  r1: BBBB field ref
11874     */
11875.LOP_SGET_VOLATILE_resolve:
11876    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11877    EXPORT_PC()                         @ resolve() could throw, so export now
11878    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11879    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11880    cmp     r0, #0                      @ success?
11881    bne     .LOP_SGET_VOLATILE_finish          @ yes, finish
11882    b       common_exceptionThrown      @ no, handle exception
11883
11884/* continuation for OP_SPUT_VOLATILE */
11885
11886    /*
11887     * Continuation if the field has not yet been resolved.
11888     *  r1: BBBB field ref
11889     */
11890.LOP_SPUT_VOLATILE_resolve:
11891    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11892    EXPORT_PC()                         @ resolve() could throw, so export now
11893    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11894    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11895    cmp     r0, #0                      @ success?
11896    bne     .LOP_SPUT_VOLATILE_finish          @ yes, finish
11897    b       common_exceptionThrown      @ no, handle exception
11898
11899/* continuation for OP_IGET_OBJECT_VOLATILE */
11900
11901    /*
11902     * Currently:
11903     *  r0 holds resolved field
11904     *  r9 holds object
11905     */
11906.LOP_IGET_OBJECT_VOLATILE_finish:
11907    @bl      common_squeak0
11908    cmp     r9, #0                      @ check object for null
11909    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11910    beq     common_errNullObject        @ object was null
11911    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
11912    SMP_DMB                            @ acquiring load
11913    mov     r2, rINST, lsr #8           @ r2<- A+
11914    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11915    and     r2, r2, #15                 @ r2<- A
11916    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11917    SET_VREG(r0, r2)                    @ fp[A]<- r0
11918    GOTO_OPCODE(ip)                     @ jump to next instruction
11919
11920/* continuation for OP_IGET_WIDE_VOLATILE */
11921
11922    /*
11923     * Currently:
11924     *  r0 holds resolved field
11925     *  r9 holds object
11926     */
11927.LOP_IGET_WIDE_VOLATILE_finish:
11928    cmp     r9, #0                      @ check object for null
11929    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11930    beq     common_errNullObject        @ object was null
11931    .if     1
11932    add     r0, r9, r3                  @ r0<- address of field
11933    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
11934    .else
11935    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
11936    .endif
11937    mov     r2, rINST, lsr #8           @ r2<- A+
11938    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11939    and     r2, r2, #15                 @ r2<- A
11940    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
11941    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
11942    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
11943    GOTO_OPCODE(ip)                     @ jump to next instruction
11944
11945/* continuation for OP_IPUT_WIDE_VOLATILE */
11946
11947    /*
11948     * Currently:
11949     *  r0 holds resolved field
11950     *  r9 holds object
11951     */
11952.LOP_IPUT_WIDE_VOLATILE_finish:
11953    mov     r2, rINST, lsr #8           @ r2<- A+
11954    cmp     r9, #0                      @ check object for null
11955    and     r2, r2, #15                 @ r2<- A
11956    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
11957    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
11958    beq     common_errNullObject        @ object was null
11959    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
11960    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
11961    GET_INST_OPCODE(r10)                @ extract opcode from rINST
11962    .if     1
11963    add     r2, r9, r3                  @ r2<- target address
11964    bl      dvmQuasiAtomicSwap64        @ stores r0/r1 into addr r2
11965    .else
11966    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
11967    .endif
11968    GOTO_OPCODE(r10)                    @ jump to next instruction
11969
11970/* continuation for OP_SGET_WIDE_VOLATILE */
11971
11972    /*
11973     * Continuation if the field has not yet been resolved.
11974     *  r1: BBBB field ref
11975     *
11976     * Returns StaticField pointer in r0.
11977     */
11978.LOP_SGET_WIDE_VOLATILE_resolve:
11979    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11980    EXPORT_PC()                         @ resolve() could throw, so export now
11981    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
11982    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
11983    cmp     r0, #0                      @ success?
11984    bne     .LOP_SGET_WIDE_VOLATILE_finish          @ yes, finish
11985    b       common_exceptionThrown      @ no, handle exception
11986
11987/* continuation for OP_SPUT_WIDE_VOLATILE */
11988
11989    /*
11990     * Continuation if the field has not yet been resolved.
11991     *  r1: BBBB field ref
11992     *  r9: &fp[AA]
11993     *
11994     * Returns StaticField pointer in r2.
11995     */
11996.LOP_SPUT_WIDE_VOLATILE_resolve:
11997    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
11998    EXPORT_PC()                         @ resolve() could throw, so export now
11999    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12000    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12001    cmp     r0, #0                      @ success?
12002    mov     r2, r0                      @ copy to r2
12003    bne     .LOP_SPUT_WIDE_VOLATILE_finish          @ yes, finish
12004    b       common_exceptionThrown      @ no, handle exception
12005
12006/* continuation for OP_EXECUTE_INLINE */
12007
12008    /*
12009     * Extract args, call function.
12010     *  r0 = #of args (0-4)
12011     *  r10 = call index
12012     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
12013     *
12014     * Other ideas:
12015     * - Use a jump table from the main piece to jump directly into the
12016     *   AND/LDR pairs.  Costs a data load, saves a branch.
12017     * - Have five separate pieces that do the loading, so we can work the
12018     *   interleave a little better.  Increases code size.
12019     */
12020.LOP_EXECUTE_INLINE_continue:
12021    rsb     r0, r0, #4                  @ r0<- 4-r0
12022    FETCH(r9, 2)                        @ r9<- FEDC
12023    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
12024    bl      common_abort                @ (skipped due to ARM prefetch)
120254:  and     ip, r9, #0xf000             @ isolate F
12026    ldr     r3, [rFP, ip, lsr #10]      @ r3<- vF (shift right 12, left 2)
120273:  and     ip, r9, #0x0f00             @ isolate E
12028    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vE
120292:  and     ip, r9, #0x00f0             @ isolate D
12030    ldr     r1, [rFP, ip, lsr #2]       @ r1<- vD
120311:  and     ip, r9, #0x000f             @ isolate C
12032    ldr     r0, [rFP, ip, lsl #2]       @ r0<- vC
120330:
12034    ldr     r9, .LOP_EXECUTE_INLINE_table       @ table of InlineOperation
12035    ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
12036    @ (not reached)
12037
12038.LOP_EXECUTE_INLINE_table:
12039    .word   gDvmInlineOpsTable
12040
12041/* continuation for OP_EXECUTE_INLINE_RANGE */
12042
12043    /*
12044     * Extract args, call function.
12045     *  r0 = #of args (0-4)
12046     *  r10 = call index
12047     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
12048     */
12049.LOP_EXECUTE_INLINE_RANGE_continue:
12050    rsb     r0, r0, #4                  @ r0<- 4-r0
12051    FETCH(r9, 2)                        @ r9<- CCCC
12052    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
12053    bl      common_abort                @ (skipped due to ARM prefetch)
120544:  add     ip, r9, #3                  @ base+3
12055    GET_VREG(r3, ip)                    @ r3<- vBase[3]
120563:  add     ip, r9, #2                  @ base+2
12057    GET_VREG(r2, ip)                    @ r2<- vBase[2]
120582:  add     ip, r9, #1                  @ base+1
12059    GET_VREG(r1, ip)                    @ r1<- vBase[1]
120601:  add     ip, r9, #0                  @ (nop)
12061    GET_VREG(r0, ip)                    @ r0<- vBase[0]
120620:
12063    ldr     r9, .LOP_EXECUTE_INLINE_RANGE_table       @ table of InlineOperation
12064    ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
12065    @ (not reached)
12066
12067.LOP_EXECUTE_INLINE_RANGE_table:
12068    .word   gDvmInlineOpsTable
12069
12070/* continuation for OP_IPUT_OBJECT_VOLATILE */
12071
12072    /*
12073     * Currently:
12074     *  r0 holds resolved field
12075     *  r9 holds object
12076     */
12077.LOP_IPUT_OBJECT_VOLATILE_finish:
12078    @bl      common_squeak0
12079    mov     r1, rINST, lsr #8           @ r1<- A+
12080    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12081    and     r1, r1, #15                 @ r1<- A
12082    cmp     r9, #0                      @ check object for null
12083    GET_VREG(r0, r1)                    @ r0<- fp[A]
12084    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
12085    beq     common_errNullObject        @ object was null
12086    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12087    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12088    SMP_DMB                            @ releasing store
12089    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
12090    cmp     r0, #0                      @ stored a null reference?
12091    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
12092    GOTO_OPCODE(ip)                     @ jump to next instruction
12093
12094/* continuation for OP_SGET_OBJECT_VOLATILE */
12095
12096    /*
12097     * Continuation if the field has not yet been resolved.
12098     *  r1: BBBB field ref
12099     */
12100.LOP_SGET_OBJECT_VOLATILE_resolve:
12101    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12102    EXPORT_PC()                         @ resolve() could throw, so export now
12103    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12104    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12105    cmp     r0, #0                      @ success?
12106    bne     .LOP_SGET_OBJECT_VOLATILE_finish          @ yes, finish
12107    b       common_exceptionThrown      @ no, handle exception
12108
12109/* continuation for OP_SPUT_OBJECT_VOLATILE */
12110.LOP_SPUT_OBJECT_VOLATILE_finish:   @ field ptr in r0
12111    mov     r2, rINST, lsr #8           @ r2<- AA
12112    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
12113    GET_VREG(r1, r2)                    @ r1<- fp[AA]
12114    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
12115    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
12116    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12117    SMP_DMB                            @ releasing store
12118    str     r1, [r0, #offStaticField_value]  @ field<- vAA
12119    cmp     r1, #0                      @ stored a null object?
12120    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
12121    GOTO_OPCODE(ip)                     @ jump to next instruction
12122
12123/* continuation for OP_CONST_CLASS_JUMBO */
12124
12125    /*
12126     * Continuation if the Class has not yet been resolved.
12127     *  r1: AAAAAAAA (Class ref)
12128     *  r9: target register
12129     */
12130.LOP_CONST_CLASS_JUMBO_resolve:
12131    EXPORT_PC()
12132    ldr     r0, [rSELF, #offThread_method] @ r0<- self->method
12133    mov     r2, #1                      @ r2<- true
12134    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
12135    bl      dvmResolveClass             @ r0<- Class reference
12136    cmp     r0, #0                      @ failed?
12137    beq     common_exceptionThrown      @ yup, handle the exception
12138    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12139    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12140    SET_VREG(r0, r9)                    @ vBBBB<- r0
12141    GOTO_OPCODE(ip)                     @ jump to next instruction
12142
12143/* continuation for OP_CHECK_CAST_JUMBO */
12144
12145    /*
12146     * Trivial test failed, need to perform full check.  This is common.
12147     *  r0 holds obj->clazz
12148     *  r1 holds desired class resolved from AAAAAAAA
12149     *  r9 holds object
12150     */
12151.LOP_CHECK_CAST_JUMBO_fullcheck:
12152    mov     r10, r1                     @ avoid ClassObject getting clobbered
12153    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
12154    cmp     r0, #0                      @ failed?
12155    bne     .LOP_CHECK_CAST_JUMBO_okay            @ no, success
12156
12157    @ A cast has failed.  We need to throw a ClassCastException.
12158    EXPORT_PC()                         @ about to throw
12159    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
12160    mov     r1, r10                     @ r1<- desired class
12161    bl      dvmThrowClassCastException
12162    b       common_exceptionThrown
12163
12164    /*
12165     * Advance PC and get the next opcode.
12166     */
12167.LOP_CHECK_CAST_JUMBO_okay:
12168    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12169    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12170    GOTO_OPCODE(ip)                     @ jump to next instruction
12171
12172    /*
12173     * Resolution required.  This is the least-likely path.
12174     *
12175     *  r2 holds AAAAAAAA
12176     *  r9 holds object
12177     */
12178.LOP_CHECK_CAST_JUMBO_resolve:
12179    EXPORT_PC()                         @ resolve() could throw
12180    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
12181    mov     r1, r2                      @ r1<- AAAAAAAA
12182    mov     r2, #0                      @ r2<- false
12183    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12184    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12185    cmp     r0, #0                      @ got null?
12186    beq     common_exceptionThrown      @ yes, handle exception
12187    mov     r1, r0                      @ r1<- class resolved from AAAAAAAA
12188    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
12189    b       .LOP_CHECK_CAST_JUMBO_resolved        @ pick up where we left off
12190
12191/* continuation for OP_INSTANCE_OF_JUMBO */
12192
12193    /*
12194     * Class resolved, determine type of check necessary.  This is common.
12195     *  r0 holds obj->clazz
12196     *  r1 holds class resolved from AAAAAAAA
12197     *  r9 holds BBBB
12198     */
12199.LOP_INSTANCE_OF_JUMBO_resolved:
12200    cmp     r0, r1                      @ same class (trivial success)?
12201    beq     .LOP_INSTANCE_OF_JUMBO_trivial         @ yes, trivial finish
12202    @ fall through to OP_INSTANCE_OF_JUMBO_fullcheck
12203
12204    /*
12205     * Trivial test failed, need to perform full check.  This is common.
12206     *  r0 holds obj->clazz
12207     *  r1 holds class resolved from AAAAAAAA
12208     *  r9 holds BBBB
12209     */
12210.LOP_INSTANCE_OF_JUMBO_fullcheck:
12211    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
12212    @ fall through to OP_INSTANCE_OF_JUMBO_store
12213
12214    /*
12215     * r0 holds boolean result
12216     * r9 holds BBBB
12217     */
12218.LOP_INSTANCE_OF_JUMBO_store:
12219    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12220    SET_VREG(r0, r9)                    @ vBBBB<- r0
12221    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12222    GOTO_OPCODE(ip)                     @ jump to next instruction
12223
12224    /*
12225     * Trivial test succeeded, save and bail.
12226     *  r9 holds BBBB
12227     */
12228.LOP_INSTANCE_OF_JUMBO_trivial:
12229    mov     r0, #1                      @ indicate success
12230    @ could b OP_INSTANCE_OF_JUMBO_store, but copying is faster and cheaper
12231    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12232    SET_VREG(r0, r9)                    @ vBBBB<- r0
12233    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12234    GOTO_OPCODE(ip)                     @ jump to next instruction
12235
12236    /*
12237     * Resolution required.  This is the least-likely path.
12238     *
12239     *  r3 holds AAAAAAAA
12240     *  r9 holds BBBB
12241     */
12242
12243.LOP_INSTANCE_OF_JUMBO_resolve:
12244    EXPORT_PC()                         @ resolve() could throw
12245    ldr     r0, [rSELF, #offThread_method]    @ r0<- self->method
12246    mov     r1, r3                      @ r1<- AAAAAAAA
12247    mov     r2, #1                      @ r2<- true
12248    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
12249    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12250    cmp     r0, #0                      @ got null?
12251    beq     common_exceptionThrown      @ yes, handle exception
12252    FETCH(r3, 4)                        @ r3<- vCCCC
12253    mov     r1, r0                      @ r1<- class resolved from AAAAAAAA
12254    GET_VREG(r0, r3)                    @ r0<- vCCCC (object)
12255    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
12256    b       .LOP_INSTANCE_OF_JUMBO_resolved        @ pick up where we left off
12257
12258/* continuation for OP_NEW_INSTANCE_JUMBO */
12259
12260    .balign 32                          @ minimize cache lines
12261.LOP_NEW_INSTANCE_JUMBO_finish: @ r0=new object
12262    FETCH(r3, 3)                        @ r3<- BBBB
12263    cmp     r0, #0                      @ failed?
12264    beq     common_exceptionThrown      @ yes, handle the exception
12265    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12266    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12267    SET_VREG(r0, r3)                    @ vBBBB<- r0
12268    GOTO_OPCODE(ip)                     @ jump to next instruction
12269
12270    /*
12271     * Class initialization required.
12272     *
12273     *  r0 holds class object
12274     */
12275.LOP_NEW_INSTANCE_JUMBO_needinit:
12276    mov     r9, r0                      @ save r0
12277    bl      dvmInitClass                @ initialize class
12278    cmp     r0, #0                      @ check boolean result
12279    mov     r0, r9                      @ restore r0
12280    bne     .LOP_NEW_INSTANCE_JUMBO_initialized     @ success, continue
12281    b       common_exceptionThrown      @ failed, deal with init exception
12282
12283    /*
12284     * Resolution required.  This is the least-likely path.
12285     *
12286     *  r1 holds AAAAAAAA
12287     */
12288.LOP_NEW_INSTANCE_JUMBO_resolve:
12289    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
12290    mov     r2, #0                      @ r2<- false
12291    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12292    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
12293    cmp     r0, #0                      @ got null?
12294    bne     .LOP_NEW_INSTANCE_JUMBO_resolved        @ no, continue
12295    b       common_exceptionThrown      @ yes, handle exception
12296
12297/* continuation for OP_NEW_ARRAY_JUMBO */
12298
12299
12300    /*
12301     * Resolve class.  (This is an uncommon case.)
12302     *
12303     *  r1 holds array length
12304     *  r2 holds class ref AAAAAAAA
12305     */
12306.LOP_NEW_ARRAY_JUMBO_resolve:
12307    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
12308    mov     r9, r1                      @ r9<- length (save)
12309    mov     r1, r2                      @ r1<- AAAAAAAA
12310    mov     r2, #0                      @ r2<- false
12311    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
12312    bl      dvmResolveClass             @ r0<- call(clazz, ref)
12313    cmp     r0, #0                      @ got null?
12314    mov     r1, r9                      @ r1<- length (restore)
12315    beq     common_exceptionThrown      @ yes, handle exception
12316    @ fall through to OP_NEW_ARRAY_JUMBO_finish
12317
12318    /*
12319     * Finish allocation.
12320     *
12321     *  r0 holds class
12322     *  r1 holds array length
12323     */
12324.LOP_NEW_ARRAY_JUMBO_finish:
12325    mov     r2, #ALLOC_DONT_TRACK       @ don't track in local refs table
12326    bl      dvmAllocArrayByClass        @ r0<- call(clazz, length, flags)
12327    cmp     r0, #0                      @ failed?
12328    FETCH(r2, 3)                        @ r2<- vBBBB
12329    beq     common_exceptionThrown      @ yes, handle the exception
12330    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12331    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12332    SET_VREG(r0, r2)                    @ vBBBB<- r0
12333    GOTO_OPCODE(ip)                     @ jump to next instruction
12334
12335/* continuation for OP_FILLED_NEW_ARRAY_JUMBO */
12336
12337    /*
12338     * On entry:
12339     *  r0 holds array class
12340     */
12341.LOP_FILLED_NEW_ARRAY_JUMBO_continue:
12342    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
12343    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
12344    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
12345    FETCH(r1, 3)                        @ r1<- BBBB (length)
12346    cmp     rINST, #'I'                 @ array of ints?
12347    cmpne   rINST, #'L'                 @ array of objects?
12348    cmpne   rINST, #'['                 @ array of arrays?
12349    mov     r9, r1                      @ save length in r9
12350    bne     .LOP_FILLED_NEW_ARRAY_JUMBO_notimpl         @ no, not handled yet
12351    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
12352    cmp     r0, #0                      @ null return?
12353    beq     common_exceptionThrown      @ alloc failed, handle exception
12354
12355    FETCH(r1, 4)                        @ r1<- CCCC
12356    str     r0, [rSELF, #offThread_retval]      @ retval.l <- new array
12357    str     rINST, [rSELF, #offThread_retval+4] @ retval.h <- type
12358    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
12359    subs    r9, r9, #1                  @ length--, check for neg
12360    FETCH_ADVANCE_INST(5)               @ advance to next instr, load rINST
12361    bmi     2f                          @ was zero, bail
12362
12363    @ copy values from registers into the array
12364    @ r0=array, r1=CCCC, r9=BBBB (length)
12365    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
123661:  ldr     r3, [r2], #4                @ r3<- *r2++
12367    subs    r9, r9, #1                  @ count--
12368    str     r3, [r0], #4                @ *contents++ = vX
12369    bpl     1b
12370
123712:  ldr     r0, [rSELF, #offThread_retval]     @ r0<- object
12372    ldr     r1, [rSELF, #offThread_retval+4]   @ r1<- type
12373    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
12374    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
12375    cmp     r1, #'I'                         @ Is int array?
12376    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
12377    GOTO_OPCODE(ip)                          @ execute it
12378
12379    /*
12380     * Throw an exception indicating that we have not implemented this
12381     * mode of filled-new-array.
12382     */
12383.LOP_FILLED_NEW_ARRAY_JUMBO_notimpl:
12384    ldr     r0, .L_strInternalError
12385    ldr     r1, .L_strFilledNewArrayNotImpl
12386    bl      dvmThrowException
12387    b       common_exceptionThrown
12388
12389/* continuation for OP_IGET_JUMBO */
12390
12391    /*
12392     * Currently:
12393     *  r0 holds resolved field
12394     *  r9 holds object
12395     */
12396.LOP_IGET_JUMBO_resolved:
12397    cmp     r0, #0                      @ resolution unsuccessful?
12398    beq     common_exceptionThrown      @ yes, throw exception
12399    @ fall through to OP_IGET_JUMBO_finish
12400
12401    /*
12402     * Currently:
12403     *  r0 holds resolved field
12404     *  r9 holds object
12405     */
12406.LOP_IGET_JUMBO_finish:
12407    @bl      common_squeak0
12408    cmp     r9, #0                      @ check object for null
12409    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12410    beq     common_errNullObject        @ object was null
12411    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12412    @ no-op                             @ acquiring load
12413    FETCH(r2, 3)                        @ r2<- BBBB
12414    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12415    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12416    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12417    GOTO_OPCODE(ip)                     @ jump to next instruction
12418
12419/* continuation for OP_IGET_WIDE_JUMBO */
12420
12421    /*
12422     * Currently:
12423     *  r0 holds resolved field
12424     *  r9 holds object
12425     */
12426.LOP_IGET_WIDE_JUMBO_resolved:
12427    cmp     r0, #0                      @ resolution unsuccessful?
12428    beq     common_exceptionThrown      @ yes, throw exception
12429    @ fall through to OP_IGET_WIDE_JUMBO_finish
12430
12431    /*
12432     * Currently:
12433     *  r0 holds resolved field
12434     *  r9 holds object
12435     */
12436.LOP_IGET_WIDE_JUMBO_finish:
12437    cmp     r9, #0                      @ check object for null
12438    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12439    beq     common_errNullObject        @ object was null
12440    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
12441    FETCH(r2, 3)                        @ r2<- BBBB
12442    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12443    add     r3, rFP, r2, lsl #2         @ r3<- &fp[BBBB]
12444    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12445    stmia   r3, {r0-r1}                 @ fp[BBBB]<- r0/r1
12446    GOTO_OPCODE(ip)                     @ jump to next instruction
12447
12448/* continuation for OP_IGET_OBJECT_JUMBO */
12449
12450    /*
12451     * Currently:
12452     *  r0 holds resolved field
12453     *  r9 holds object
12454     */
12455.LOP_IGET_OBJECT_JUMBO_resolved:
12456    cmp     r0, #0                      @ resolution unsuccessful?
12457    beq     common_exceptionThrown      @ yes, throw exception
12458    @ fall through to OP_IGET_OBJECT_JUMBO_finish
12459
12460    /*
12461     * Currently:
12462     *  r0 holds resolved field
12463     *  r9 holds object
12464     */
12465.LOP_IGET_OBJECT_JUMBO_finish:
12466    @bl      common_squeak0
12467    cmp     r9, #0                      @ check object for null
12468    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12469    beq     common_errNullObject        @ object was null
12470    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12471    @ no-op                             @ acquiring load
12472    FETCH(r2, 3)                        @ r2<- BBBB
12473    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12474    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12475    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12476    GOTO_OPCODE(ip)                     @ jump to next instruction
12477
12478/* continuation for OP_IGET_BOOLEAN_JUMBO */
12479
12480    /*
12481     * Currently:
12482     *  r0 holds resolved field
12483     *  r9 holds object
12484     */
12485.LOP_IGET_BOOLEAN_JUMBO_resolved:
12486    cmp     r0, #0                      @ resolution unsuccessful?
12487    beq     common_exceptionThrown      @ yes, throw exception
12488    @ fall through to OP_IGET_BOOLEAN_JUMBO_finish
12489
12490    /*
12491     * Currently:
12492     *  r0 holds resolved field
12493     *  r9 holds object
12494     */
12495.LOP_IGET_BOOLEAN_JUMBO_finish:
12496    @bl      common_squeak1
12497    cmp     r9, #0                      @ check object for null
12498    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12499    beq     common_errNullObject        @ object was null
12500    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12501    @ no-op                             @ acquiring load
12502    FETCH(r2, 3)                        @ r2<- BBBB
12503    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12504    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12505    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12506    GOTO_OPCODE(ip)                     @ jump to next instruction
12507
12508/* continuation for OP_IGET_BYTE_JUMBO */
12509
12510    /*
12511     * Currently:
12512     *  r0 holds resolved field
12513     *  r9 holds object
12514     */
12515.LOP_IGET_BYTE_JUMBO_resolved:
12516    cmp     r0, #0                      @ resolution unsuccessful?
12517    beq     common_exceptionThrown      @ yes, throw exception
12518    @ fall through to OP_IGET_BYTE_JUMBO_finish
12519
12520    /*
12521     * Currently:
12522     *  r0 holds resolved field
12523     *  r9 holds object
12524     */
12525.LOP_IGET_BYTE_JUMBO_finish:
12526    @bl      common_squeak2
12527    cmp     r9, #0                      @ check object for null
12528    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12529    beq     common_errNullObject        @ object was null
12530    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12531    @ no-op                             @ acquiring load
12532    FETCH(r2, 3)                        @ r2<- BBBB
12533    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12534    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12535    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12536    GOTO_OPCODE(ip)                     @ jump to next instruction
12537
12538/* continuation for OP_IGET_CHAR_JUMBO */
12539
12540    /*
12541     * Currently:
12542     *  r0 holds resolved field
12543     *  r9 holds object
12544     */
12545.LOP_IGET_CHAR_JUMBO_resolved:
12546    cmp     r0, #0                      @ resolution unsuccessful?
12547    beq     common_exceptionThrown      @ yes, throw exception
12548    @ fall through to OP_IGET_CHAR_JUMBO_finish
12549
12550    /*
12551     * Currently:
12552     *  r0 holds resolved field
12553     *  r9 holds object
12554     */
12555.LOP_IGET_CHAR_JUMBO_finish:
12556    @bl      common_squeak3
12557    cmp     r9, #0                      @ check object for null
12558    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12559    beq     common_errNullObject        @ object was null
12560    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12561    @ no-op                             @ acquiring load
12562    FETCH(r2, 3)                        @ r2<- BBBB
12563    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12564    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12565    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12566    GOTO_OPCODE(ip)                     @ jump to next instruction
12567
12568/* continuation for OP_IGET_SHORT_JUMBO */
12569
12570    /*
12571     * Currently:
12572     *  r0 holds resolved field
12573     *  r9 holds object
12574     */
12575.LOP_IGET_SHORT_JUMBO_resolved:
12576    cmp     r0, #0                      @ resolution unsuccessful?
12577    beq     common_exceptionThrown      @ yes, throw exception
12578    @ fall through to OP_IGET_SHORT_JUMBO_finish
12579
12580    /*
12581     * Currently:
12582     *  r0 holds resolved field
12583     *  r9 holds object
12584     */
12585.LOP_IGET_SHORT_JUMBO_finish:
12586    @bl      common_squeak4
12587    cmp     r9, #0                      @ check object for null
12588    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12589    beq     common_errNullObject        @ object was null
12590    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
12591    @ no-op                             @ acquiring load
12592    FETCH(r2, 3)                        @ r2<- BBBB
12593    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12594    SET_VREG(r0, r2)                    @ fp[BBBB]<- r0
12595    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12596    GOTO_OPCODE(ip)                     @ jump to next instruction
12597
12598/* continuation for OP_IPUT_JUMBO */
12599
12600    /*
12601     * Currently:
12602     *  r0 holds resolved field
12603     *  r9 holds object
12604     */
12605.LOP_IPUT_JUMBO_resolved:
12606     cmp     r0, #0                     @ resolution unsuccessful?
12607     beq     common_exceptionThrown     @ yes, throw exception
12608     @ fall through to OP_IPUT_JUMBO_finish
12609
12610    /*
12611     * Currently:
12612     *  r0 holds resolved field
12613     *  r9 holds object
12614     */
12615.LOP_IPUT_JUMBO_finish:
12616    @bl      common_squeak0
12617    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12618    FETCH(r1, 3)                        @ r1<- BBBB
12619    cmp     r9, #0                      @ check object for null
12620    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12621    beq     common_errNullObject        @ object was null
12622    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12623    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12624    @ no-op                             @ releasing store
12625    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12626    GOTO_OPCODE(ip)                     @ jump to next instruction
12627
12628/* continuation for OP_IPUT_WIDE_JUMBO */
12629
12630    /*
12631     * Currently:
12632     *  r0 holds resolved field
12633     *  r9 holds object
12634     */
12635.LOP_IPUT_WIDE_JUMBO_resolved:
12636     cmp     r0, #0                     @ resolution unsuccessful?
12637     beq     common_exceptionThrown     @ yes, throw exception
12638     @ fall through to OP_IPUT_WIDE_JUMBO_finish
12639
12640    /*
12641     * Currently:
12642     *  r0 holds resolved field
12643     *  r9 holds object
12644     */
12645.LOP_IPUT_WIDE_JUMBO_finish:
12646    cmp     r9, #0                      @ check object for null
12647    FETCH(r2, 3)                        @ r1<- BBBB
12648    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12649    add     r2, rFP, r2, lsl #2         @ r3<- &fp[BBBB]
12650    beq     common_errNullObject        @ object was null
12651    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12652    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[BBBB]
12653    GET_INST_OPCODE(r10)                @ extract opcode from rINST
12654    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
12655    GOTO_OPCODE(r10)                    @ jump to next instruction
12656
12657/* continuation for OP_IPUT_OBJECT_JUMBO */
12658
12659    /*
12660     * Currently:
12661     *  r0 holds resolved field
12662     *  r9 holds object
12663     */
12664.LOP_IPUT_OBJECT_JUMBO_resolved:
12665     cmp     r0, #0                     @ resolution unsuccessful?
12666     beq     common_exceptionThrown     @ yes, throw exception
12667     @ fall through to OP_IPUT_OBJECT_JUMBO_finish
12668
12669    /*
12670     * Currently:
12671     *  r0 holds resolved field
12672     *  r9 holds object
12673     */
12674.LOP_IPUT_OBJECT_JUMBO_finish:
12675    @bl      common_squeak0
12676    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12677    FETCH(r1, 3)                        @ r1<- BBBB
12678    cmp     r9, #0                      @ check object for null
12679    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12680    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
12681    beq     common_errNullObject        @ object was null
12682    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12683    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12684    @ no-op                             @ releasing store
12685    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
12686    cmp     r0, #0                      @ stored a null reference?
12687    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
12688    GOTO_OPCODE(ip)                     @ jump to next instruction
12689
12690/* continuation for OP_IPUT_BOOLEAN_JUMBO */
12691
12692    /*
12693     * Currently:
12694     *  r0 holds resolved field
12695     *  r9 holds object
12696     */
12697.LOP_IPUT_BOOLEAN_JUMBO_resolved:
12698     cmp     r0, #0                     @ resolution unsuccessful?
12699     beq     common_exceptionThrown     @ yes, throw exception
12700     @ fall through to OP_IPUT_BOOLEAN_JUMBO_finish
12701
12702    /*
12703     * Currently:
12704     *  r0 holds resolved field
12705     *  r9 holds object
12706     */
12707.LOP_IPUT_BOOLEAN_JUMBO_finish:
12708    @bl      common_squeak1
12709    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12710    FETCH(r1, 3)                        @ r1<- BBBB
12711    cmp     r9, #0                      @ check object for null
12712    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12713    beq     common_errNullObject        @ object was null
12714    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12715    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12716    @ no-op                             @ releasing store
12717    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12718    GOTO_OPCODE(ip)                     @ jump to next instruction
12719
12720/* continuation for OP_IPUT_BYTE_JUMBO */
12721
12722    /*
12723     * Currently:
12724     *  r0 holds resolved field
12725     *  r9 holds object
12726     */
12727.LOP_IPUT_BYTE_JUMBO_resolved:
12728     cmp     r0, #0                     @ resolution unsuccessful?
12729     beq     common_exceptionThrown     @ yes, throw exception
12730     @ fall through to OP_IPUT_BYTE_JUMBO_finish
12731
12732    /*
12733     * Currently:
12734     *  r0 holds resolved field
12735     *  r9 holds object
12736     */
12737.LOP_IPUT_BYTE_JUMBO_finish:
12738    @bl      common_squeak2
12739    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12740    FETCH(r1, 3)                        @ r1<- BBBB
12741    cmp     r9, #0                      @ check object for null
12742    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
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 (8/16/32 bits)<- r0
12748    GOTO_OPCODE(ip)                     @ jump to next instruction
12749
12750/* continuation for OP_IPUT_CHAR_JUMBO */
12751
12752    /*
12753     * Currently:
12754     *  r0 holds resolved field
12755     *  r9 holds object
12756     */
12757.LOP_IPUT_CHAR_JUMBO_resolved:
12758     cmp     r0, #0                     @ resolution unsuccessful?
12759     beq     common_exceptionThrown     @ yes, throw exception
12760     @ fall through to OP_IPUT_CHAR_JUMBO_finish
12761
12762    /*
12763     * Currently:
12764     *  r0 holds resolved field
12765     *  r9 holds object
12766     */
12767.LOP_IPUT_CHAR_JUMBO_finish:
12768    @bl      common_squeak3
12769    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12770    FETCH(r1, 3)                        @ r1<- BBBB
12771    cmp     r9, #0                      @ check object for null
12772    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12773    beq     common_errNullObject        @ object was null
12774    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12775    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12776    @ no-op                             @ releasing store
12777    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12778    GOTO_OPCODE(ip)                     @ jump to next instruction
12779
12780/* continuation for OP_IPUT_SHORT_JUMBO */
12781
12782    /*
12783     * Currently:
12784     *  r0 holds resolved field
12785     *  r9 holds object
12786     */
12787.LOP_IPUT_SHORT_JUMBO_resolved:
12788     cmp     r0, #0                     @ resolution unsuccessful?
12789     beq     common_exceptionThrown     @ yes, throw exception
12790     @ fall through to OP_IPUT_SHORT_JUMBO_finish
12791
12792    /*
12793     * Currently:
12794     *  r0 holds resolved field
12795     *  r9 holds object
12796     */
12797.LOP_IPUT_SHORT_JUMBO_finish:
12798    @bl      common_squeak4
12799    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
12800    FETCH(r1, 3)                        @ r1<- BBBB
12801    cmp     r9, #0                      @ check object for null
12802    GET_VREG(r0, r1)                    @ r0<- fp[BBBB]
12803    beq     common_errNullObject        @ object was null
12804    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
12805    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12806    @ no-op                             @ releasing store
12807    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
12808    GOTO_OPCODE(ip)                     @ jump to next instruction
12809
12810/* continuation for OP_SGET_JUMBO */
12811
12812    /*
12813     * Continuation if the field has not yet been resolved.
12814     *  r1: AAAAAAAA field ref
12815     */
12816.LOP_SGET_JUMBO_resolve:
12817    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12818    EXPORT_PC()                         @ resolve() could throw, so export now
12819    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12820    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12821    cmp     r0, #0                      @ success?
12822    bne     .LOP_SGET_JUMBO_finish          @ yes, finish
12823    b       common_exceptionThrown      @ no, handle exception
12824
12825/* continuation for OP_SGET_WIDE_JUMBO */
12826
12827    /*
12828     * Continuation if the field has not yet been resolved.
12829     *  r1: BBBB field ref
12830     *
12831     * Returns StaticField pointer in r0.
12832     */
12833.LOP_SGET_WIDE_JUMBO_resolve:
12834    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12835    EXPORT_PC()                         @ resolve() could throw, so export now
12836    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12837    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12838    cmp     r0, #0                      @ success?
12839    bne     .LOP_SGET_WIDE_JUMBO_finish          @ yes, finish
12840    b       common_exceptionThrown      @ no, handle exception
12841
12842/* continuation for OP_SGET_OBJECT_JUMBO */
12843
12844    /*
12845     * Continuation if the field has not yet been resolved.
12846     *  r1: AAAAAAAA field ref
12847     */
12848.LOP_SGET_OBJECT_JUMBO_resolve:
12849    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12850    EXPORT_PC()                         @ resolve() could throw, so export now
12851    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12852    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12853    cmp     r0, #0                      @ success?
12854    bne     .LOP_SGET_OBJECT_JUMBO_finish          @ yes, finish
12855    b       common_exceptionThrown      @ no, handle exception
12856
12857/* continuation for OP_SGET_BOOLEAN_JUMBO */
12858
12859    /*
12860     * Continuation if the field has not yet been resolved.
12861     *  r1: AAAAAAAA field ref
12862     */
12863.LOP_SGET_BOOLEAN_JUMBO_resolve:
12864    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12865    EXPORT_PC()                         @ resolve() could throw, so export now
12866    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12867    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12868    cmp     r0, #0                      @ success?
12869    bne     .LOP_SGET_BOOLEAN_JUMBO_finish          @ yes, finish
12870    b       common_exceptionThrown      @ no, handle exception
12871
12872/* continuation for OP_SGET_BYTE_JUMBO */
12873
12874    /*
12875     * Continuation if the field has not yet been resolved.
12876     *  r1: AAAAAAAA field ref
12877     */
12878.LOP_SGET_BYTE_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_BYTE_JUMBO_finish          @ yes, finish
12885    b       common_exceptionThrown      @ no, handle exception
12886
12887/* continuation for OP_SGET_CHAR_JUMBO */
12888
12889    /*
12890     * Continuation if the field has not yet been resolved.
12891     *  r1: AAAAAAAA field ref
12892     */
12893.LOP_SGET_CHAR_JUMBO_resolve:
12894    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12895    EXPORT_PC()                         @ resolve() could throw, so export now
12896    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12897    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12898    cmp     r0, #0                      @ success?
12899    bne     .LOP_SGET_CHAR_JUMBO_finish          @ yes, finish
12900    b       common_exceptionThrown      @ no, handle exception
12901
12902/* continuation for OP_SGET_SHORT_JUMBO */
12903
12904    /*
12905     * Continuation if the field has not yet been resolved.
12906     *  r1: AAAAAAAA field ref
12907     */
12908.LOP_SGET_SHORT_JUMBO_resolve:
12909    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12910    EXPORT_PC()                         @ resolve() could throw, so export now
12911    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12912    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12913    cmp     r0, #0                      @ success?
12914    bne     .LOP_SGET_SHORT_JUMBO_finish          @ yes, finish
12915    b       common_exceptionThrown      @ no, handle exception
12916
12917/* continuation for OP_SPUT_JUMBO */
12918
12919    /*
12920     * Continuation if the field has not yet been resolved.
12921     *  r1: AAAAAAAA field ref
12922     */
12923.LOP_SPUT_JUMBO_resolve:
12924    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12925    EXPORT_PC()                         @ resolve() could throw, so export now
12926    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12927    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12928    cmp     r0, #0                      @ success?
12929    bne     .LOP_SPUT_JUMBO_finish          @ yes, finish
12930    b       common_exceptionThrown      @ no, handle exception
12931
12932/* continuation for OP_SPUT_WIDE_JUMBO */
12933
12934    /*
12935     * Continuation if the field has not yet been resolved.
12936     *  r1: BBBB field ref
12937     *  r9: &fp[AA]
12938     *
12939     * Returns StaticField pointer in r2.
12940     */
12941.LOP_SPUT_WIDE_JUMBO_resolve:
12942    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12943    EXPORT_PC()                         @ resolve() could throw, so export now
12944    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12945    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12946    cmp     r0, #0                      @ success?
12947    mov     r2, r0                      @ copy to r2
12948    bne     .LOP_SPUT_WIDE_JUMBO_finish          @ yes, finish
12949    b       common_exceptionThrown      @ no, handle exception
12950
12951/* continuation for OP_SPUT_OBJECT_JUMBO */
12952
12953.LOP_SPUT_OBJECT_JUMBO_finish:   @ field ptr in r0
12954    FETCH(r2, 3)                        @ r2<- BBBB
12955    FETCH_ADVANCE_INST(4)               @ advance rPC, load rINST
12956    GET_VREG(r1, r2)                    @ r1<- fp[BBBB]
12957    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
12958    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
12959    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
12960    @ no-op                             @ releasing store
12961    str     r1, [r0, #offStaticField_value]  @ field<- vBBBB
12962    cmp     r1, #0                      @ stored a null object?
12963    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
12964    GOTO_OPCODE(ip)                     @ jump to next instruction
12965
12966/* continuation for OP_SPUT_BOOLEAN_JUMBO */
12967
12968    /*
12969     * Continuation if the field has not yet been resolved.
12970     *  r1: AAAAAAAA field ref
12971     */
12972.LOP_SPUT_BOOLEAN_JUMBO_resolve:
12973    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12974    EXPORT_PC()                         @ resolve() could throw, so export now
12975    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12976    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12977    cmp     r0, #0                      @ success?
12978    bne     .LOP_SPUT_BOOLEAN_JUMBO_finish          @ yes, finish
12979    b       common_exceptionThrown      @ no, handle exception
12980
12981/* continuation for OP_SPUT_BYTE_JUMBO */
12982
12983    /*
12984     * Continuation if the field has not yet been resolved.
12985     *  r1: AAAAAAAA field ref
12986     */
12987.LOP_SPUT_BYTE_JUMBO_resolve:
12988    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
12989    EXPORT_PC()                         @ resolve() could throw, so export now
12990    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
12991    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
12992    cmp     r0, #0                      @ success?
12993    bne     .LOP_SPUT_BYTE_JUMBO_finish          @ yes, finish
12994    b       common_exceptionThrown      @ no, handle exception
12995
12996/* continuation for OP_SPUT_CHAR_JUMBO */
12997
12998    /*
12999     * Continuation if the field has not yet been resolved.
13000     *  r1: AAAAAAAA field ref
13001     */
13002.LOP_SPUT_CHAR_JUMBO_resolve:
13003    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
13004    EXPORT_PC()                         @ resolve() could throw, so export now
13005    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13006    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13007    cmp     r0, #0                      @ success?
13008    bne     .LOP_SPUT_CHAR_JUMBO_finish          @ yes, finish
13009    b       common_exceptionThrown      @ no, handle exception
13010
13011/* continuation for OP_SPUT_SHORT_JUMBO */
13012
13013    /*
13014     * Continuation if the field has not yet been resolved.
13015     *  r1: AAAAAAAA field ref
13016     */
13017.LOP_SPUT_SHORT_JUMBO_resolve:
13018    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
13019    EXPORT_PC()                         @ resolve() could throw, so export now
13020    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
13021    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
13022    cmp     r0, #0                      @ success?
13023    bne     .LOP_SPUT_SHORT_JUMBO_finish          @ yes, finish
13024    b       common_exceptionThrown      @ no, handle exception
13025
13026/* continuation for OP_INVOKE_VIRTUAL_JUMBO */
13027
13028    /*
13029     * At this point:
13030     *  r0 = resolved base method
13031     */
13032.LOP_INVOKE_VIRTUAL_JUMBO_continue:
13033    FETCH(r10, 4)                       @ r10<- CCCC
13034    GET_VREG(r1, r10)                   @ r1<- "this" ptr
13035    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
13036    cmp     r1, #0                      @ is "this" null?
13037    beq     common_errNullObject        @ null "this", throw exception
13038    ldr     r3, [r1, #offObject_clazz]  @ r1<- thisPtr->clazz
13039    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
13040    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
13041    bl      common_invokeMethodJumbo    @ continue on
13042
13043/* continuation for OP_INVOKE_SUPER_JUMBO */
13044
13045    /*
13046     * At this point:
13047     *  r0 = resolved base method
13048     *  r9 = method->clazz
13049     */
13050.LOP_INVOKE_SUPER_JUMBO_continue:
13051    ldr     r1, [r9, #offClassObject_super]     @ r1<- method->clazz->super
13052    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
13053    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
13054    EXPORT_PC()                         @ must export for invoke
13055    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
13056    bcs     .LOP_INVOKE_SUPER_JUMBO_nsm             @ method not present in superclass
13057    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
13058    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
13059    bl      common_invokeMethodJumbo    @ continue on
13060
13061.LOP_INVOKE_SUPER_JUMBO_resolve:
13062    mov     r0, r9                      @ r0<- method->clazz
13063    mov     r2, #METHOD_VIRTUAL         @ resolver method type
13064    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
13065    cmp     r0, #0                      @ got null?
13066    bne     .LOP_INVOKE_SUPER_JUMBO_continue        @ no, continue
13067    b       common_exceptionThrown      @ yes, handle exception
13068
13069    /*
13070     * Throw a NoSuchMethodError with the method name as the message.
13071     *  r0 = resolved base method
13072     */
13073.LOP_INVOKE_SUPER_JUMBO_nsm:
13074    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
13075    b       common_errNoSuchMethod
13076
13077/* continuation for OP_INVOKE_DIRECT_JUMBO */
13078
13079    /*
13080     * On entry:
13081     *  r1 = reference (CCCC)
13082     *  r10 = "this" register
13083     */
13084.LOP_INVOKE_DIRECT_JUMBO_resolve:
13085    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
13086    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
13087    mov     r2, #METHOD_DIRECT          @ resolver method type
13088    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
13089    cmp     r0, #0                      @ got null?
13090    GET_VREG(r2, r10)                   @ r2<- "this" ptr (reload)
13091    bne     .LOP_INVOKE_DIRECT_JUMBO_finish          @ no, continue
13092    b       common_exceptionThrown      @ yes, handle exception
13093
13094    .size   dvmAsmSisterStart, .-dvmAsmSisterStart
13095    .global dvmAsmSisterEnd
13096dvmAsmSisterEnd:
13097
13098/* File: armv5te/footer.S */
13099
13100/*
13101 * ===========================================================================
13102 *  Common subroutines and data
13103 * ===========================================================================
13104 */
13105
13106
13107
13108    .text
13109    .align  2
13110
13111#if defined(WITH_JIT)
13112#if defined(WITH_SELF_VERIFICATION)
13113    .global dvmJitToInterpPunt
13114dvmJitToInterpPunt:
13115    mov    r2,#kSVSPunt                 @ r2<- interpreter entry point
13116    mov    r3, #0
13117    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
13118    b      jitSVShadowRunEnd            @ doesn't return
13119
13120    .global dvmJitToInterpSingleStep
13121dvmJitToInterpSingleStep:
13122    str    lr,[rSELF,#offThread_jitResumeNPC]
13123    str    r1,[rSELF,#offThread_jitResumeDPC]
13124    mov    r2,#kSVSSingleStep           @ r2<- interpreter entry point
13125    b      jitSVShadowRunEnd            @ doesn't return
13126
13127    .global dvmJitToInterpNoChainNoProfile
13128dvmJitToInterpNoChainNoProfile:
13129    mov    r0,rPC                       @ pass our target PC
13130    mov    r2,#kSVSNoProfile            @ r2<- interpreter entry point
13131    mov    r3, #0                       @ 0 means !inJitCodeCache
13132    str    r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land
13133    b      jitSVShadowRunEnd            @ doesn't return
13134
13135    .global dvmJitToInterpTraceSelectNoChain
13136dvmJitToInterpTraceSelectNoChain:
13137    mov    r0,rPC                       @ pass our target PC
13138    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
13139    mov    r3, #0                       @ 0 means !inJitCodeCache
13140    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
13141    b      jitSVShadowRunEnd            @ doesn't return
13142
13143    .global dvmJitToInterpTraceSelect
13144dvmJitToInterpTraceSelect:
13145    ldr    r0,[lr, #-1]                 @ pass our target PC
13146    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
13147    mov    r3, #0                       @ 0 means !inJitCodeCache
13148    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
13149    b      jitSVShadowRunEnd            @ doesn't return
13150
13151    .global dvmJitToInterpBackwardBranch
13152dvmJitToInterpBackwardBranch:
13153    ldr    r0,[lr, #-1]                 @ pass our target PC
13154    mov    r2,#kSVSBackwardBranch       @ r2<- interpreter entry point
13155    mov    r3, #0                       @ 0 means !inJitCodeCache
13156    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
13157    b      jitSVShadowRunEnd            @ doesn't return
13158
13159    .global dvmJitToInterpNormal
13160dvmJitToInterpNormal:
13161    ldr    r0,[lr, #-1]                 @ pass our target PC
13162    mov    r2,#kSVSNormal               @ r2<- interpreter entry point
13163    mov    r3, #0                       @ 0 means !inJitCodeCache
13164    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
13165    b      jitSVShadowRunEnd            @ doesn't return
13166
13167    .global dvmJitToInterpNoChain
13168dvmJitToInterpNoChain:
13169    mov    r0,rPC                       @ pass our target PC
13170    mov    r2,#kSVSNoChain              @ r2<- interpreter entry point
13171    mov    r3, #0                       @ 0 means !inJitCodeCache
13172    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
13173    b      jitSVShadowRunEnd            @ doesn't return
13174#else
13175/*
13176 * Return from the translation cache to the interpreter when the compiler is
13177 * having issues translating/executing a Dalvik instruction. We have to skip
13178 * the code cache lookup otherwise it is possible to indefinitely bouce
13179 * between the interpreter and the code cache if the instruction that fails
13180 * to be compiled happens to be at a trace start.
13181 */
13182    .global dvmJitToInterpPunt
13183dvmJitToInterpPunt:
13184    mov    rPC, r0
13185#if defined(WITH_JIT_TUNING)
13186    mov    r0,lr
13187    bl     dvmBumpPunt;
13188#endif
13189    EXPORT_PC()
13190    mov    r0, #0
13191    str    r0, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
13192    adrl   rIBASE, dvmAsmInstructionStart
13193    FETCH_INST()
13194    GET_INST_OPCODE(ip)
13195    GOTO_OPCODE(ip)
13196
13197/*
13198 * Return to the interpreter to handle a single instruction.
13199 * On entry:
13200 *    r0 <= PC
13201 *    r1 <= PC of resume instruction
13202 *    lr <= resume point in translation
13203 */
13204    .global dvmJitToInterpSingleStep
13205dvmJitToInterpSingleStep:
13206    str    lr,[rSELF,#offThread_jitResumeNPC]
13207    str    r1,[rSELF,#offThread_jitResumeDPC]
13208    mov    r1,#kInterpEntryInstr
13209    @ enum is 4 byte in aapcs-EABI
13210    str    r1, [rSELF, #offThread_entryPoint]
13211    mov    rPC,r0
13212    EXPORT_PC()
13213
13214    adrl   rIBASE, dvmAsmInstructionStart
13215    mov    r2,#kJitSingleStep     @ Ask for single step and then revert
13216    str    r2,[rSELF,#offThread_jitState]
13217    mov    r1,#1                  @ set changeInterp to bail to debug interp
13218    b      common_gotoBail
13219
13220/*
13221 * Return from the translation cache and immediately request
13222 * a translation for the exit target.  Commonly used for callees.
13223 */
13224    .global dvmJitToInterpTraceSelectNoChain
13225dvmJitToInterpTraceSelectNoChain:
13226#if defined(WITH_JIT_TUNING)
13227    bl     dvmBumpNoChain
13228#endif
13229    mov    r0,rPC
13230    bl     dvmJitGetTraceAddr       @ Is there a translation?
13231    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13232    mov    r1, rPC                  @ arg1 of translation may need this
13233    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13234    cmp    r0,#0                    @ !0 means translation exists
13235    bxne   r0                       @ continue native execution if so
13236    b      2f                       @ branch over to use the interpreter
13237
13238/*
13239 * Return from the translation cache and immediately request
13240 * a translation for the exit target.  Commonly used following
13241 * invokes.
13242 */
13243    .global dvmJitToInterpTraceSelect
13244dvmJitToInterpTraceSelect:
13245    ldr    rPC,[lr, #-1]           @ get our target PC
13246    add    rINST,lr,#-5            @ save start of chain branch
13247    add    rINST, #-4              @  .. which is 9 bytes back
13248    mov    r0,rPC
13249    bl     dvmJitGetTraceAddr      @ Is there a translation?
13250    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13251    cmp    r0,#0
13252    beq    2f
13253    mov    r1,rINST
13254    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
13255    mov    r1, rPC                  @ arg1 of translation may need this
13256    mov    lr, #0                   @ in case target is HANDLER_INTERPRET
13257    cmp    r0,#0                    @ successful chain?
13258    bxne   r0                       @ continue native execution
13259    b      toInterpreter            @ didn't chain - resume with interpreter
13260
13261/* No translation, so request one if profiling isn't disabled*/
132622:
13263    adrl   rIBASE, dvmAsmInstructionStart
13264    GET_JIT_PROF_TABLE(r0)
13265    FETCH_INST()
13266    cmp    r0, #0
13267    movne  r2,#kJitTSelectRequestHot   @ ask for trace selection
13268    bne    common_selectTrace
13269    GET_INST_OPCODE(ip)
13270    GOTO_OPCODE(ip)
13271
13272/*
13273 * Return from the translation cache to the interpreter.
13274 * The return was done with a BLX from thumb mode, and
13275 * the following 32-bit word contains the target rPC value.
13276 * Note that lr (r14) will have its low-order bit set to denote
13277 * its thumb-mode origin.
13278 *
13279 * We'll need to stash our lr origin away, recover the new
13280 * target and then check to see if there is a translation available
13281 * for our new target.  If so, we do a translation chain and
13282 * go back to native execution.  Otherwise, it's back to the
13283 * interpreter (after treating this entry as a potential
13284 * trace start).
13285 */
13286    .global dvmJitToInterpNormal
13287dvmJitToInterpNormal:
13288    ldr    rPC,[lr, #-1]           @ get our target PC
13289    add    rINST,lr,#-5            @ save start of chain branch
13290    add    rINST,#-4               @ .. which is 9 bytes back
13291#if defined(WITH_JIT_TUNING)
13292    bl     dvmBumpNormal
13293#endif
13294    mov    r0,rPC
13295    bl     dvmJitGetTraceAddr      @ Is there a translation?
13296    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13297    cmp    r0,#0
13298    beq    toInterpreter            @ go if not, otherwise do chain
13299    mov    r1,rINST
13300    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
13301    mov    r1, rPC                  @ arg1 of translation may need this
13302    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13303    cmp    r0,#0                    @ successful chain?
13304    bxne   r0                       @ continue native execution
13305    b      toInterpreter            @ didn't chain - resume with interpreter
13306
13307/*
13308 * Return from the translation cache to the interpreter to do method invocation.
13309 * Check if translation exists for the callee, but don't chain to it.
13310 */
13311    .global dvmJitToInterpNoChainNoProfile
13312dvmJitToInterpNoChainNoProfile:
13313#if defined(WITH_JIT_TUNING)
13314    bl     dvmBumpNoChain
13315#endif
13316    mov    r0,rPC
13317    bl     dvmJitGetTraceAddr       @ Is there a translation?
13318    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13319    mov    r1, rPC                  @ arg1 of translation may need this
13320    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13321    cmp    r0,#0
13322    bxne   r0                       @ continue native execution if so
13323    EXPORT_PC()
13324    adrl   rIBASE, dvmAsmInstructionStart
13325    FETCH_INST()
13326    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13327    GOTO_OPCODE(ip)                     @ jump to next instruction
13328
13329/*
13330 * Return from the translation cache to the interpreter to do method invocation.
13331 * Check if translation exists for the callee, but don't chain to it.
13332 */
13333    .global dvmJitToInterpNoChain
13334dvmJitToInterpNoChain:
13335#if defined(WITH_JIT_TUNING)
13336    bl     dvmBumpNoChain
13337#endif
13338    mov    r0,rPC
13339    bl     dvmJitGetTraceAddr       @ Is there a translation?
13340    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13341    mov    r1, rPC                  @ arg1 of translation may need this
13342    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
13343    cmp    r0,#0
13344    bxne   r0                       @ continue native execution if so
13345#endif
13346
13347/*
13348 * No translation, restore interpreter regs and start interpreting.
13349 * rSELF & rFP were preserved in the translated code, and rPC has
13350 * already been restored by the time we get here.  We'll need to set
13351 * up rIBASE & rINST, and load the address of the JitTable into r0.
13352 */
13353toInterpreter:
13354    EXPORT_PC()
13355    adrl   rIBASE, dvmAsmInstructionStart
13356    FETCH_INST()
13357    GET_JIT_PROF_TABLE(r0)
13358    @ NOTE: intended fallthrough
13359
13360/*
13361 * Common code to update potential trace start counter, and initiate
13362 * a trace-build if appropriate.  On entry, rPC should point to the
13363 * next instruction to execute, and rINST should be already loaded with
13364 * the next opcode word, and r0 holds a pointer to the jit profile
13365 * table (pJitProfTable).
13366 */
13367common_testUpdateProfile:
13368    cmp     r0,#0
13369    GET_INST_OPCODE(ip)
13370    GOTO_OPCODE_IFEQ(ip)       @ if not profiling, fallthrough otherwise */
13371
13372common_updateProfile:
13373    eor     r3,rPC,rPC,lsr #12 @ cheap, but fast hash function
13374    lsl     r3,r3,#(32 - JIT_PROF_SIZE_LOG_2)          @ shift out excess bits
13375    ldrb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter
13376    GET_INST_OPCODE(ip)
13377    subs    r1,r1,#1           @ decrement counter
13378    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it
13379    GOTO_OPCODE_IFNE(ip)       @ if not threshold, fallthrough otherwise */
13380
13381/*
13382 * Here, we switch to the debug interpreter to request
13383 * trace selection.  First, though, check to see if there
13384 * is already a native translation in place (and, if so,
13385 * jump to it now).
13386 */
13387
13388    GET_JIT_THRESHOLD(r1)
13389    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter
13390    EXPORT_PC()
13391    mov     r0,rPC
13392    bl      dvmJitGetTraceAddr          @ r0<- dvmJitGetTraceAddr(rPC)
13393    str     r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
13394    mov     r1, rPC                     @ arg1 of translation may need this
13395    mov     lr, #0                      @  in case target is HANDLER_INTERPRET
13396    cmp     r0,#0
13397#if !defined(WITH_SELF_VERIFICATION)
13398    bxne    r0                          @ jump to the translation
13399    mov     r2,#kJitTSelectRequest      @ ask for trace selection
13400    @ fall-through to common_selectTrace
13401#else
13402    moveq   r2,#kJitTSelectRequest      @ ask for trace selection
13403    beq     common_selectTrace
13404    /*
13405     * At this point, we have a target translation.  However, if
13406     * that translation is actually the interpret-only pseudo-translation
13407     * we want to treat it the same as no translation.
13408     */
13409    mov     r10, r0                     @ save target
13410    bl      dvmCompilerGetInterpretTemplate
13411    cmp     r0, r10                     @ special case?
13412    bne     jitSVShadowRunStart         @ set up self verification shadow space
13413    @ Need to clear the inJitCodeCache flag
13414    mov    r3, #0                       @ 0 means not in the JIT code cache
13415    str    r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land
13416    GET_INST_OPCODE(ip)
13417    GOTO_OPCODE(ip)
13418    /* no return */
13419#endif
13420
13421/*
13422 * On entry:
13423 *  r2 is jit state, e.g. kJitTSelectRequest or kJitTSelectRequestHot
13424 */
13425common_selectTrace:
13426
13427    str     r2,[rSELF,#offThread_jitState]
13428    mov     r2,#kInterpEntryInstr       @ normal entry reason
13429    str     r2,[rSELF,#offThread_entryPoint]
13430    mov     r1,#1                       @ set changeInterp
13431    b       common_gotoBail
13432
13433#if defined(WITH_SELF_VERIFICATION)
13434/*
13435 * Save PC and registers to shadow memory for self verification mode
13436 * before jumping to native translation.
13437 * On entry:
13438 *    rPC, rFP, rSELF: the values that they should contain
13439 *    r10: the address of the target translation.
13440 */
13441jitSVShadowRunStart:
13442    mov     r0,rPC                      @ r0<- program counter
13443    mov     r1,rFP                      @ r1<- frame pointer
13444    mov     r2,rSELF                    @ r2<- self (Thread) pointer
13445    mov     r3,r10                      @ r3<- target translation
13446    bl      dvmSelfVerificationSaveState @ save registers to shadow space
13447    ldr     rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space
13448    bx      r10                         @ jump to the translation
13449
13450/*
13451 * Restore PC, registers, and interpreter state to original values
13452 * before jumping back to the interpreter.
13453 */
13454jitSVShadowRunEnd:
13455    mov    r1,rFP                        @ pass ending fp
13456    mov    r3,rSELF                      @ pass self ptr for convenience
13457    bl     dvmSelfVerificationRestoreState @ restore pc and fp values
13458    ldr    rPC,[rSELF,#offThread_pc]     @ restore PC
13459    ldr    rFP,[rSELF,#offThread_fp]     @ restore FP
13460    ldr    r1,[r0,#offShadowSpace_svState] @ get self verification state
13461    cmp    r1,#0                         @ check for punt condition
13462    beq    1f
13463    mov    r2,#kJitSelfVerification      @ ask for self verification
13464    str    r2,[rSELF,#offThread_jitState]
13465    mov    r2,#kInterpEntryInstr         @ normal entry reason
13466    str    r2,[rSELF,#offThread_entryPoint]
13467    mov    r1,#1                         @ set changeInterp
13468    b      common_gotoBail
13469
134701:                                       @ exit to interpreter without check
13471    EXPORT_PC()
13472    adrl   rIBASE, dvmAsmInstructionStart
13473    FETCH_INST()
13474    GET_INST_OPCODE(ip)
13475    GOTO_OPCODE(ip)
13476#endif
13477
13478#endif
13479
13480/*
13481 * Common code when a backward branch is taken.
13482 *
13483 * TODO: we could avoid a branch by just setting r0 and falling through
13484 * into the common_periodicChecks code, and having a test on r0 at the
13485 * end determine if we should return to the caller or update & branch to
13486 * the next instr.
13487 *
13488 * On entry:
13489 *  r9 is PC adjustment *in bytes*
13490 */
13491common_backwardBranch:
13492    mov     r0, #kInterpEntryInstr
13493    bl      common_periodicChecks
13494#if defined(WITH_JIT)
13495    GET_JIT_PROF_TABLE(r0)
13496    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
13497    cmp     r0,#0
13498    bne     common_updateProfile
13499    GET_INST_OPCODE(ip)
13500    GOTO_OPCODE(ip)
13501#else
13502    FETCH_ADVANCE_INST_RB(r9)           @ update rPC, load rINST
13503    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13504    GOTO_OPCODE(ip)                     @ jump to next instruction
13505#endif
13506
13507
13508/*
13509 * Need to see if the thread needs to be suspended or debugger/profiler
13510 * activity has begun.  If so, we suspend the thread or side-exit to
13511 * the debug interpreter as appropriate.
13512 *
13513 * The common case is no activity on any of these, so we want to figure
13514 * that out quickly.  If something is up, we can then sort out what.
13515 *
13516 * We want to be fast if the VM was built without debugger or profiler
13517 * support, but we also need to recognize that the system is usually
13518 * shipped with both of these enabled.
13519 *
13520 * TODO: reduce this so we're just checking a single location.
13521 *
13522 * On entry:
13523 *  r0 is reentry type, e.g. kInterpEntryInstr (for debugger/profiling)
13524 *  r9 is trampoline PC adjustment *in bytes*
13525 */
13526common_periodicChecks:
13527/* TUNING - make this a direct load when interpBreak moved to Thread */
13528    ldr     r1, [rSELF, #offThread_pInterpBreak] @ r3<- &interpBreak
13529    /* speculatively thread-specific suspend count */
13530    ldr     ip, [rSELF, #offThread_suspendCount]
13531    ldr     r1, [r1]                                @ r1<- interpBreak
13532    cmp     r1, #0                                  @ anything unusual?
13533    bxeq    lr                                      @ return if not
13534    /*
13535     * One or more interesting events have happened.  Figure out what.
13536     *
13537     * r0 still holds the reentry type.
13538     */
13539    cmp     ip, #0                      @ want suspend?
13540    beq     3f                          @ no, must be something else
13541
13542    stmfd   sp!, {r0, lr}               @ preserve r0 and lr
13543#if defined(WITH_JIT)
13544    /*
13545     * Refresh the Jit's cached copy of profile table pointer.  This pointer
13546     * doubles as the Jit's on/off switch.
13547     */
13548    ldr     r3, [rSELF, #offThread_ppJitProfTable] @ r3<-&gDvmJit.pJitProfTable
13549    mov     r0, rSELF                  @ r0<- self
13550    ldr     r3, [r3] @ r3 <- pJitProfTable
13551    EXPORT_PC()                         @ need for precise GC
13552    str     r3, [rSELF, #offThread_pJitProfTable] @ refresh Jit's on/off switch
13553#else
13554    mov     r0, rSELF                   @ r0<- self
13555    EXPORT_PC()                         @ need for precise GC
13556#endif
13557    bl      dvmCheckSuspendPending      @ do full check, suspend if necessary
13558    ldmfd   sp!, {r0, lr}               @ restore r0 and lr
13559
13560    /*
13561     * Reload the interpBreak flags - they may have changed while we
13562     * were suspended.
13563     */
13564/* TUNING - direct load when InterpBreak moved to Thread */
13565    ldr     r1, [rSELF, #offThread_pInterpBreak]   @ r1<- &interpBreak
13566    ldr     r1, [r1]                    @ r1<- interpBreak
135673:
13568    /*
13569     * TODO: this code is too fragile.  Need a general mechanism
13570     * to identify what actions to take by submode.  Some profiling modes
13571     * (instruction count) need to single-step, while method tracing
13572     * may not.  Debugging with breakpoints can run unfettered, but
13573     * source-level single-stepping requires Dalvik singlestepping.
13574     * GC may require a one-shot action and then full-speed resumption.
13575     */
13576    ands    r1, #(kSubModeDebuggerActive | kSubModeEmulatorTrace | kSubModeInstCounting)
13577    bxeq    lr                          @ nothing to do, return
13578
13579    @ debugger/profiler enabled, bail out; self->entryPoint was set above
13580    str     r0, [rSELF, #offThread_entryPoint]  @ store r0, need for debug/prof
13581    add     rPC, rPC, r9                @ update rPC
13582    mov     r1, #1                      @ "want switch" = true
13583    b       common_gotoBail             @ side exit
13584
13585
13586/*
13587 * The equivalent of "goto bail", this calls through the "bail handler".
13588 *
13589 * State registers will be saved to the "thread" area before bailing.
13590 *
13591 * On entry:
13592 *  r1 is "bool changeInterp", indicating if we want to switch to the
13593 *     other interpreter or just bail all the way out
13594 */
13595common_gotoBail:
13596    SAVE_PC_FP_TO_SELF()                @ export state to "thread"
13597    mov     r0, rSELF                   @ r0<- self ptr
13598    b       dvmMterpStdBail             @ call(self, changeInterp)
13599
13600    @add     r1, r1, #1                  @ using (boolean+1)
13601    @add     r0, rSELF, #offThread_jmpBuf @ r0<- &self->jmpBuf
13602    @bl      _longjmp                    @ does not return
13603    @bl      common_abort
13604
13605
13606/*
13607 * Common code for jumbo method invocation.
13608 * NOTE: this adjusts rPC to account for the difference in instruction width.
13609 * As a result, the savedPc in the stack frame will not be wholly accurate. So
13610 * long as that is only used for source file line number calculations, we're
13611 * okay.
13612 *
13613 * On entry:
13614 *  r0 is "Method* methodToCall", the method we're trying to call
13615 */
13616common_invokeMethodJumbo:
13617.LinvokeNewJumbo:
13618    @ prepare to copy args to "outs" area of current frame
13619    add     rPC, rPC, #4                @ adjust pc to make return consistent
13620    FETCH(r2, 1)                        @ r2<- BBBB (arg count)
13621    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13622    cmp     r2, #0                      @ no args?
13623    beq     .LinvokeArgsDone            @ if no args, skip the rest
13624    FETCH(r1, 2)                        @ r1<- CCCC
13625    b       .LinvokeRangeArgs           @ handle args like invoke range
13626
13627/*
13628 * Common code for method invocation with range.
13629 *
13630 * On entry:
13631 *  r0 is "Method* methodToCall", the method we're trying to call
13632 */
13633common_invokeMethodRange:
13634.LinvokeNewRange:
13635    @ prepare to copy args to "outs" area of current frame
13636    movs    r2, rINST, lsr #8           @ r2<- AA (arg count) -- test for zero
13637    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13638    beq     .LinvokeArgsDone            @ if no args, skip the rest
13639    FETCH(r1, 2)                        @ r1<- CCCC
13640
13641.LinvokeRangeArgs:
13642    @ r0=methodToCall, r1=CCCC, r2=count, r10=outs
13643    @ (very few methods have > 10 args; could unroll for common cases)
13644    add     r3, rFP, r1, lsl #2         @ r3<- &fp[CCCC]
13645    sub     r10, r10, r2, lsl #2        @ r10<- "outs" area, for call args
136461:  ldr     r1, [r3], #4                @ val = *fp++
13647    subs    r2, r2, #1                  @ count--
13648    str     r1, [r10], #4               @ *outs++ = val
13649    bne     1b                          @ ...while count != 0
13650    b       .LinvokeArgsDone
13651
13652/*
13653 * Common code for method invocation without range.
13654 *
13655 * On entry:
13656 *  r0 is "Method* methodToCall", the method we're trying to call
13657 */
13658common_invokeMethodNoRange:
13659.LinvokeNewNoRange:
13660    @ prepare to copy args to "outs" area of current frame
13661    movs    r2, rINST, lsr #12          @ r2<- B (arg count) -- test for zero
13662    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
13663    FETCH(r1, 2)                        @ r1<- GFED (load here to hide latency)
13664    beq     .LinvokeArgsDone
13665
13666    @ r0=methodToCall, r1=GFED, r2=count, r10=outs
13667.LinvokeNonRange:
13668    rsb     r2, r2, #5                  @ r2<- 5-r2
13669    add     pc, pc, r2, lsl #4          @ computed goto, 4 instrs each
13670    bl      common_abort                @ (skipped due to ARM prefetch)
136715:  and     ip, rINST, #0x0f00          @ isolate A
13672    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vA (shift right 8, left 2)
13673    mov     r0, r0                      @ nop
13674    str     r2, [r10, #-4]!             @ *--outs = vA
136754:  and     ip, r1, #0xf000             @ isolate G
13676    ldr     r2, [rFP, ip, lsr #10]      @ r2<- vG (shift right 12, left 2)
13677    mov     r0, r0                      @ nop
13678    str     r2, [r10, #-4]!             @ *--outs = vG
136793:  and     ip, r1, #0x0f00             @ isolate F
13680    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vF
13681    mov     r0, r0                      @ nop
13682    str     r2, [r10, #-4]!             @ *--outs = vF
136832:  and     ip, r1, #0x00f0             @ isolate E
13684    ldr     r2, [rFP, ip, lsr #2]       @ r2<- vE
13685    mov     r0, r0                      @ nop
13686    str     r2, [r10, #-4]!             @ *--outs = vE
136871:  and     ip, r1, #0x000f             @ isolate D
13688    ldr     r2, [rFP, ip, lsl #2]       @ r2<- vD
13689    mov     r0, r0                      @ nop
13690    str     r2, [r10, #-4]!             @ *--outs = vD
136910:  @ fall through to .LinvokeArgsDone
13692
13693.LinvokeArgsDone: @ r0=methodToCall
13694    ldrh    r9, [r0, #offMethod_registersSize]  @ r9<- methodToCall->regsSize
13695    ldrh    r3, [r0, #offMethod_outsSize]  @ r3<- methodToCall->outsSize
13696    ldr     r2, [r0, #offMethod_insns]  @ r2<- method->insns
13697    ldr     rINST, [r0, #offMethod_clazz]  @ rINST<- method->clazz
13698    @ find space for the new stack frame, check for overflow
13699    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- stack save area
13700    sub     r1, r1, r9, lsl #2          @ r1<- newFp (old savearea - regsSize)
13701    SAVEAREA_FROM_FP(r10, r1)           @ r10<- newSaveArea
13702@    bl      common_dumpRegs
13703    ldr     r9, [rSELF, #offThread_interpStackEnd]    @ r9<- interpStackEnd
13704    sub     r3, r10, r3, lsl #2         @ r3<- bottom (newsave - outsSize)
13705    cmp     r3, r9                      @ bottom < interpStackEnd?
13706    ldr     lr, [rSELF, #offThread_pInterpBreak]
13707    ldr     r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags
13708    blo     .LstackOverflow             @ yes, this frame will overflow stack
13709
13710    @ set up newSaveArea
13711    ldr     lr, [lr]                    @ lr<- active submodes
13712#ifdef EASY_GDB
13713    SAVEAREA_FROM_FP(ip, rFP)           @ ip<- stack save area
13714    str     ip, [r10, #offStackSaveArea_prevSave]
13715#endif
13716    str     rFP, [r10, #offStackSaveArea_prevFrame]
13717    str     rPC, [r10, #offStackSaveArea_savedPc]
13718#if defined(WITH_JIT)
13719    mov     r9, #0
13720    str     r9, [r10, #offStackSaveArea_returnAddr]
13721#endif
13722    ands    lr, #kSubModeMethodTrace    @ method tracing?
13723    beq     1f                          @ skip if not
13724    stmfd   sp!, {r0-r3}                @ preserve r0-r3
13725    mov     r1, r6
13726    @ r0=methodToCall, r1=rSELF
13727    bl      dvmFastMethodTraceEnter
13728    ldmfd   sp!, {r0-r3}                @ restore r0-r3
137291:
13730    str     r0, [r10, #offStackSaveArea_method]
13731    tst     r3, #ACC_NATIVE
13732    bne     .LinvokeNative
13733
13734    /*
13735    stmfd   sp!, {r0-r3}
13736    bl      common_printNewline
13737    mov     r0, rFP
13738    mov     r1, #0
13739    bl      dvmDumpFp
13740    ldmfd   sp!, {r0-r3}
13741    stmfd   sp!, {r0-r3}
13742    mov     r0, r1
13743    mov     r1, r10
13744    bl      dvmDumpFp
13745    bl      common_printNewline
13746    ldmfd   sp!, {r0-r3}
13747    */
13748
13749    ldrh    r9, [r2]                        @ r9 <- load INST from new PC
13750    ldr     r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
13751    mov     rPC, r2                         @ publish new rPC
13752
13753    @ Update state values for the new method
13754    @ r0=methodToCall, r1=newFp, r3=newMethodClass, r9=newINST
13755    str     r0, [rSELF, #offThread_method]    @ self->method = methodToCall
13756    str     r3, [rSELF, #offThread_methodClassDex] @ self->methodClassDex = ...
13757#if defined(WITH_JIT)
13758    GET_JIT_PROF_TABLE(r0)
13759    mov     rFP, r1                         @ fp = newFp
13760    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
13761    mov     rINST, r9                       @ publish new rINST
13762    str     r1, [rSELF, #offThread_curFrame]   @ self->curFrame = newFp
13763    cmp     r0,#0
13764    bne     common_updateProfile
13765    GOTO_OPCODE(ip)                         @ jump to next instruction
13766#else
13767    mov     rFP, r1                         @ fp = newFp
13768    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
13769    mov     rINST, r9                       @ publish new rINST
13770    str     r1, [rSELF, #offThread_curFrame]   @ self->curFrame = newFp
13771    GOTO_OPCODE(ip)                         @ jump to next instruction
13772#endif
13773
13774.LinvokeNative:
13775    @ Prep for the native call
13776    @ r0=methodToCall, r1=newFp, r10=newSaveArea
13777    ldr     lr, [rSELF, #offThread_pInterpBreak]
13778    ldr     r9, [rSELF, #offThread_jniLocal_topCookie]@r9<-thread->localRef->...
13779    str     r1, [rSELF, #offThread_curFrame]   @ self->curFrame = newFp
13780    str     r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top
13781    ldr     lr, [lr]                    @ lr<- active submodes
13782
13783    mov     r2, r0                      @ r2<- methodToCall
13784    mov     r0, r1                      @ r0<- newFp (points to args)
13785    add     r1, rSELF, #offThread_retval  @ r1<- &retval
13786    mov     r3, rSELF                   @ arg3<- self
13787
13788#ifdef ASSIST_DEBUGGER
13789    /* insert fake function header to help gdb find the stack frame */
13790    b       .Lskip
13791    .type   dalvik_mterp, %function
13792dalvik_mterp:
13793    .fnstart
13794    MTERP_ENTRY1
13795    MTERP_ENTRY2
13796.Lskip:
13797#endif
13798
13799    ands    lr, #kSubModeMethodTrace    @ method tracing?
13800    beq     110f                        @ hop if not
13801    @ r2=JNIMethod, r6=rSELF
13802    stmfd   sp!, {r2,r6}
13803
13804    mov     lr, pc                      @ set return addr
13805    ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
13806
13807    @ r0=JNIMethod, r1=rSELF
13808    ldmfd   sp!, {r0-r1}
13809    bl      dvmFastNativeMethodTraceExit
13810    b       220f
13811110:
13812    mov     lr, pc                      @ set return addr
13813    ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
13814220:
13815#if defined(WITH_JIT)
13816    ldr     r3, [rSELF, #offThread_ppJitProfTable] @ Refresh Jit's on/off status
13817#endif
13818
13819    @ native return; r10=newSaveArea
13820    @ equivalent to dvmPopJniLocals
13821    ldr     r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top
13822    ldr     r1, [rSELF, #offThread_exception] @ check for exception
13823#if defined(WITH_JIT)
13824    ldr     r3, [r3]                    @ r3 <- gDvmJit.pProfTable
13825#endif
13826    str     rFP, [rSELF, #offThread_curFrame]  @ self->curFrame = fp
13827    cmp     r1, #0                      @ null?
13828    str     r0, [rSELF, #offThread_jniLocal_topCookie] @ new top <- old top
13829#if defined(WITH_JIT)
13830    str     r3, [rSELF, #offThread_pJitProfTable] @ refresh cached on/off switch
13831#endif
13832    bne     common_exceptionThrown      @ no, handle exception
13833
13834    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
13835    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13836    GOTO_OPCODE(ip)                     @ jump to next instruction
13837
13838.LstackOverflow:    @ r0=methodToCall
13839    mov     r1, r0                      @ r1<- methodToCall
13840    mov     r0, rSELF                   @ r0<- self
13841    bl      dvmHandleStackOverflow
13842    b       common_exceptionThrown
13843#ifdef ASSIST_DEBUGGER
13844    .fnend
13845    .size   dalvik_mterp, .-dalvik_mterp
13846#endif
13847
13848
13849    /*
13850     * Common code for method invocation, calling through "glue code".
13851     *
13852     * TODO: now that we have range and non-range invoke handlers, this
13853     *       needs to be split into two.  Maybe just create entry points
13854     *       that set r9 and jump here?
13855     *
13856     * On entry:
13857     *  r0 is "Method* methodToCall", the method we're trying to call
13858     *  r9 is "bool methodCallRange", indicating if this is a /range variant
13859     */
13860     .if    0
13861.LinvokeOld:
13862    sub     sp, sp, #8                  @ space for args + pad
13863    FETCH(ip, 2)                        @ ip<- FEDC or CCCC
13864    mov     r2, r0                      @ A2<- methodToCall
13865    mov     r0, rSELF                   @ A0<- self
13866    SAVE_PC_FP_TO_SELF()                @ export state to "self"
13867    mov     r1, r9                      @ A1<- methodCallRange
13868    mov     r3, rINST, lsr #8           @ A3<- AA
13869    str     ip, [sp, #0]                @ A4<- ip
13870    bl      dvmMterp_invokeMethod       @ call the C invokeMethod
13871    add     sp, sp, #8                  @ remove arg area
13872    b       common_resumeAfterGlueCall  @ continue to next instruction
13873    .endif
13874
13875
13876
13877/*
13878 * Common code for handling a return instruction.
13879 *
13880 * This does not return.
13881 */
13882common_returnFromMethod:
13883.LreturnNew:
13884    mov     r0, #kInterpEntryReturn
13885    mov     r9, #0
13886    bl      common_periodicChecks
13887
13888    ldr     lr, [rSELF, #offThread_pInterpBreak]
13889    SAVEAREA_FROM_FP(r0, rFP)
13890    ldr     lr, [lr]                    @ lr<- active submodes
13891    ldr     r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc
13892    ands    lr, #kSubModeMethodTrace    @ method tracing?
13893    beq     333f
13894    stmfd   sp!, {r0-r3}                @ preserve r0-r3
13895    mov     r0, r6
13896    @ r0=rSELF
13897    bl      dvmFastJavaMethodTraceExit
13898    ldmfd   sp!, {r0-r3}                @ restore r0-r3
13899333:
13900    ldr     rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame
13901    ldr     r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)]
13902                                        @ r2<- method we're returning to
13903    cmp     r2, #0                      @ is this a break frame?
13904#if defined(WORKAROUND_CORTEX_A9_745320)
13905    /* Don't use conditional loads if the HW defect exists */
13906    beq     101f
13907    ldr     r10, [r2, #offMethod_clazz] @ r10<- method->clazz
13908101:
13909#else
13910    ldrne   r10, [r2, #offMethod_clazz] @ r10<- method->clazz
13911#endif
13912    mov     r1, #0                      @ "want switch" = false
13913    beq     common_gotoBail             @ break frame, bail out completely
13914
13915    PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST
13916    str     r2, [rSELF, #offThread_method]@ self->method = newSave->method
13917    ldr     r1, [r10, #offClassObject_pDvmDex]   @ r1<- method->clazz->pDvmDex
13918    str     rFP, [rSELF, #offThread_curFrame]  @ self->curFrame = fp
13919#if defined(WITH_JIT)
13920    ldr     r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr
13921    mov     rPC, r9                     @ publish new rPC
13922    str     r1, [rSELF, #offThread_methodClassDex]
13923    str     r10, [rSELF, #offThread_inJitCodeCache]  @ may return to JIT'ed land
13924    cmp     r10, #0                      @ caller is compiled code
13925    blxne   r10
13926    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13927    GOTO_OPCODE(ip)                     @ jump to next instruction
13928#else
13929    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
13930    mov     rPC, r9                     @ publish new rPC
13931    str     r1, [rSELF, #offThread_methodClassDex]
13932    GOTO_OPCODE(ip)                     @ jump to next instruction
13933#endif
13934
13935    /*
13936     * Return handling, calls through "glue code".
13937     */
13938     .if    0
13939.LreturnOld:
13940    SAVE_PC_FP_TO_SELF()                @ export state
13941    mov     r0, rSELF                   @ arg to function
13942    bl      dvmMterp_returnFromMethod
13943    b       common_resumeAfterGlueCall
13944    .endif
13945
13946
13947/*
13948 * Somebody has thrown an exception.  Handle it.
13949 *
13950 * If the exception processing code returns to us (instead of falling
13951 * out of the interpreter), continue with whatever the next instruction
13952 * now happens to be.
13953 *
13954 * This does not return.
13955 */
13956     .global dvmMterpCommonExceptionThrown
13957dvmMterpCommonExceptionThrown:
13958common_exceptionThrown:
13959.LexceptionNew:
13960    mov     r0, #kInterpEntryThrow
13961    mov     r9, #0
13962    bl      common_periodicChecks
13963
13964    ldr     r9, [rSELF, #offThread_exception] @ r9<- self->exception
13965    mov     r1, rSELF                   @ r1<- self
13966    mov     r0, r9                      @ r0<- exception
13967    bl      dvmAddTrackedAlloc          @ don't let the exception be GCed
13968    mov     r3, #0                      @ r3<- NULL
13969    str     r3, [rSELF, #offThread_exception] @ self->exception = NULL
13970
13971    /* set up args and a local for "&fp" */
13972    /* (str sp, [sp, #-4]!  would be perfect here, but is discouraged) */
13973    str     rFP, [sp, #-4]!             @ *--sp = fp
13974    mov     ip, sp                      @ ip<- &fp
13975    mov     r3, #0                      @ r3<- false
13976    str     ip, [sp, #-4]!              @ *--sp = &fp
13977    ldr     r1, [rSELF, #offThread_method] @ r1<- self->method
13978    mov     r0, rSELF                   @ r0<- self
13979    ldr     r1, [r1, #offMethod_insns]  @ r1<- method->insns
13980    mov     r2, r9                      @ r2<- exception
13981    sub     r1, rPC, r1                 @ r1<- pc - method->insns
13982    mov     r1, r1, asr #1              @ r1<- offset in code units
13983
13984    /* call, r0 gets catchRelPc (a code-unit offset) */
13985    bl      dvmFindCatchBlock           @ call(self, relPc, exc, scan?, &fp)
13986
13987    /* fix earlier stack overflow if necessary; may trash rFP */
13988    ldrb    r1, [rSELF, #offThread_stackOverflowed]
13989    cmp     r1, #0                      @ did we overflow earlier?
13990    beq     1f                          @ no, skip ahead
13991    mov     rFP, r0                     @ save relPc result in rFP
13992    mov     r0, rSELF                   @ r0<- self
13993    mov     r1, r9                      @ r1<- exception
13994    bl      dvmCleanupStackOverflow     @ call(self)
13995    mov     r0, rFP                     @ restore result
139961:
13997
13998    /* update frame pointer and check result from dvmFindCatchBlock */
13999    ldr     rFP, [sp, #4]               @ retrieve the updated rFP
14000    cmp     r0, #0                      @ is catchRelPc < 0?
14001    add     sp, sp, #8                  @ restore stack
14002    bmi     .LnotCaughtLocally
14003
14004    /* adjust locals to match self->curFrame and updated PC */
14005    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- new save area
14006    ldr     r1, [r1, #offStackSaveArea_method] @ r1<- new method
14007    str     r1, [rSELF, #offThread_method]  @ self->method = new method
14008    ldr     r2, [r1, #offMethod_clazz]      @ r2<- method->clazz
14009    ldr     r3, [r1, #offMethod_insns]      @ r3<- method->insns
14010    ldr     r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex
14011    add     rPC, r3, r0, asl #1             @ rPC<- method->insns + catchRelPc
14012    str     r2, [rSELF, #offThread_methodClassDex] @ self->pDvmDex = meth...
14013
14014    /* release the tracked alloc on the exception */
14015    mov     r0, r9                      @ r0<- exception
14016    mov     r1, rSELF                   @ r1<- self
14017    bl      dvmReleaseTrackedAlloc      @ release the exception
14018
14019    /* restore the exception if the handler wants it */
14020    FETCH_INST()                        @ load rINST from rPC
14021    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14022    cmp     ip, #OP_MOVE_EXCEPTION      @ is it "move-exception"?
14023    streq   r9, [rSELF, #offThread_exception] @ yes, restore the exception
14024    GOTO_OPCODE(ip)                     @ jump to next instruction
14025
14026.LnotCaughtLocally: @ r9=exception
14027    /* fix stack overflow if necessary */
14028    ldrb    r1, [rSELF, #offThread_stackOverflowed]
14029    cmp     r1, #0                      @ did we overflow earlier?
14030    movne   r0, rSELF                   @ if yes: r0<- self
14031    movne   r1, r9                      @ if yes: r1<- exception
14032    blne    dvmCleanupStackOverflow     @ if yes: call(self)
14033
14034    @ may want to show "not caught locally" debug messages here
14035#if DVM_SHOW_EXCEPTION >= 2
14036    /* call __android_log_print(prio, tag, format, ...) */
14037    /* "Exception %s from %s:%d not caught locally" */
14038    @ dvmLineNumFromPC(method, pc - method->insns)
14039    ldr     r0, [rSELF, #offThread_method]
14040    ldr     r1, [r0, #offMethod_insns]
14041    sub     r1, rPC, r1
14042    asr     r1, r1, #1
14043    bl      dvmLineNumFromPC
14044    str     r0, [sp, #-4]!
14045    @ dvmGetMethodSourceFile(method)
14046    ldr     r0, [rSELF, #offThread_method]
14047    bl      dvmGetMethodSourceFile
14048    str     r0, [sp, #-4]!
14049    @ exception->clazz->descriptor
14050    ldr     r3, [r9, #offObject_clazz]
14051    ldr     r3, [r3, #offClassObject_descriptor]
14052    @
14053    ldr     r2, strExceptionNotCaughtLocally
14054    ldr     r1, strLogTag
14055    mov     r0, #3                      @ LOG_DEBUG
14056    bl      __android_log_print
14057#endif
14058    str     r9, [rSELF, #offThread_exception] @ restore exception
14059    mov     r0, r9                      @ r0<- exception
14060    mov     r1, rSELF                   @ r1<- self
14061    bl      dvmReleaseTrackedAlloc      @ release the exception
14062    mov     r1, #0                      @ "want switch" = false
14063    b       common_gotoBail             @ bail out
14064
14065
14066    /*
14067     * Exception handling, calls through "glue code".
14068     */
14069    .if     0
14070.LexceptionOld:
14071    SAVE_PC_FP_TO_SELF()                @ export state
14072    mov     r0, rSELF                   @ arg to function
14073    bl      dvmMterp_exceptionThrown
14074    b       common_resumeAfterGlueCall
14075    .endif
14076
14077
14078/*
14079 * After returning from a "glued" function, pull out the updated
14080 * values and start executing at the next instruction.
14081 */
14082common_resumeAfterGlueCall:
14083    LOAD_PC_FP_FROM_SELF()              @ pull rPC and rFP out of thread
14084    FETCH_INST()                        @ load rINST from rPC
14085    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
14086    GOTO_OPCODE(ip)                     @ jump to next instruction
14087
14088/*
14089 * Invalid array index. Note that our calling convention is strange; we use r1
14090 * and r3 because those just happen to be the registers all our callers are
14091 * using. We shuffle them here before calling the C function.
14092 * r1: index
14093 * r3: size
14094 */
14095common_errArrayIndex:
14096    EXPORT_PC()
14097    mov     r0, r1
14098    mov     r1, r3
14099    bl      dvmThrowArrayIndexOutOfBoundsException
14100    b       common_exceptionThrown
14101
14102/*
14103 * Integer divide or mod by zero.
14104 */
14105common_errDivideByZero:
14106    EXPORT_PC()
14107    ldr     r0, strArithmeticException
14108    ldr     r1, strDivideByZero
14109    bl      dvmThrowException
14110    b       common_exceptionThrown
14111
14112/*
14113 * Attempt to allocate an array with a negative size.
14114 * On entry: length in r1
14115 */
14116common_errNegativeArraySize:
14117    EXPORT_PC()
14118    mov     r0, r1                                @ arg0 <- len
14119    bl      dvmThrowNegativeArraySizeException    @ (len)
14120    b       common_exceptionThrown
14121
14122/*
14123 * Invocation of a non-existent method.
14124 */
14125common_errNoSuchMethod:
14126    EXPORT_PC()
14127    ldr     r0, strNoSuchMethodError
14128    mov     r1, #0
14129    bl      dvmThrowException
14130    b       common_exceptionThrown
14131
14132/*
14133 * We encountered a null object when we weren't expecting one.  We
14134 * export the PC, throw a NullPointerException, and goto the exception
14135 * processing code.
14136 */
14137common_errNullObject:
14138    EXPORT_PC()
14139    ldr     r0, strNullPointerException
14140    mov     r1, #0
14141    bl      dvmThrowException
14142    b       common_exceptionThrown
14143
14144/*
14145 * For debugging, cause an immediate fault.  The source address will
14146 * be in lr (use a bl instruction to jump here).
14147 */
14148common_abort:
14149    ldr     pc, .LdeadFood
14150.LdeadFood:
14151    .word   0xdeadf00d
14152
14153/*
14154 * Spit out a "we were here", preserving all registers.  (The attempt
14155 * to save ip won't work, but we need to save an even number of
14156 * registers for EABI 64-bit stack alignment.)
14157 */
14158    .macro  SQUEAK num
14159common_squeak\num:
14160    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14161    ldr     r0, strSqueak
14162    mov     r1, #\num
14163    bl      printf
14164    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14165    bx      lr
14166    .endm
14167
14168    SQUEAK  0
14169    SQUEAK  1
14170    SQUEAK  2
14171    SQUEAK  3
14172    SQUEAK  4
14173    SQUEAK  5
14174
14175/*
14176 * Spit out the number in r0, preserving registers.
14177 */
14178common_printNum:
14179    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14180    mov     r1, r0
14181    ldr     r0, strSqueak
14182    bl      printf
14183    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14184    bx      lr
14185
14186/*
14187 * Print a newline, preserving registers.
14188 */
14189common_printNewline:
14190    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14191    ldr     r0, strNewline
14192    bl      printf
14193    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14194    bx      lr
14195
14196    /*
14197     * Print the 32-bit quantity in r0 as a hex value, preserving registers.
14198     */
14199common_printHex:
14200    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14201    mov     r1, r0
14202    ldr     r0, strPrintHex
14203    bl      printf
14204    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14205    bx      lr
14206
14207/*
14208 * Print the 64-bit quantity in r0-r1, preserving registers.
14209 */
14210common_printLong:
14211    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14212    mov     r3, r1
14213    mov     r2, r0
14214    ldr     r0, strPrintLong
14215    bl      printf
14216    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14217    bx      lr
14218
14219/*
14220 * Print full method info.  Pass the Method* in r0.  Preserves regs.
14221 */
14222common_printMethod:
14223    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14224    bl      dvmMterpPrintMethod
14225    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14226    bx      lr
14227
14228/*
14229 * Call a C helper function that dumps regs and possibly some
14230 * additional info.  Requires the C function to be compiled in.
14231 */
14232    .if     0
14233common_dumpRegs:
14234    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
14235    bl      dvmMterpDumpArmRegs
14236    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
14237    bx      lr
14238    .endif
14239
14240#if 0
14241/*
14242 * Experiment on VFP mode.
14243 *
14244 * uint32_t setFPSCR(uint32_t val, uint32_t mask)
14245 *
14246 * Updates the bits specified by "mask", setting them to the values in "val".
14247 */
14248setFPSCR:
14249    and     r0, r0, r1                  @ make sure no stray bits are set
14250    fmrx    r2, fpscr                   @ get VFP reg
14251    mvn     r1, r1                      @ bit-invert mask
14252    and     r2, r2, r1                  @ clear masked bits
14253    orr     r2, r2, r0                  @ set specified bits
14254    fmxr    fpscr, r2                   @ set VFP reg
14255    mov     r0, r2                      @ return new value
14256    bx      lr
14257
14258    .align  2
14259    .global dvmConfigureFP
14260    .type   dvmConfigureFP, %function
14261dvmConfigureFP:
14262    stmfd   sp!, {ip, lr}
14263    /* 0x03000000 sets DN/FZ */
14264    /* 0x00009f00 clears the six exception enable flags */
14265    bl      common_squeak0
14266    mov     r0, #0x03000000             @ r0<- 0x03000000
14267    add     r1, r0, #0x9f00             @ r1<- 0x03009f00
14268    bl      setFPSCR
14269    ldmfd   sp!, {ip, pc}
14270#endif
14271
14272
14273/*
14274 * String references, must be close to the code that uses them.
14275 */
14276    .align  2
14277strArithmeticException:
14278    .word   .LstrArithmeticException
14279strDivideByZero:
14280    .word   .LstrDivideByZero
14281strNoSuchMethodError:
14282    .word   .LstrNoSuchMethodError
14283strNullPointerException:
14284    .word   .LstrNullPointerException
14285
14286strLogTag:
14287    .word   .LstrLogTag
14288strExceptionNotCaughtLocally:
14289    .word   .LstrExceptionNotCaughtLocally
14290
14291strNewline:
14292    .word   .LstrNewline
14293strSqueak:
14294    .word   .LstrSqueak
14295strPrintHex:
14296    .word   .LstrPrintHex
14297strPrintLong:
14298    .word   .LstrPrintLong
14299
14300/*
14301 * Zero-terminated ASCII string data.
14302 *
14303 * On ARM we have two choices: do like gcc does, and LDR from a .word
14304 * with the address, or use an ADR pseudo-op to get the address
14305 * directly.  ADR saves 4 bytes and an indirection, but it's using a
14306 * PC-relative addressing mode and hence has a limited range, which
14307 * makes it not work well with mergeable string sections.
14308 */
14309    .section .rodata.str1.4,"aMS",%progbits,1
14310
14311.LstrBadEntryPoint:
14312    .asciz  "Bad entry point %d\n"
14313.LstrArithmeticException:
14314    .asciz  "Ljava/lang/ArithmeticException;"
14315.LstrDivideByZero:
14316    .asciz  "divide by zero"
14317.LstrFilledNewArrayNotImpl:
14318    .asciz  "filled-new-array only implemented for objects and 'int'"
14319.LstrInternalError:
14320    .asciz  "Ljava/lang/InternalError;"
14321.LstrInstantiationError:
14322    .asciz  "Ljava/lang/InstantiationError;"
14323.LstrNoSuchMethodError:
14324    .asciz  "Ljava/lang/NoSuchMethodError;"
14325.LstrNullPointerException:
14326    .asciz  "Ljava/lang/NullPointerException;"
14327
14328.LstrLogTag:
14329    .asciz  "mterp"
14330.LstrExceptionNotCaughtLocally:
14331    .asciz  "Exception %s from %s:%d not caught locally\n"
14332
14333.LstrNewline:
14334    .asciz  "\n"
14335.LstrSqueak:
14336    .asciz  "<%d>"
14337.LstrPrintHex:
14338    .asciz  "<0x%x>"
14339.LstrPrintLong:
14340    .asciz  "<%lld>"
14341
14342