InterpAsm-armv7-a-neon.S revision 5dfcc78af479937ba8dafceefd9b1931a88dfaaf
1/*
2 * This file was generated automatically by gen-mterp.py for 'armv7-a-neon'.
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_curFrame]
86#define SAVE_FP_TO_SELF()       str     rFP, [rSELF, #offThread_curFrame]
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 throws.
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 #1]!", 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_BASE(_base,_reg)  add     pc, _base, _reg, lsl #6
180#define GOTO_OPCODE_IFEQ(_reg)  addeq   pc, rIBASE, _reg, lsl #6
181#define GOTO_OPCODE_IFNE(_reg)  addne   pc, rIBASE, _reg, lsl #6
182
183/*
184 * Get/set the 32-bit value from a Dalvik register.
185 */
186#define GET_VREG(_reg, _vreg)   ldr     _reg, [rFP, _vreg, lsl #2]
187#define SET_VREG(_reg, _vreg)   str     _reg, [rFP, _vreg, lsl #2]
188
189/*
190 * Convert a virtual register index into an address.
191 */
192#define VREG_INDEX_TO_ADDR(_reg, _vreg) \
193        add     _reg, rFP, _vreg, lsl #2
194
195/*
196 * This is a #include, not a %include, because we want the C pre-processor
197 * to expand the macros into assembler assignment statements.
198 */
199#include "../common/asm-constants.h"
200
201#if defined(WITH_JIT)
202#include "../common/jit-config.h"
203#endif
204
205/* File: armv7-a/platform.S */
206/*
207 * ===========================================================================
208 *  CPU-version-specific defines
209 * ===========================================================================
210 */
211
212#if !defined(ANDROID_SMP)
213# error "Must define ANDROID_SMP"
214#endif
215
216/*
217 * Macro for data memory barrier.
218 */
219.macro  SMP_DMB
220#if ANDROID_SMP != 0
221    dmb
222#else
223    /* not SMP */
224#endif
225.endm
226
227/*
228 * Macro for data memory barrier (store/store variant).
229 */
230.macro  SMP_DMB_ST
231#if ANDROID_SMP != 0
232    dmb     st
233#else
234    /* not SMP */
235#endif
236.endm
237
238/* File: armv5te/entry.S */
239/*
240 * Copyright (C) 2008 The Android Open Source Project
241 *
242 * Licensed under the Apache License, Version 2.0 (the "License");
243 * you may not use this file except in compliance with the License.
244 * You may obtain a copy of the License at
245 *
246 *      http://www.apache.org/licenses/LICENSE-2.0
247 *
248 * Unless required by applicable law or agreed to in writing, software
249 * distributed under the License is distributed on an "AS IS" BASIS,
250 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
251 * See the License for the specific language governing permissions and
252 * limitations under the License.
253 */
254/*
255 * Interpreter entry point.
256 */
257
258/*
259 * We don't have formal stack frames, so gdb scans upward in the code
260 * to find the start of the function (a label with the %function type),
261 * and then looks at the next few instructions to figure out what
262 * got pushed onto the stack.  From this it figures out how to restore
263 * the registers, including PC, for the previous stack frame.  If gdb
264 * sees a non-function label, it stops scanning, so either we need to
265 * have nothing but assembler-local labels between the entry point and
266 * the break, or we need to fake it out.
267 *
268 * When this is defined, we add some stuff to make gdb less confused.
269 */
270#define ASSIST_DEBUGGER 1
271
272    .text
273    .align  2
274    .global dvmMterpStdRun
275    .type   dvmMterpStdRun, %function
276
277/*
278 * On entry:
279 *  r0  Thread* self
280 *
281 * The return comes via a call to dvmMterpStdBail().
282 */
283dvmMterpStdRun:
284#define MTERP_ENTRY1 \
285    .save {r4-r10,fp,lr}; \
286    stmfd   sp!, {r4-r10,fp,lr}         @ save 9 regs
287#define MTERP_ENTRY2 \
288    .pad    #4; \
289    sub     sp, sp, #4                  @ align 64
290
291    .fnstart
292    MTERP_ENTRY1
293    MTERP_ENTRY2
294
295    /* save stack pointer, add magic word for debuggerd */
296    str     sp, [r0, #offThread_bailPtr]  @ save SP for eventual return
297
298    /* set up "named" registers, figure out entry point */
299    mov     rSELF, r0                   @ set rSELF
300    LOAD_PC_FP_FROM_SELF()              @ load rPC and rFP from "thread"
301    ldr     rIBASE, [rSELF, #offThread_curHandlerTable] @ set rIBASE
302
303#if defined(WITH_JIT)
304.LentryInstr:
305    /* Entry is always a possible trace start */
306    ldr     r0, [rSELF, #offThread_pJitProfTable]
307    FETCH_INST()
308    mov     r1, #0                      @ prepare the value for the new state
309    str     r1, [rSELF, #offThread_inJitCodeCache] @ back to the interp land
310    cmp     r0,#0                       @ is profiling disabled?
311#if !defined(WITH_SELF_VERIFICATION)
312    bne     common_updateProfile        @ profiling is enabled
313#else
314    ldr     r2, [rSELF, #offThread_shadowSpace] @ to find out the jit exit state
315    beq     1f                          @ profiling is disabled
316    ldr     r3, [r2, #offShadowSpace_jitExitState]  @ jit exit state
317    cmp     r3, #kSVSTraceSelect        @ hot trace following?
318    moveq   r2,#kJitTSelectRequestHot   @ ask for trace selection
319    beq     common_selectTrace          @ go build the trace
320    cmp     r3, #kSVSNoProfile          @ don't profile the next instruction?
321    beq     1f                          @ intrepret the next instruction
322    b       common_updateProfile        @ collect profiles
323#endif
3241:
325    GET_INST_OPCODE(ip)
326    GOTO_OPCODE(ip)
327#else
328    /* start executing the instruction at rPC */
329    FETCH_INST()                        @ load rINST from rPC
330    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
331    GOTO_OPCODE(ip)                     @ jump to next instruction
332#endif
333
334.Lbad_arg:
335    ldr     r0, strBadEntryPoint
3360:  add     r0, pc
337    @ r1 holds value of entryPoint
338    bl      printf
339    bl      dvmAbort
340    .fnend
341    .size   dvmMterpStdRun, .-dvmMterpStdRun
342
343strBadEntryPoint:
344    .word   PCREL_REF(.LstrBadEntryPoint,0b)
345
346    .global dvmMterpStdBail
347    .type   dvmMterpStdBail, %function
348
349/*
350 * Restore the stack pointer and PC from the save point established on entry.
351 * This is essentially the same as a longjmp, but should be cheaper.  The
352 * last instruction causes us to return to whoever called dvmMterpStdRun.
353 *
354 * We pushed some registers on the stack in dvmMterpStdRun, then saved
355 * SP and LR.  Here we restore SP, restore the registers, and then restore
356 * LR to PC.
357 *
358 * On entry:
359 *  r0  Thread* self
360 */
361dvmMterpStdBail:
362    ldr     sp, [r0, #offThread_bailPtr]    @ sp<- saved SP
363    add     sp, sp, #4                      @ un-align 64
364    ldmfd   sp!, {r4-r10,fp,pc}             @ restore 9 regs and return
365
366
367
368    .global dvmAsmInstructionStart
369    .type   dvmAsmInstructionStart, %function
370dvmAsmInstructionStart = .L_OP_NOP
371    .text
372
373/* ------------------------------ */
374    .balign 64
375.L_OP_NOP: /* 0x00 */
376/* File: armv5te/OP_NOP.S */
377    FETCH_ADVANCE_INST(1)               @ advance to next instr, load rINST
378    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
379    GOTO_OPCODE(ip)                     @ execute it
380
381#ifdef ASSIST_DEBUGGER
382    /* insert fake function header to help gdb find the stack frame */
383    .type   dalvik_inst, %function
384dalvik_inst:
385    .fnstart
386    MTERP_ENTRY1
387    MTERP_ENTRY2
388    .fnend
389#endif
390
391/* ------------------------------ */
392    .balign 64
393.L_OP_MOVE: /* 0x01 */
394/* File: armv6t2/OP_MOVE.S */
395    /* for move, move-object, long-to-int */
396    /* op vA, vB */
397    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
398    ubfx    r0, rINST, #8, #4           @ r0<- A from 11:8
399    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
400    GET_VREG(r2, r1)                    @ r2<- fp[B]
401    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
402    SET_VREG(r2, r0)                    @ fp[A]<- r2
403    GOTO_OPCODE(ip)                     @ execute next instruction
404
405/* ------------------------------ */
406    .balign 64
407.L_OP_MOVE_FROM16: /* 0x02 */
408/* File: armv5te/OP_MOVE_FROM16.S */
409    /* for: move/from16, move-object/from16 */
410    /* op vAA, vBBBB */
411    FETCH(r1, 1)                        @ r1<- BBBB
412    mov     r0, rINST, lsr #8           @ r0<- AA
413    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
414    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
415    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
416    SET_VREG(r2, r0)                    @ fp[AA]<- r2
417    GOTO_OPCODE(ip)                     @ jump to next instruction
418
419/* ------------------------------ */
420    .balign 64
421.L_OP_MOVE_16: /* 0x03 */
422/* File: armv5te/OP_MOVE_16.S */
423    /* for: move/16, move-object/16 */
424    /* op vAAAA, vBBBB */
425    FETCH(r1, 2)                        @ r1<- BBBB
426    FETCH(r0, 1)                        @ r0<- AAAA
427    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
428    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
429    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
430    SET_VREG(r2, r0)                    @ fp[AAAA]<- r2
431    GOTO_OPCODE(ip)                     @ jump to next instruction
432
433/* ------------------------------ */
434    .balign 64
435.L_OP_MOVE_WIDE: /* 0x04 */
436/* File: armv6t2/OP_MOVE_WIDE.S */
437    /* move-wide vA, vB */
438    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
439    mov     r3, rINST, lsr #12          @ r3<- B
440    ubfx    r2, rINST, #8, #4           @ r2<- A
441    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
442    add     r2, rFP, r2, lsl #2         @ r2<- &fp[A]
443    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[B]
444    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
445    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
446    stmia   r2, {r0-r1}                 @ fp[A]<- r0/r1
447    GOTO_OPCODE(ip)                     @ jump to next instruction
448
449/* ------------------------------ */
450    .balign 64
451.L_OP_MOVE_WIDE_FROM16: /* 0x05 */
452/* File: armv5te/OP_MOVE_WIDE_FROM16.S */
453    /* move-wide/from16 vAA, vBBBB */
454    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
455    FETCH(r3, 1)                        @ r3<- BBBB
456    mov     r2, rINST, lsr #8           @ r2<- AA
457    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BBBB]
458    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
459    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[BBBB]
460    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
461    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
462    stmia   r2, {r0-r1}                 @ fp[AA]<- r0/r1
463    GOTO_OPCODE(ip)                     @ jump to next instruction
464
465/* ------------------------------ */
466    .balign 64
467.L_OP_MOVE_WIDE_16: /* 0x06 */
468/* File: armv5te/OP_MOVE_WIDE_16.S */
469    /* move-wide/16 vAAAA, vBBBB */
470    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
471    FETCH(r3, 2)                        @ r3<- BBBB
472    FETCH(r2, 1)                        @ r2<- AAAA
473    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BBBB]
474    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AAAA]
475    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[BBBB]
476    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
477    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
478    stmia   r2, {r0-r1}                 @ fp[AAAA]<- r0/r1
479    GOTO_OPCODE(ip)                     @ jump to next instruction
480
481/* ------------------------------ */
482    .balign 64
483.L_OP_MOVE_OBJECT: /* 0x07 */
484/* File: armv5te/OP_MOVE_OBJECT.S */
485/* File: armv5te/OP_MOVE.S */
486    /* for move, move-object, long-to-int */
487    /* op vA, vB */
488    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
489    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
490    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
491    GET_VREG(r2, r1)                    @ r2<- fp[B]
492    and     r0, r0, #15
493    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
494    SET_VREG(r2, r0)                    @ fp[A]<- r2
495    GOTO_OPCODE(ip)                     @ execute next instruction
496
497
498/* ------------------------------ */
499    .balign 64
500.L_OP_MOVE_OBJECT_FROM16: /* 0x08 */
501/* File: armv5te/OP_MOVE_OBJECT_FROM16.S */
502/* File: armv5te/OP_MOVE_FROM16.S */
503    /* for: move/from16, move-object/from16 */
504    /* op vAA, vBBBB */
505    FETCH(r1, 1)                        @ r1<- BBBB
506    mov     r0, rINST, lsr #8           @ r0<- AA
507    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
508    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
509    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
510    SET_VREG(r2, r0)                    @ fp[AA]<- r2
511    GOTO_OPCODE(ip)                     @ jump to next instruction
512
513
514/* ------------------------------ */
515    .balign 64
516.L_OP_MOVE_OBJECT_16: /* 0x09 */
517/* File: armv5te/OP_MOVE_OBJECT_16.S */
518/* File: armv5te/OP_MOVE_16.S */
519    /* for: move/16, move-object/16 */
520    /* op vAAAA, vBBBB */
521    FETCH(r1, 2)                        @ r1<- BBBB
522    FETCH(r0, 1)                        @ r0<- AAAA
523    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
524    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
525    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
526    SET_VREG(r2, r0)                    @ fp[AAAA]<- r2
527    GOTO_OPCODE(ip)                     @ jump to next instruction
528
529
530/* ------------------------------ */
531    .balign 64
532.L_OP_MOVE_RESULT: /* 0x0a */
533/* File: armv5te/OP_MOVE_RESULT.S */
534    /* for: move-result, move-result-object */
535    /* op vAA */
536    mov     r2, rINST, lsr #8           @ r2<- AA
537    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
538    ldr     r0, [rSELF, #offThread_retval]    @ r0<- self->retval.i
539    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
540    SET_VREG(r0, r2)                    @ fp[AA]<- r0
541    GOTO_OPCODE(ip)                     @ jump to next instruction
542
543/* ------------------------------ */
544    .balign 64
545.L_OP_MOVE_RESULT_WIDE: /* 0x0b */
546/* File: armv5te/OP_MOVE_RESULT_WIDE.S */
547    /* move-result-wide vAA */
548    mov     r2, rINST, lsr #8           @ r2<- AA
549    add     r3, rSELF, #offThread_retval  @ r3<- &self->retval
550    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
551    ldmia   r3, {r0-r1}                 @ r0/r1<- retval.j
552    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
553    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
554    stmia   r2, {r0-r1}                 @ fp[AA]<- r0/r1
555    GOTO_OPCODE(ip)                     @ jump to next instruction
556
557/* ------------------------------ */
558    .balign 64
559.L_OP_MOVE_RESULT_OBJECT: /* 0x0c */
560/* File: armv5te/OP_MOVE_RESULT_OBJECT.S */
561/* File: armv5te/OP_MOVE_RESULT.S */
562    /* for: move-result, move-result-object */
563    /* op vAA */
564    mov     r2, rINST, lsr #8           @ r2<- AA
565    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
566    ldr     r0, [rSELF, #offThread_retval]    @ r0<- self->retval.i
567    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
568    SET_VREG(r0, r2)                    @ fp[AA]<- r0
569    GOTO_OPCODE(ip)                     @ jump to next instruction
570
571
572/* ------------------------------ */
573    .balign 64
574.L_OP_MOVE_EXCEPTION: /* 0x0d */
575/* File: armv5te/OP_MOVE_EXCEPTION.S */
576    /* move-exception vAA */
577    mov     r2, rINST, lsr #8           @ r2<- AA
578    ldr     r3, [rSELF, #offThread_exception]  @ r3<- dvmGetException bypass
579    mov     r1, #0                      @ r1<- 0
580    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
581    SET_VREG(r3, r2)                    @ fp[AA]<- exception obj
582    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
583    str     r1, [rSELF, #offThread_exception]  @ dvmClearException bypass
584    GOTO_OPCODE(ip)                     @ jump to next instruction
585
586/* ------------------------------ */
587    .balign 64
588.L_OP_RETURN_VOID: /* 0x0e */
589/* File: armv5te/OP_RETURN_VOID.S */
590    b       common_returnFromMethod
591
592/* ------------------------------ */
593    .balign 64
594.L_OP_RETURN: /* 0x0f */
595/* File: armv5te/OP_RETURN.S */
596    /*
597     * Return a 32-bit value.  Copies the return value into the "thread"
598     * structure, then jumps to the return handler.
599     *
600     * for: return, return-object
601     */
602    /* op vAA */
603    mov     r2, rINST, lsr #8           @ r2<- AA
604    GET_VREG(r0, r2)                    @ r0<- vAA
605    str     r0, [rSELF, #offThread_retval] @ retval.i <- vAA
606    b       common_returnFromMethod
607
608/* ------------------------------ */
609    .balign 64
610.L_OP_RETURN_WIDE: /* 0x10 */
611/* File: armv5te/OP_RETURN_WIDE.S */
612    /*
613     * Return a 64-bit value.  Copies the return value into the "thread"
614     * structure, then jumps to the return handler.
615     */
616    /* return-wide vAA */
617    mov     r2, rINST, lsr #8           @ r2<- AA
618    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
619    add     r3, rSELF, #offThread_retval  @ r3<- &self->retval
620    ldmia   r2, {r0-r1}                 @ r0/r1 <- vAA/vAA+1
621    stmia   r3, {r0-r1}                 @ retval<- r0/r1
622    b       common_returnFromMethod
623
624/* ------------------------------ */
625    .balign 64
626.L_OP_RETURN_OBJECT: /* 0x11 */
627/* File: armv5te/OP_RETURN_OBJECT.S */
628/* File: armv5te/OP_RETURN.S */
629    /*
630     * Return a 32-bit value.  Copies the return value into the "thread"
631     * structure, then jumps to the return handler.
632     *
633     * for: return, return-object
634     */
635    /* op vAA */
636    mov     r2, rINST, lsr #8           @ r2<- AA
637    GET_VREG(r0, r2)                    @ r0<- vAA
638    str     r0, [rSELF, #offThread_retval] @ retval.i <- vAA
639    b       common_returnFromMethod
640
641
642/* ------------------------------ */
643    .balign 64
644.L_OP_CONST_4: /* 0x12 */
645/* File: armv6t2/OP_CONST_4.S */
646    /* const/4 vA, #+B */
647    mov     r1, rINST, lsl #16          @ r1<- Bxxx0000
648    ubfx    r0, rINST, #8, #4           @ r0<- A
649    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
650    mov     r1, r1, asr #28             @ r1<- sssssssB (sign-extended)
651    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
652    SET_VREG(r1, r0)                    @ fp[A]<- r1
653    GOTO_OPCODE(ip)                     @ execute next instruction
654
655/* ------------------------------ */
656    .balign 64
657.L_OP_CONST_16: /* 0x13 */
658/* File: armv5te/OP_CONST_16.S */
659    /* const/16 vAA, #+BBBB */
660    FETCH_S(r0, 1)                      @ r0<- ssssBBBB (sign-extended)
661    mov     r3, rINST, lsr #8           @ r3<- AA
662    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
663    SET_VREG(r0, r3)                    @ vAA<- r0
664    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
665    GOTO_OPCODE(ip)                     @ jump to next instruction
666
667/* ------------------------------ */
668    .balign 64
669.L_OP_CONST: /* 0x14 */
670/* File: armv5te/OP_CONST.S */
671    /* const vAA, #+BBBBbbbb */
672    mov     r3, rINST, lsr #8           @ r3<- AA
673    FETCH(r0, 1)                        @ r0<- bbbb (low)
674    FETCH(r1, 2)                        @ r1<- BBBB (high)
675    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
676    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
677    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
678    SET_VREG(r0, r3)                    @ vAA<- r0
679    GOTO_OPCODE(ip)                     @ jump to next instruction
680
681/* ------------------------------ */
682    .balign 64
683.L_OP_CONST_HIGH16: /* 0x15 */
684/* File: armv5te/OP_CONST_HIGH16.S */
685    /* const/high16 vAA, #+BBBB0000 */
686    FETCH(r0, 1)                        @ r0<- 0000BBBB (zero-extended)
687    mov     r3, rINST, lsr #8           @ r3<- AA
688    mov     r0, r0, lsl #16             @ r0<- BBBB0000
689    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
690    SET_VREG(r0, r3)                    @ vAA<- r0
691    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
692    GOTO_OPCODE(ip)                     @ jump to next instruction
693
694/* ------------------------------ */
695    .balign 64
696.L_OP_CONST_WIDE_16: /* 0x16 */
697/* File: armv5te/OP_CONST_WIDE_16.S */
698    /* const-wide/16 vAA, #+BBBB */
699    FETCH_S(r0, 1)                      @ r0<- ssssBBBB (sign-extended)
700    mov     r3, rINST, lsr #8           @ r3<- AA
701    mov     r1, r0, asr #31             @ r1<- ssssssss
702    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
703    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
704    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
705    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
706    GOTO_OPCODE(ip)                     @ jump to next instruction
707
708/* ------------------------------ */
709    .balign 64
710.L_OP_CONST_WIDE_32: /* 0x17 */
711/* File: armv5te/OP_CONST_WIDE_32.S */
712    /* const-wide/32 vAA, #+BBBBbbbb */
713    FETCH(r0, 1)                        @ r0<- 0000bbbb (low)
714    mov     r3, rINST, lsr #8           @ r3<- AA
715    FETCH_S(r2, 2)                      @ r2<- ssssBBBB (high)
716    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
717    orr     r0, r0, r2, lsl #16         @ r0<- BBBBbbbb
718    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
719    mov     r1, r0, asr #31             @ r1<- ssssssss
720    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
721    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
722    GOTO_OPCODE(ip)                     @ jump to next instruction
723
724/* ------------------------------ */
725    .balign 64
726.L_OP_CONST_WIDE: /* 0x18 */
727/* File: armv5te/OP_CONST_WIDE.S */
728    /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
729    FETCH(r0, 1)                        @ r0<- bbbb (low)
730    FETCH(r1, 2)                        @ r1<- BBBB (low middle)
731    FETCH(r2, 3)                        @ r2<- hhhh (high middle)
732    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb (low word)
733    FETCH(r3, 4)                        @ r3<- HHHH (high)
734    mov     r9, rINST, lsr #8           @ r9<- AA
735    orr     r1, r2, r3, lsl #16         @ r1<- HHHHhhhh (high word)
736    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
737    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
738    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
739    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
740    GOTO_OPCODE(ip)                     @ jump to next instruction
741
742/* ------------------------------ */
743    .balign 64
744.L_OP_CONST_WIDE_HIGH16: /* 0x19 */
745/* File: armv5te/OP_CONST_WIDE_HIGH16.S */
746    /* const-wide/high16 vAA, #+BBBB000000000000 */
747    FETCH(r1, 1)                        @ r1<- 0000BBBB (zero-extended)
748    mov     r3, rINST, lsr #8           @ r3<- AA
749    mov     r0, #0                      @ r0<- 00000000
750    mov     r1, r1, lsl #16             @ r1<- BBBB0000
751    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
752    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
753    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
754    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
755    GOTO_OPCODE(ip)                     @ jump to next instruction
756
757/* ------------------------------ */
758    .balign 64
759.L_OP_CONST_STRING: /* 0x1a */
760/* File: armv5te/OP_CONST_STRING.S */
761    /* const/string vAA, String@BBBB */
762    FETCH(r1, 1)                        @ r1<- BBBB
763    ldr     r2, [rSELF, #offThread_methodClassDex]  @ r2<- self->methodClassDex
764    mov     r9, rINST, lsr #8           @ r9<- AA
765    ldr     r2, [r2, #offDvmDex_pResStrings]   @ r2<- dvmDex->pResStrings
766    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResStrings[BBBB]
767    cmp     r0, #0                      @ not yet resolved?
768    beq     .LOP_CONST_STRING_resolve
769    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
770    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
771    SET_VREG(r0, r9)                    @ vAA<- r0
772    GOTO_OPCODE(ip)                     @ jump to next instruction
773
774/* ------------------------------ */
775    .balign 64
776.L_OP_CONST_STRING_JUMBO: /* 0x1b */
777/* File: armv5te/OP_CONST_STRING_JUMBO.S */
778    /* const/string vAA, String@BBBBBBBB */
779    FETCH(r0, 1)                        @ r0<- bbbb (low)
780    FETCH(r1, 2)                        @ r1<- BBBB (high)
781    ldr     r2, [rSELF, #offThread_methodClassDex]  @ r2<- self->methodClassDex
782    mov     r9, rINST, lsr #8           @ r9<- AA
783    ldr     r2, [r2, #offDvmDex_pResStrings]   @ r2<- dvmDex->pResStrings
784    orr     r1, r0, r1, lsl #16         @ r1<- BBBBbbbb
785    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResStrings[BBBB]
786    cmp     r0, #0
787    beq     .LOP_CONST_STRING_JUMBO_resolve
788    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
789    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
790    SET_VREG(r0, r9)                    @ vAA<- r0
791    GOTO_OPCODE(ip)                     @ jump to next instruction
792
793/* ------------------------------ */
794    .balign 64
795.L_OP_CONST_CLASS: /* 0x1c */
796/* File: armv5te/OP_CONST_CLASS.S */
797    /* const/class vAA, Class@BBBB */
798    FETCH(r1, 1)                        @ r1<- BBBB
799    ldr     r2, [rSELF, #offThread_methodClassDex]  @ r2<- self->methodClassDex
800    mov     r9, rINST, lsr #8           @ r9<- AA
801    ldr     r2, [r2, #offDvmDex_pResClasses]   @ r2<- dvmDex->pResClasses
802    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResClasses[BBBB]
803    cmp     r0, #0                      @ not yet resolved?
804    beq     .LOP_CONST_CLASS_resolve
805    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
806    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
807    SET_VREG(r0, r9)                    @ vAA<- r0
808    GOTO_OPCODE(ip)                     @ jump to next instruction
809
810/* ------------------------------ */
811    .balign 64
812.L_OP_MONITOR_ENTER: /* 0x1d */
813/* File: armv5te/OP_MONITOR_ENTER.S */
814    /*
815     * Synchronize on an object.
816     */
817    /* monitor-enter vAA */
818    mov     r2, rINST, lsr #8           @ r2<- AA
819    GET_VREG(r1, r2)                    @ r1<- vAA (object)
820    mov     r0, rSELF                   @ r0<- self
821    cmp     r1, #0                      @ null object?
822    EXPORT_PC()                         @ need for precise GC
823    beq     common_errNullObject        @ null object, throw an exception
824    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
825    bl      dvmLockObject               @ call(self, obj)
826    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
827    GOTO_OPCODE(ip)                     @ jump to next instruction
828
829/* ------------------------------ */
830    .balign 64
831.L_OP_MONITOR_EXIT: /* 0x1e */
832/* File: armv5te/OP_MONITOR_EXIT.S */
833    /*
834     * Unlock an object.
835     *
836     * Exceptions that occur when unlocking a monitor need to appear as
837     * if they happened at the following instruction.  See the Dalvik
838     * instruction spec.
839     */
840    /* monitor-exit vAA */
841    mov     r2, rINST, lsr #8           @ r2<- AA
842    EXPORT_PC()                         @ before fetch: export the PC
843    GET_VREG(r1, r2)                    @ r1<- vAA (object)
844    cmp     r1, #0                      @ null object?
845    beq     1f                          @ yes
846    mov     r0, rSELF                   @ r0<- self
847    bl      dvmUnlockObject             @ r0<- success for unlock(self, obj)
848    cmp     r0, #0                      @ failed?
849    FETCH_ADVANCE_INST(1)               @ before throw: advance rPC, load rINST
850    beq     common_exceptionThrown      @ yes, exception is pending
851    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
852    GOTO_OPCODE(ip)                     @ jump to next instruction
8531:
854    FETCH_ADVANCE_INST(1)               @ advance before throw
855    b      common_errNullObject
856
857/* ------------------------------ */
858    .balign 64
859.L_OP_CHECK_CAST: /* 0x1f */
860/* File: armv5te/OP_CHECK_CAST.S */
861    /*
862     * Check to see if a cast from one class to another is allowed.
863     */
864    /* check-cast vAA, class@BBBB */
865    mov     r3, rINST, lsr #8           @ r3<- AA
866    FETCH(r2, 1)                        @ r2<- BBBB
867    GET_VREG(r9, r3)                    @ r9<- object
868    ldr     r0, [rSELF, #offThread_methodClassDex]    @ r0<- pDvmDex
869    cmp     r9, #0                      @ is object null?
870    ldr     r0, [r0, #offDvmDex_pResClasses]    @ r0<- pDvmDex->pResClasses
871    beq     .LOP_CHECK_CAST_okay            @ null obj, cast always succeeds
872    ldr     r1, [r0, r2, lsl #2]        @ r1<- resolved class
873    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
874    cmp     r1, #0                      @ have we resolved this before?
875    beq     .LOP_CHECK_CAST_resolve         @ not resolved, do it now
876.LOP_CHECK_CAST_resolved:
877    cmp     r0, r1                      @ same class (trivial success)?
878    bne     .LOP_CHECK_CAST_fullcheck       @ no, do full check
879.LOP_CHECK_CAST_okay:
880    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
881    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
882    GOTO_OPCODE(ip)                     @ jump to next instruction
883
884/* ------------------------------ */
885    .balign 64
886.L_OP_INSTANCE_OF: /* 0x20 */
887/* File: armv5te/OP_INSTANCE_OF.S */
888    /*
889     * Check to see if an object reference is an instance of a class.
890     *
891     * Most common situation is a non-null object, being compared against
892     * an already-resolved class.
893     */
894    /* instance-of vA, vB, class@CCCC */
895    mov     r3, rINST, lsr #12          @ r3<- B
896    mov     r9, rINST, lsr #8           @ r9<- A+
897    GET_VREG(r0, r3)                    @ r0<- vB (object)
898    and     r9, r9, #15                 @ r9<- A
899    cmp     r0, #0                      @ is object null?
900    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- pDvmDex
901    beq     .LOP_INSTANCE_OF_store           @ null obj, not an instance, store r0
902    FETCH(r3, 1)                        @ r3<- CCCC
903    ldr     r2, [r2, #offDvmDex_pResClasses]    @ r2<- pDvmDex->pResClasses
904    ldr     r1, [r2, r3, lsl #2]        @ r1<- resolved class
905    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
906    cmp     r1, #0                      @ have we resolved this before?
907    beq     .LOP_INSTANCE_OF_resolve         @ not resolved, do it now
908.LOP_INSTANCE_OF_resolved: @ r0=obj->clazz, r1=resolved class
909    cmp     r0, r1                      @ same class (trivial success)?
910    beq     .LOP_INSTANCE_OF_trivial         @ yes, trivial finish
911    b       .LOP_INSTANCE_OF_fullcheck       @ no, do full check
912
913/* ------------------------------ */
914    .balign 64
915.L_OP_ARRAY_LENGTH: /* 0x21 */
916/* File: armv6t2/OP_ARRAY_LENGTH.S */
917    /*
918     * Return the length of an array.
919     */
920    mov     r1, rINST, lsr #12          @ r1<- B
921    ubfx    r2, rINST, #8, #4           @ r2<- A
922    GET_VREG(r0, r1)                    @ r0<- vB (object ref)
923    cmp     r0, #0                      @ is object null?
924    beq     common_errNullObject        @ yup, fail
925    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
926    ldr     r3, [r0, #offArrayObject_length]    @ r3<- array length
927    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
928    SET_VREG(r3, r2)                    @ vB<- length
929    GOTO_OPCODE(ip)                     @ jump to next instruction
930
931/* ------------------------------ */
932    .balign 64
933.L_OP_NEW_INSTANCE: /* 0x22 */
934/* File: armv5te/OP_NEW_INSTANCE.S */
935    /*
936     * Create a new instance of a class.
937     */
938    /* new-instance vAA, class@BBBB */
939    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
940    FETCH(r1, 1)                        @ r1<- BBBB
941    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
942    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
943#if defined(WITH_JIT)
944    add     r10, r3, r1, lsl #2         @ r10<- &resolved_class
945#endif
946    EXPORT_PC()                         @ req'd for init, resolve, alloc
947    cmp     r0, #0                      @ already resolved?
948    beq     .LOP_NEW_INSTANCE_resolve         @ no, resolve it now
949.LOP_NEW_INSTANCE_resolved:   @ r0=class
950    ldrb    r1, [r0, #offClassObject_status]    @ r1<- ClassStatus enum
951    cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
952    bne     .LOP_NEW_INSTANCE_needinit        @ no, init class now
953.LOP_NEW_INSTANCE_initialized: @ r0=class
954    mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
955    bl      dvmAllocObject              @ r0<- new object
956    b       .LOP_NEW_INSTANCE_finish          @ continue
957
958/* ------------------------------ */
959    .balign 64
960.L_OP_NEW_ARRAY: /* 0x23 */
961/* File: armv5te/OP_NEW_ARRAY.S */
962    /*
963     * Allocate an array of objects, specified with the array class
964     * and a count.
965     *
966     * The verifier guarantees that this is an array class, so we don't
967     * check for it here.
968     */
969    /* new-array vA, vB, class@CCCC */
970    mov     r0, rINST, lsr #12          @ r0<- B
971    FETCH(r2, 1)                        @ r2<- CCCC
972    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
973    GET_VREG(r1, r0)                    @ r1<- vB (array length)
974    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
975    cmp     r1, #0                      @ check length
976    ldr     r0, [r3, r2, lsl #2]        @ r0<- resolved class
977    bmi     common_errNegativeArraySize @ negative length, bail - len in r1
978    cmp     r0, #0                      @ already resolved?
979    EXPORT_PC()                         @ req'd for resolve, alloc
980    bne     .LOP_NEW_ARRAY_finish          @ resolved, continue
981    b       .LOP_NEW_ARRAY_resolve         @ do resolve now
982
983/* ------------------------------ */
984    .balign 64
985.L_OP_FILLED_NEW_ARRAY: /* 0x24 */
986/* File: armv5te/OP_FILLED_NEW_ARRAY.S */
987    /*
988     * Create a new array with elements filled from registers.
989     *
990     * for: filled-new-array, filled-new-array/range
991     */
992    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
993    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
994    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
995    FETCH(r1, 1)                        @ r1<- BBBB
996    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
997    EXPORT_PC()                         @ need for resolve and alloc
998    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
999    mov     r10, rINST, lsr #8          @ r10<- AA or BA
1000    cmp     r0, #0                      @ already resolved?
1001    bne     .LOP_FILLED_NEW_ARRAY_continue        @ yes, continue on
10028:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
1003    mov     r2, #0                      @ r2<- false
1004    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
1005    bl      dvmResolveClass             @ r0<- call(clazz, ref)
1006    cmp     r0, #0                      @ got null?
1007    beq     common_exceptionThrown      @ yes, handle exception
1008    b       .LOP_FILLED_NEW_ARRAY_continue
1009
1010/* ------------------------------ */
1011    .balign 64
1012.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
1013/* File: armv5te/OP_FILLED_NEW_ARRAY_RANGE.S */
1014/* File: armv5te/OP_FILLED_NEW_ARRAY.S */
1015    /*
1016     * Create a new array with elements filled from registers.
1017     *
1018     * for: filled-new-array, filled-new-array/range
1019     */
1020    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1021    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1022    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
1023    FETCH(r1, 1)                        @ r1<- BBBB
1024    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1025    EXPORT_PC()                         @ need for resolve and alloc
1026    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
1027    mov     r10, rINST, lsr #8          @ r10<- AA or BA
1028    cmp     r0, #0                      @ already resolved?
1029    bne     .LOP_FILLED_NEW_ARRAY_RANGE_continue        @ yes, continue on
10308:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
1031    mov     r2, #0                      @ r2<- false
1032    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
1033    bl      dvmResolveClass             @ r0<- call(clazz, ref)
1034    cmp     r0, #0                      @ got null?
1035    beq     common_exceptionThrown      @ yes, handle exception
1036    b       .LOP_FILLED_NEW_ARRAY_RANGE_continue
1037
1038
1039/* ------------------------------ */
1040    .balign 64
1041.L_OP_FILL_ARRAY_DATA: /* 0x26 */
1042/* File: armv5te/OP_FILL_ARRAY_DATA.S */
1043    /* fill-array-data vAA, +BBBBBBBB */
1044    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1045    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1046    mov     r3, rINST, lsr #8           @ r3<- AA
1047    orr     r1, r0, r1, lsl #16         @ r1<- BBBBbbbb
1048    GET_VREG(r0, r3)                    @ r0<- vAA (array object)
1049    add     r1, rPC, r1, lsl #1         @ r1<- PC + BBBBbbbb*2 (array data off.)
1050    EXPORT_PC();
1051    bl      dvmInterpHandleFillArrayData@ fill the array with predefined data
1052    cmp     r0, #0                      @ 0 means an exception is thrown
1053    beq     common_exceptionThrown      @ has exception
1054    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
1055    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1056    GOTO_OPCODE(ip)                     @ jump to next instruction
1057
1058/* ------------------------------ */
1059    .balign 64
1060.L_OP_THROW: /* 0x27 */
1061/* File: armv5te/OP_THROW.S */
1062    /*
1063     * Throw an exception object in the current thread.
1064     */
1065    /* throw vAA */
1066    mov     r2, rINST, lsr #8           @ r2<- AA
1067    GET_VREG(r1, r2)                    @ r1<- vAA (exception object)
1068    EXPORT_PC()                         @ exception handler can throw
1069    cmp     r1, #0                      @ null object?
1070    beq     common_errNullObject        @ yes, throw an NPE instead
1071    @ bypass dvmSetException, just store it
1072    str     r1, [rSELF, #offThread_exception]  @ thread->exception<- obj
1073    b       common_exceptionThrown
1074
1075/* ------------------------------ */
1076    .balign 64
1077.L_OP_GOTO: /* 0x28 */
1078/* File: armv5te/OP_GOTO.S */
1079    /*
1080     * Unconditional branch, 8-bit offset.
1081     *
1082     * The branch distance is a signed code-unit offset, which we need to
1083     * double to get a byte offset.
1084     */
1085    /* goto +AA */
1086    /* tuning: use sbfx for 6t2+ targets */
1087    mov     r0, rINST, lsl #16          @ r0<- AAxx0000
1088    movs    r1, r0, asr #24             @ r1<- ssssssAA (sign-extended)
1089    add     r2, r1, r1                  @ r2<- byte offset, set flags
1090       @ If backwards branch refresh rIBASE
1091    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1092    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1093#if defined(WITH_JIT)
1094    ldr     r0, [rSELF, #offThread_pJitProfTable]
1095    bmi     common_testUpdateProfile    @ (r0) check for trace hotness
1096#endif
1097    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1098    GOTO_OPCODE(ip)                     @ jump to next instruction
1099
1100/* ------------------------------ */
1101    .balign 64
1102.L_OP_GOTO_16: /* 0x29 */
1103/* File: armv5te/OP_GOTO_16.S */
1104    /*
1105     * Unconditional branch, 16-bit offset.
1106     *
1107     * The branch distance is a signed code-unit offset, which we need to
1108     * double to get a byte offset.
1109     */
1110    /* goto/16 +AAAA */
1111    FETCH_S(r0, 1)                      @ r0<- ssssAAAA (sign-extended)
1112    adds    r1, r0, r0                  @ r1<- byte offset, flags set
1113    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1114    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1115#if defined(WITH_JIT)
1116    ldr     r0, [rSELF, #offThread_pJitProfTable]
1117    bmi     common_testUpdateProfile    @ (r0) hot trace head?
1118#endif
1119    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1120    GOTO_OPCODE(ip)                     @ jump to next instruction
1121
1122/* ------------------------------ */
1123    .balign 64
1124.L_OP_GOTO_32: /* 0x2a */
1125/* File: armv5te/OP_GOTO_32.S */
1126    /*
1127     * Unconditional branch, 32-bit offset.
1128     *
1129     * The branch distance is a signed code-unit offset, which we need to
1130     * double to get a byte offset.
1131     *
1132     * Unlike most opcodes, this one is allowed to branch to itself, so
1133     * our "backward branch" test must be "<=0" instead of "<0".  Because
1134     * we need the V bit set, we'll use an adds to convert from Dalvik
1135     * offset to byte offset.
1136     */
1137    /* goto/32 +AAAAAAAA */
1138    FETCH(r0, 1)                        @ r0<- aaaa (lo)
1139    FETCH(r1, 2)                        @ r1<- AAAA (hi)
1140    orr     r0, r0, r1, lsl #16         @ r0<- AAAAaaaa
1141    adds    r1, r0, r0                  @ r1<- byte offset
1142#if defined(WITH_JIT)
1143    ldr     r0, [rSELF, #offThread_pJitProfTable]
1144    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1145    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1146    ble     common_testUpdateProfile    @ (r0) hot trace head?
1147#else
1148    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1149    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1150#endif
1151    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1152    GOTO_OPCODE(ip)                     @ jump to next instruction
1153
1154/* ------------------------------ */
1155    .balign 64
1156.L_OP_PACKED_SWITCH: /* 0x2b */
1157/* File: armv5te/OP_PACKED_SWITCH.S */
1158    /*
1159     * Handle a packed-switch or sparse-switch instruction.  In both cases
1160     * we decode it and hand it off to a helper function.
1161     *
1162     * We don't really expect backward branches in a switch statement, but
1163     * they're perfectly legal, so we check for them here.
1164     *
1165     * When the JIT is present, all targets are considered treated as
1166     * a potential trace heads regardless of branch direction.
1167     *
1168     * for: packed-switch, sparse-switch
1169     */
1170    /* op vAA, +BBBB */
1171    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1172    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1173    mov     r3, rINST, lsr #8           @ r3<- AA
1174    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
1175    GET_VREG(r1, r3)                    @ r1<- vAA
1176    add     r0, rPC, r0, lsl #1         @ r0<- PC + BBBBbbbb*2
1177    bl      dvmInterpHandlePackedSwitch                       @ r0<- code-unit branch offset
1178    adds    r1, r0, r0                  @ r1<- byte offset; clear V
1179#if defined(WITH_JIT)
1180    ldr     r0, [rSELF, #offThread_pJitProfTable]
1181    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1182    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1183    cmp     r0, #0
1184    bne     common_updateProfile
1185#else
1186    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1187    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1188#endif
1189    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1190    GOTO_OPCODE(ip)                     @ jump to next instruction
1191
1192/* ------------------------------ */
1193    .balign 64
1194.L_OP_SPARSE_SWITCH: /* 0x2c */
1195/* File: armv5te/OP_SPARSE_SWITCH.S */
1196/* File: armv5te/OP_PACKED_SWITCH.S */
1197    /*
1198     * Handle a packed-switch or sparse-switch instruction.  In both cases
1199     * we decode it and hand it off to a helper function.
1200     *
1201     * We don't really expect backward branches in a switch statement, but
1202     * they're perfectly legal, so we check for them here.
1203     *
1204     * When the JIT is present, all targets are considered treated as
1205     * a potential trace heads regardless of branch direction.
1206     *
1207     * for: packed-switch, sparse-switch
1208     */
1209    /* op vAA, +BBBB */
1210    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1211    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1212    mov     r3, rINST, lsr #8           @ r3<- AA
1213    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
1214    GET_VREG(r1, r3)                    @ r1<- vAA
1215    add     r0, rPC, r0, lsl #1         @ r0<- PC + BBBBbbbb*2
1216    bl      dvmInterpHandleSparseSwitch                       @ r0<- code-unit branch offset
1217    adds    r1, r0, r0                  @ r1<- byte offset; clear V
1218#if defined(WITH_JIT)
1219    ldr     r0, [rSELF, #offThread_pJitProfTable]
1220    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1221    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1222    cmp     r0, #0
1223    bne     common_updateProfile
1224#else
1225    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1226    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1227#endif
1228    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1229    GOTO_OPCODE(ip)                     @ jump to next instruction
1230
1231
1232/* ------------------------------ */
1233    .balign 64
1234.L_OP_CMPL_FLOAT: /* 0x2d */
1235/* File: arm-vfp/OP_CMPL_FLOAT.S */
1236    /*
1237     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1238     * destination register based on the results of the comparison.
1239     *
1240     * int compare(x, y) {
1241     *     if (x == y) {
1242     *         return 0;
1243     *     } else if (x > y) {
1244     *         return 1;
1245     *     } else if (x < y) {
1246     *         return -1;
1247     *     } else {
1248     *         return -1;
1249     *     }
1250     * }
1251     */
1252    /* op vAA, vBB, vCC */
1253    FETCH(r0, 1)                        @ r0<- CCBB
1254    mov     r9, rINST, lsr #8           @ r9<- AA
1255    and     r2, r0, #255                @ r2<- BB
1256    mov     r3, r0, lsr #8              @ r3<- CC
1257    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1258    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1259    flds    s0, [r2]                    @ s0<- vBB
1260    flds    s1, [r3]                    @ s1<- vCC
1261    fcmpes  s0, s1                      @ compare (vBB, vCC)
1262    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1263    mvn     r0, #0                      @ r0<- -1 (default)
1264    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1265    fmstat                              @ export status flags
1266    movgt   r0, #1                      @ (greater than) r1<- 1
1267    moveq   r0, #0                      @ (equal) r1<- 0
1268    b       .LOP_CMPL_FLOAT_finish          @ argh
1269
1270
1271/* ------------------------------ */
1272    .balign 64
1273.L_OP_CMPG_FLOAT: /* 0x2e */
1274/* File: arm-vfp/OP_CMPG_FLOAT.S */
1275    /*
1276     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1277     * destination register based on the results of the comparison.
1278     *
1279     * int compare(x, y) {
1280     *     if (x == y) {
1281     *         return 0;
1282     *     } else if (x < y) {
1283     *         return -1;
1284     *     } else if (x > y) {
1285     *         return 1;
1286     *     } else {
1287     *         return 1;
1288     *     }
1289     * }
1290     */
1291    /* op vAA, vBB, vCC */
1292    FETCH(r0, 1)                        @ r0<- CCBB
1293    mov     r9, rINST, lsr #8           @ r9<- AA
1294    and     r2, r0, #255                @ r2<- BB
1295    mov     r3, r0, lsr #8              @ r3<- CC
1296    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1297    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1298    flds    s0, [r2]                    @ s0<- vBB
1299    flds    s1, [r3]                    @ s1<- vCC
1300    fcmpes  s0, s1                      @ compare (vBB, vCC)
1301    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1302    mov     r0, #1                      @ r0<- 1 (default)
1303    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1304    fmstat                              @ export status flags
1305    mvnmi   r0, #0                      @ (less than) r1<- -1
1306    moveq   r0, #0                      @ (equal) r1<- 0
1307    b       .LOP_CMPG_FLOAT_finish          @ argh
1308
1309
1310/* ------------------------------ */
1311    .balign 64
1312.L_OP_CMPL_DOUBLE: /* 0x2f */
1313/* File: arm-vfp/OP_CMPL_DOUBLE.S */
1314    /*
1315     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1316     * destination register based on the results of the comparison.
1317     *
1318     * int compare(x, y) {
1319     *     if (x == y) {
1320     *         return 0;
1321     *     } else if (x > y) {
1322     *         return 1;
1323     *     } else if (x < y) {
1324     *         return -1;
1325     *     } else {
1326     *         return -1;
1327     *     }
1328     * }
1329     */
1330    /* op vAA, vBB, vCC */
1331    FETCH(r0, 1)                        @ r0<- CCBB
1332    mov     r9, rINST, lsr #8           @ r9<- AA
1333    and     r2, r0, #255                @ r2<- BB
1334    mov     r3, r0, lsr #8              @ r3<- CC
1335    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1336    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1337    fldd    d0, [r2]                    @ d0<- vBB
1338    fldd    d1, [r3]                    @ d1<- vCC
1339    fcmped  d0, d1                      @ compare (vBB, vCC)
1340    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1341    mvn     r0, #0                      @ r0<- -1 (default)
1342    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1343    fmstat                              @ export status flags
1344    movgt   r0, #1                      @ (greater than) r1<- 1
1345    moveq   r0, #0                      @ (equal) r1<- 0
1346    b       .LOP_CMPL_DOUBLE_finish          @ argh
1347
1348
1349/* ------------------------------ */
1350    .balign 64
1351.L_OP_CMPG_DOUBLE: /* 0x30 */
1352/* File: arm-vfp/OP_CMPG_DOUBLE.S */
1353    /*
1354     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1355     * destination register based on the results of the comparison.
1356     *
1357     * int compare(x, y) {
1358     *     if (x == y) {
1359     *         return 0;
1360     *     } else if (x < y) {
1361     *         return -1;
1362     *     } else if (x > y) {
1363     *         return 1;
1364     *     } else {
1365     *         return 1;
1366     *     }
1367     * }
1368     */
1369    /* op vAA, vBB, vCC */
1370    FETCH(r0, 1)                        @ r0<- CCBB
1371    mov     r9, rINST, lsr #8           @ r9<- AA
1372    and     r2, r0, #255                @ r2<- BB
1373    mov     r3, r0, lsr #8              @ r3<- CC
1374    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1375    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1376    fldd    d0, [r2]                    @ d0<- vBB
1377    fldd    d1, [r3]                    @ d1<- vCC
1378    fcmped  d0, d1                      @ compare (vBB, vCC)
1379    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1380    mov     r0, #1                      @ r0<- 1 (default)
1381    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1382    fmstat                              @ export status flags
1383    mvnmi   r0, #0                      @ (less than) r1<- -1
1384    moveq   r0, #0                      @ (equal) r1<- 0
1385    b       .LOP_CMPG_DOUBLE_finish          @ argh
1386
1387
1388/* ------------------------------ */
1389    .balign 64
1390.L_OP_CMP_LONG: /* 0x31 */
1391/* File: armv5te/OP_CMP_LONG.S */
1392    /*
1393     * Compare two 64-bit values.  Puts 0, 1, or -1 into the destination
1394     * register based on the results of the comparison.
1395     *
1396     * We load the full values with LDM, but in practice many values could
1397     * be resolved by only looking at the high word.  This could be made
1398     * faster or slower by splitting the LDM into a pair of LDRs.
1399     *
1400     * If we just wanted to set condition flags, we could do this:
1401     *  subs    ip, r0, r2
1402     *  sbcs    ip, r1, r3
1403     *  subeqs  ip, r0, r2
1404     * Leaving { <0, 0, >0 } in ip.  However, we have to set it to a specific
1405     * integer value, which we can do with 2 conditional mov/mvn instructions
1406     * (set 1, set -1; if they're equal we already have 0 in ip), giving
1407     * us a constant 5-cycle path plus a branch at the end to the
1408     * instruction epilogue code.  The multi-compare approach below needs
1409     * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch
1410     * in the worst case (the 64-bit values are equal).
1411     */
1412    /* cmp-long vAA, vBB, vCC */
1413    FETCH(r0, 1)                        @ r0<- CCBB
1414    mov     r9, rINST, lsr #8           @ r9<- AA
1415    and     r2, r0, #255                @ r2<- BB
1416    mov     r3, r0, lsr #8              @ r3<- CC
1417    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
1418    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
1419    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
1420    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
1421    cmp     r1, r3                      @ compare (vBB+1, vCC+1)
1422    blt     .LOP_CMP_LONG_less            @ signed compare on high part
1423    bgt     .LOP_CMP_LONG_greater
1424    subs    r1, r0, r2                  @ r1<- r0 - r2
1425    bhi     .LOP_CMP_LONG_greater         @ unsigned compare on low part
1426    bne     .LOP_CMP_LONG_less
1427    b       .LOP_CMP_LONG_finish          @ equal; r1 already holds 0
1428
1429/* ------------------------------ */
1430    .balign 64
1431.L_OP_IF_EQ: /* 0x32 */
1432/* File: armv6t2/OP_IF_EQ.S */
1433/* File: armv6t2/bincmp.S */
1434    /*
1435     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1436     * fragment that specifies the *reverse* comparison to perform, e.g.
1437     * for "if-le" you would use "gt".
1438     *
1439     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1440     */
1441    /* if-cmp vA, vB, +CCCC */
1442    mov     r1, rINST, lsr #12          @ r1<- B
1443    ubfx    r0, rINST, #8, #4           @ r0<- A
1444    GET_VREG(r3, r1)                    @ r3<- vB
1445    GET_VREG(r2, r0)                    @ r2<- vA
1446    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1447    cmp     r2, r3                      @ compare (vA, vB)
1448    movne r1, #2                 @ r1<- BYTE branch dist for not-taken
1449    adds    r2, r1, r1                  @ convert to bytes, check sign
1450    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1451#if defined(WITH_JIT)
1452    ldr     r0, [rSELF, #offThread_pJitProfTable]
1453    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1454    cmp     r0, #0
1455    bne     common_updateProfile
1456#else
1457    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1458#endif
1459    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1460    GOTO_OPCODE(ip)                     @ jump to next instruction
1461
1462
1463/* ------------------------------ */
1464    .balign 64
1465.L_OP_IF_NE: /* 0x33 */
1466/* File: armv6t2/OP_IF_NE.S */
1467/* File: armv6t2/bincmp.S */
1468    /*
1469     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1470     * fragment that specifies the *reverse* comparison to perform, e.g.
1471     * for "if-le" you would use "gt".
1472     *
1473     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1474     */
1475    /* if-cmp vA, vB, +CCCC */
1476    mov     r1, rINST, lsr #12          @ r1<- B
1477    ubfx    r0, rINST, #8, #4           @ r0<- A
1478    GET_VREG(r3, r1)                    @ r3<- vB
1479    GET_VREG(r2, r0)                    @ r2<- vA
1480    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1481    cmp     r2, r3                      @ compare (vA, vB)
1482    moveq r1, #2                 @ r1<- BYTE branch dist for not-taken
1483    adds    r2, r1, r1                  @ convert to bytes, check sign
1484    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1485#if defined(WITH_JIT)
1486    ldr     r0, [rSELF, #offThread_pJitProfTable]
1487    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1488    cmp     r0, #0
1489    bne     common_updateProfile
1490#else
1491    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1492#endif
1493    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1494    GOTO_OPCODE(ip)                     @ jump to next instruction
1495
1496
1497/* ------------------------------ */
1498    .balign 64
1499.L_OP_IF_LT: /* 0x34 */
1500/* File: armv6t2/OP_IF_LT.S */
1501/* File: armv6t2/bincmp.S */
1502    /*
1503     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1504     * fragment that specifies the *reverse* comparison to perform, e.g.
1505     * for "if-le" you would use "gt".
1506     *
1507     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1508     */
1509    /* if-cmp vA, vB, +CCCC */
1510    mov     r1, rINST, lsr #12          @ r1<- B
1511    ubfx    r0, rINST, #8, #4           @ r0<- A
1512    GET_VREG(r3, r1)                    @ r3<- vB
1513    GET_VREG(r2, r0)                    @ r2<- vA
1514    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1515    cmp     r2, r3                      @ compare (vA, vB)
1516    movge r1, #2                 @ r1<- BYTE branch dist for not-taken
1517    adds    r2, r1, r1                  @ convert to bytes, check sign
1518    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1519#if defined(WITH_JIT)
1520    ldr     r0, [rSELF, #offThread_pJitProfTable]
1521    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1522    cmp     r0, #0
1523    bne     common_updateProfile
1524#else
1525    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1526#endif
1527    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1528    GOTO_OPCODE(ip)                     @ jump to next instruction
1529
1530
1531/* ------------------------------ */
1532    .balign 64
1533.L_OP_IF_GE: /* 0x35 */
1534/* File: armv6t2/OP_IF_GE.S */
1535/* File: armv6t2/bincmp.S */
1536    /*
1537     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1538     * fragment that specifies the *reverse* comparison to perform, e.g.
1539     * for "if-le" you would use "gt".
1540     *
1541     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1542     */
1543    /* if-cmp vA, vB, +CCCC */
1544    mov     r1, rINST, lsr #12          @ r1<- B
1545    ubfx    r0, rINST, #8, #4           @ r0<- A
1546    GET_VREG(r3, r1)                    @ r3<- vB
1547    GET_VREG(r2, r0)                    @ r2<- vA
1548    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1549    cmp     r2, r3                      @ compare (vA, vB)
1550    movlt r1, #2                 @ r1<- BYTE branch dist for not-taken
1551    adds    r2, r1, r1                  @ convert to bytes, check sign
1552    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1553#if defined(WITH_JIT)
1554    ldr     r0, [rSELF, #offThread_pJitProfTable]
1555    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1556    cmp     r0, #0
1557    bne     common_updateProfile
1558#else
1559    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1560#endif
1561    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1562    GOTO_OPCODE(ip)                     @ jump to next instruction
1563
1564
1565/* ------------------------------ */
1566    .balign 64
1567.L_OP_IF_GT: /* 0x36 */
1568/* File: armv6t2/OP_IF_GT.S */
1569/* File: armv6t2/bincmp.S */
1570    /*
1571     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1572     * fragment that specifies the *reverse* comparison to perform, e.g.
1573     * for "if-le" you would use "gt".
1574     *
1575     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1576     */
1577    /* if-cmp vA, vB, +CCCC */
1578    mov     r1, rINST, lsr #12          @ r1<- B
1579    ubfx    r0, rINST, #8, #4           @ r0<- A
1580    GET_VREG(r3, r1)                    @ r3<- vB
1581    GET_VREG(r2, r0)                    @ r2<- vA
1582    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1583    cmp     r2, r3                      @ compare (vA, vB)
1584    movle r1, #2                 @ r1<- BYTE branch dist for not-taken
1585    adds    r2, r1, r1                  @ convert to bytes, check sign
1586    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1587#if defined(WITH_JIT)
1588    ldr     r0, [rSELF, #offThread_pJitProfTable]
1589    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1590    cmp     r0, #0
1591    bne     common_updateProfile
1592#else
1593    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1594#endif
1595    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1596    GOTO_OPCODE(ip)                     @ jump to next instruction
1597
1598
1599/* ------------------------------ */
1600    .balign 64
1601.L_OP_IF_LE: /* 0x37 */
1602/* File: armv6t2/OP_IF_LE.S */
1603/* File: armv6t2/bincmp.S */
1604    /*
1605     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1606     * fragment that specifies the *reverse* comparison to perform, e.g.
1607     * for "if-le" you would use "gt".
1608     *
1609     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1610     */
1611    /* if-cmp vA, vB, +CCCC */
1612    mov     r1, rINST, lsr #12          @ r1<- B
1613    ubfx    r0, rINST, #8, #4           @ r0<- A
1614    GET_VREG(r3, r1)                    @ r3<- vB
1615    GET_VREG(r2, r0)                    @ r2<- vA
1616    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1617    cmp     r2, r3                      @ compare (vA, vB)
1618    movgt r1, #2                 @ r1<- BYTE branch dist for not-taken
1619    adds    r2, r1, r1                  @ convert to bytes, check sign
1620    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1621#if defined(WITH_JIT)
1622    ldr     r0, [rSELF, #offThread_pJitProfTable]
1623    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1624    cmp     r0, #0
1625    bne     common_updateProfile
1626#else
1627    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1628#endif
1629    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1630    GOTO_OPCODE(ip)                     @ jump to next instruction
1631
1632
1633/* ------------------------------ */
1634    .balign 64
1635.L_OP_IF_EQZ: /* 0x38 */
1636/* File: armv5te/OP_IF_EQZ.S */
1637/* File: armv5te/zcmp.S */
1638    /*
1639     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1640     * fragment that specifies the *reverse* comparison to perform, e.g.
1641     * for "if-le" you would use "gt".
1642     *
1643     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1644     */
1645    /* if-cmp vAA, +BBBB */
1646    mov     r0, rINST, lsr #8           @ r0<- AA
1647    GET_VREG(r2, r0)                    @ r2<- vAA
1648    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1649    cmp     r2, #0                      @ compare (vA, 0)
1650    movne r1, #2                 @ r1<- inst branch dist for not-taken
1651    adds    r1, r1, r1                  @ convert to bytes & set flags
1652    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1653#if defined(WITH_JIT)
1654    ldr     r0, [rSELF, #offThread_pJitProfTable]
1655    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1656    cmp     r0,#0
1657    bne     common_updateProfile        @ test for JIT off at target
1658#else
1659    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1660#endif
1661    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1662    GOTO_OPCODE(ip)                     @ jump to next instruction
1663
1664
1665/* ------------------------------ */
1666    .balign 64
1667.L_OP_IF_NEZ: /* 0x39 */
1668/* File: armv5te/OP_IF_NEZ.S */
1669/* File: armv5te/zcmp.S */
1670    /*
1671     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1672     * fragment that specifies the *reverse* comparison to perform, e.g.
1673     * for "if-le" you would use "gt".
1674     *
1675     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1676     */
1677    /* if-cmp vAA, +BBBB */
1678    mov     r0, rINST, lsr #8           @ r0<- AA
1679    GET_VREG(r2, r0)                    @ r2<- vAA
1680    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1681    cmp     r2, #0                      @ compare (vA, 0)
1682    moveq r1, #2                 @ r1<- inst branch dist for not-taken
1683    adds    r1, r1, r1                  @ convert to bytes & set flags
1684    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1685#if defined(WITH_JIT)
1686    ldr     r0, [rSELF, #offThread_pJitProfTable]
1687    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1688    cmp     r0,#0
1689    bne     common_updateProfile        @ test for JIT off at target
1690#else
1691    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1692#endif
1693    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1694    GOTO_OPCODE(ip)                     @ jump to next instruction
1695
1696
1697/* ------------------------------ */
1698    .balign 64
1699.L_OP_IF_LTZ: /* 0x3a */
1700/* File: armv5te/OP_IF_LTZ.S */
1701/* File: armv5te/zcmp.S */
1702    /*
1703     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1704     * fragment that specifies the *reverse* comparison to perform, e.g.
1705     * for "if-le" you would use "gt".
1706     *
1707     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1708     */
1709    /* if-cmp vAA, +BBBB */
1710    mov     r0, rINST, lsr #8           @ r0<- AA
1711    GET_VREG(r2, r0)                    @ r2<- vAA
1712    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1713    cmp     r2, #0                      @ compare (vA, 0)
1714    movge r1, #2                 @ r1<- inst branch dist for not-taken
1715    adds    r1, r1, r1                  @ convert to bytes & set flags
1716    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1717#if defined(WITH_JIT)
1718    ldr     r0, [rSELF, #offThread_pJitProfTable]
1719    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1720    cmp     r0,#0
1721    bne     common_updateProfile        @ test for JIT off at target
1722#else
1723    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1724#endif
1725    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1726    GOTO_OPCODE(ip)                     @ jump to next instruction
1727
1728
1729/* ------------------------------ */
1730    .balign 64
1731.L_OP_IF_GEZ: /* 0x3b */
1732/* File: armv5te/OP_IF_GEZ.S */
1733/* File: armv5te/zcmp.S */
1734    /*
1735     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1736     * fragment that specifies the *reverse* comparison to perform, e.g.
1737     * for "if-le" you would use "gt".
1738     *
1739     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1740     */
1741    /* if-cmp vAA, +BBBB */
1742    mov     r0, rINST, lsr #8           @ r0<- AA
1743    GET_VREG(r2, r0)                    @ r2<- vAA
1744    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1745    cmp     r2, #0                      @ compare (vA, 0)
1746    movlt r1, #2                 @ r1<- inst branch dist for not-taken
1747    adds    r1, r1, r1                  @ convert to bytes & set flags
1748    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1749#if defined(WITH_JIT)
1750    ldr     r0, [rSELF, #offThread_pJitProfTable]
1751    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1752    cmp     r0,#0
1753    bne     common_updateProfile        @ test for JIT off at target
1754#else
1755    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1756#endif
1757    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1758    GOTO_OPCODE(ip)                     @ jump to next instruction
1759
1760
1761/* ------------------------------ */
1762    .balign 64
1763.L_OP_IF_GTZ: /* 0x3c */
1764/* File: armv5te/OP_IF_GTZ.S */
1765/* File: armv5te/zcmp.S */
1766    /*
1767     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1768     * fragment that specifies the *reverse* comparison to perform, e.g.
1769     * for "if-le" you would use "gt".
1770     *
1771     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1772     */
1773    /* if-cmp vAA, +BBBB */
1774    mov     r0, rINST, lsr #8           @ r0<- AA
1775    GET_VREG(r2, r0)                    @ r2<- vAA
1776    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1777    cmp     r2, #0                      @ compare (vA, 0)
1778    movle r1, #2                 @ r1<- inst branch dist for not-taken
1779    adds    r1, r1, r1                  @ convert to bytes & set flags
1780    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1781#if defined(WITH_JIT)
1782    ldr     r0, [rSELF, #offThread_pJitProfTable]
1783    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1784    cmp     r0,#0
1785    bne     common_updateProfile        @ test for JIT off at target
1786#else
1787    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1788#endif
1789    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1790    GOTO_OPCODE(ip)                     @ jump to next instruction
1791
1792
1793/* ------------------------------ */
1794    .balign 64
1795.L_OP_IF_LEZ: /* 0x3d */
1796/* File: armv5te/OP_IF_LEZ.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    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1809    cmp     r2, #0                      @ compare (vA, 0)
1810    movgt r1, #2                 @ r1<- inst branch dist for not-taken
1811    adds    r1, r1, r1                  @ convert to bytes & set flags
1812    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1813#if defined(WITH_JIT)
1814    ldr     r0, [rSELF, #offThread_pJitProfTable]
1815    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1816    cmp     r0,#0
1817    bne     common_updateProfile        @ test for JIT off at target
1818#else
1819    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1820#endif
1821    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1822    GOTO_OPCODE(ip)                     @ jump to next instruction
1823
1824
1825/* ------------------------------ */
1826    .balign 64
1827.L_OP_UNUSED_3E: /* 0x3e */
1828/* File: armv5te/OP_UNUSED_3E.S */
1829/* File: armv5te/unused.S */
1830    bl      common_abort
1831
1832
1833/* ------------------------------ */
1834    .balign 64
1835.L_OP_UNUSED_3F: /* 0x3f */
1836/* File: armv5te/OP_UNUSED_3F.S */
1837/* File: armv5te/unused.S */
1838    bl      common_abort
1839
1840
1841/* ------------------------------ */
1842    .balign 64
1843.L_OP_UNUSED_40: /* 0x40 */
1844/* File: armv5te/OP_UNUSED_40.S */
1845/* File: armv5te/unused.S */
1846    bl      common_abort
1847
1848
1849/* ------------------------------ */
1850    .balign 64
1851.L_OP_UNUSED_41: /* 0x41 */
1852/* File: armv5te/OP_UNUSED_41.S */
1853/* File: armv5te/unused.S */
1854    bl      common_abort
1855
1856
1857/* ------------------------------ */
1858    .balign 64
1859.L_OP_UNUSED_42: /* 0x42 */
1860/* File: armv5te/OP_UNUSED_42.S */
1861/* File: armv5te/unused.S */
1862    bl      common_abort
1863
1864
1865/* ------------------------------ */
1866    .balign 64
1867.L_OP_UNUSED_43: /* 0x43 */
1868/* File: armv5te/OP_UNUSED_43.S */
1869/* File: armv5te/unused.S */
1870    bl      common_abort
1871
1872
1873/* ------------------------------ */
1874    .balign 64
1875.L_OP_AGET: /* 0x44 */
1876/* File: armv5te/OP_AGET.S */
1877    /*
1878     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1879     *
1880     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
1881     * instructions.  We use a pair of FETCH_Bs instead.
1882     *
1883     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1884     */
1885    /* op vAA, vBB, vCC */
1886    FETCH_B(r2, 1, 0)                   @ r2<- BB
1887    mov     r9, rINST, lsr #8           @ r9<- AA
1888    FETCH_B(r3, 1, 1)                   @ r3<- CC
1889    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1890    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1891    cmp     r0, #0                      @ null array object?
1892    beq     common_errNullObject        @ yes, bail
1893    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1894    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
1895    cmp     r1, r3                      @ compare unsigned index, length
1896    bcs     common_errArrayIndex        @ index >= length, bail
1897    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1898    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
1899    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1900    SET_VREG(r2, r9)                    @ vAA<- r2
1901    GOTO_OPCODE(ip)                     @ jump to next instruction
1902
1903/* ------------------------------ */
1904    .balign 64
1905.L_OP_AGET_WIDE: /* 0x45 */
1906/* File: armv5te/OP_AGET_WIDE.S */
1907    /*
1908     * Array get, 64 bits.  vAA <- vBB[vCC].
1909     *
1910     * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD.
1911     */
1912    /* aget-wide vAA, vBB, vCC */
1913    FETCH(r0, 1)                        @ r0<- CCBB
1914    mov     r9, rINST, lsr #8           @ r9<- AA
1915    and     r2, r0, #255                @ r2<- BB
1916    mov     r3, r0, lsr #8              @ r3<- CC
1917    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1918    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1919    cmp     r0, #0                      @ null array object?
1920    beq     common_errNullObject        @ yes, bail
1921    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1922    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
1923    cmp     r1, r3                      @ compare unsigned index, length
1924    bcc     .LOP_AGET_WIDE_finish          @ okay, continue below
1925    b       common_errArrayIndex        @ index >= length, bail
1926    @ May want to swap the order of these two branches depending on how the
1927    @ branch prediction (if any) handles conditional forward branches vs.
1928    @ unconditional forward branches.
1929
1930/* ------------------------------ */
1931    .balign 64
1932.L_OP_AGET_OBJECT: /* 0x46 */
1933/* File: armv5te/OP_AGET_OBJECT.S */
1934/* File: armv5te/OP_AGET.S */
1935    /*
1936     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1937     *
1938     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
1939     * instructions.  We use a pair of FETCH_Bs instead.
1940     *
1941     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1942     */
1943    /* op vAA, vBB, vCC */
1944    FETCH_B(r2, 1, 0)                   @ r2<- BB
1945    mov     r9, rINST, lsr #8           @ r9<- AA
1946    FETCH_B(r3, 1, 1)                   @ r3<- CC
1947    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1948    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1949    cmp     r0, #0                      @ null array object?
1950    beq     common_errNullObject        @ yes, bail
1951    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1952    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
1953    cmp     r1, r3                      @ compare unsigned index, length
1954    bcs     common_errArrayIndex        @ index >= length, bail
1955    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1956    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
1957    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1958    SET_VREG(r2, r9)                    @ vAA<- r2
1959    GOTO_OPCODE(ip)                     @ jump to next instruction
1960
1961
1962/* ------------------------------ */
1963    .balign 64
1964.L_OP_AGET_BOOLEAN: /* 0x47 */
1965/* File: armv5te/OP_AGET_BOOLEAN.S */
1966/* File: armv5te/OP_AGET.S */
1967    /*
1968     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1969     *
1970     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
1971     * instructions.  We use a pair of FETCH_Bs instead.
1972     *
1973     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1974     */
1975    /* op vAA, vBB, vCC */
1976    FETCH_B(r2, 1, 0)                   @ r2<- BB
1977    mov     r9, rINST, lsr #8           @ r9<- AA
1978    FETCH_B(r3, 1, 1)                   @ r3<- CC
1979    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1980    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1981    cmp     r0, #0                      @ null array object?
1982    beq     common_errNullObject        @ yes, bail
1983    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1984    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
1985    cmp     r1, r3                      @ compare unsigned index, length
1986    bcs     common_errArrayIndex        @ index >= length, bail
1987    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1988    ldrb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
1989    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1990    SET_VREG(r2, r9)                    @ vAA<- r2
1991    GOTO_OPCODE(ip)                     @ jump to next instruction
1992
1993
1994/* ------------------------------ */
1995    .balign 64
1996.L_OP_AGET_BYTE: /* 0x48 */
1997/* File: armv5te/OP_AGET_BYTE.S */
1998/* File: armv5te/OP_AGET.S */
1999    /*
2000     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2001     *
2002     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2003     * instructions.  We use a pair of FETCH_Bs instead.
2004     *
2005     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2006     */
2007    /* op vAA, vBB, vCC */
2008    FETCH_B(r2, 1, 0)                   @ r2<- BB
2009    mov     r9, rINST, lsr #8           @ r9<- AA
2010    FETCH_B(r3, 1, 1)                   @ r3<- CC
2011    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2012    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2013    cmp     r0, #0                      @ null array object?
2014    beq     common_errNullObject        @ yes, bail
2015    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2016    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2017    cmp     r1, r3                      @ compare unsigned index, length
2018    bcs     common_errArrayIndex        @ index >= length, bail
2019    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2020    ldrsb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2021    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2022    SET_VREG(r2, r9)                    @ vAA<- r2
2023    GOTO_OPCODE(ip)                     @ jump to next instruction
2024
2025
2026/* ------------------------------ */
2027    .balign 64
2028.L_OP_AGET_CHAR: /* 0x49 */
2029/* File: armv5te/OP_AGET_CHAR.S */
2030/* File: armv5te/OP_AGET.S */
2031    /*
2032     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2033     *
2034     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2035     * instructions.  We use a pair of FETCH_Bs instead.
2036     *
2037     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2038     */
2039    /* op vAA, vBB, vCC */
2040    FETCH_B(r2, 1, 0)                   @ r2<- BB
2041    mov     r9, rINST, lsr #8           @ r9<- AA
2042    FETCH_B(r3, 1, 1)                   @ r3<- CC
2043    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2044    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2045    cmp     r0, #0                      @ null array object?
2046    beq     common_errNullObject        @ yes, bail
2047    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2048    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2049    cmp     r1, r3                      @ compare unsigned index, length
2050    bcs     common_errArrayIndex        @ index >= length, bail
2051    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2052    ldrh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2053    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2054    SET_VREG(r2, r9)                    @ vAA<- r2
2055    GOTO_OPCODE(ip)                     @ jump to next instruction
2056
2057
2058/* ------------------------------ */
2059    .balign 64
2060.L_OP_AGET_SHORT: /* 0x4a */
2061/* File: armv5te/OP_AGET_SHORT.S */
2062/* File: armv5te/OP_AGET.S */
2063    /*
2064     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2065     *
2066     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2067     * instructions.  We use a pair of FETCH_Bs instead.
2068     *
2069     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2070     */
2071    /* op vAA, vBB, vCC */
2072    FETCH_B(r2, 1, 0)                   @ r2<- BB
2073    mov     r9, rINST, lsr #8           @ r9<- AA
2074    FETCH_B(r3, 1, 1)                   @ r3<- CC
2075    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2076    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2077    cmp     r0, #0                      @ null array object?
2078    beq     common_errNullObject        @ yes, bail
2079    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2080    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2081    cmp     r1, r3                      @ compare unsigned index, length
2082    bcs     common_errArrayIndex        @ index >= length, bail
2083    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2084    ldrsh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2085    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2086    SET_VREG(r2, r9)                    @ vAA<- r2
2087    GOTO_OPCODE(ip)                     @ jump to next instruction
2088
2089
2090/* ------------------------------ */
2091    .balign 64
2092.L_OP_APUT: /* 0x4b */
2093/* File: armv5te/OP_APUT.S */
2094    /*
2095     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2096     *
2097     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2098     * instructions.  We use a pair of FETCH_Bs instead.
2099     *
2100     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2101     */
2102    /* op vAA, vBB, vCC */
2103    FETCH_B(r2, 1, 0)                   @ r2<- BB
2104    mov     r9, rINST, lsr #8           @ r9<- AA
2105    FETCH_B(r3, 1, 1)                   @ r3<- CC
2106    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2107    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2108    cmp     r0, #0                      @ null array object?
2109    beq     common_errNullObject        @ yes, bail
2110    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2111    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
2112    cmp     r1, r3                      @ compare unsigned index, length
2113    bcs     common_errArrayIndex        @ index >= length, bail
2114    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2115    GET_VREG(r2, r9)                    @ r2<- vAA
2116    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2117    str  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2118    GOTO_OPCODE(ip)                     @ jump to next instruction
2119
2120/* ------------------------------ */
2121    .balign 64
2122.L_OP_APUT_WIDE: /* 0x4c */
2123/* File: armv5te/OP_APUT_WIDE.S */
2124    /*
2125     * Array put, 64 bits.  vBB[vCC] <- vAA.
2126     *
2127     * Arrays of long/double are 64-bit aligned, so it's okay to use STRD.
2128     */
2129    /* aput-wide vAA, vBB, vCC */
2130    FETCH(r0, 1)                        @ r0<- CCBB
2131    mov     r9, rINST, lsr #8           @ r9<- AA
2132    and     r2, r0, #255                @ r2<- BB
2133    mov     r3, r0, lsr #8              @ r3<- CC
2134    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2135    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2136    cmp     r0, #0                      @ null array object?
2137    beq     common_errNullObject        @ yes, bail
2138    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2139    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
2140    cmp     r1, r3                      @ compare unsigned index, length
2141    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2142    bcc     .LOP_APUT_WIDE_finish          @ okay, continue below
2143    b       common_errArrayIndex        @ index >= length, bail
2144    @ May want to swap the order of these two branches depending on how the
2145    @ branch prediction (if any) handles conditional forward branches vs.
2146    @ unconditional forward branches.
2147
2148/* ------------------------------ */
2149    .balign 64
2150.L_OP_APUT_OBJECT: /* 0x4d */
2151/* File: armv5te/OP_APUT_OBJECT.S */
2152    /*
2153     * Store an object into an array.  vBB[vCC] <- vAA.
2154     */
2155    /* op vAA, vBB, vCC */
2156    FETCH(r0, 1)                        @ r0<- CCBB
2157    mov     r9, rINST, lsr #8           @ r9<- AA
2158    and     r2, r0, #255                @ r2<- BB
2159    mov     r3, r0, lsr #8              @ r3<- CC
2160    GET_VREG(rINST, r2)                 @ rINST<- vBB (array object)
2161    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2162    cmp     rINST, #0                   @ null array object?
2163    GET_VREG(r9, r9)                    @ r9<- vAA
2164    beq     common_errNullObject        @ yes, bail
2165    ldr     r3, [rINST, #offArrayObject_length]   @ r3<- arrayObj->length
2166    add     r10, rINST, r1, lsl #2      @ r10<- arrayObj + index*width
2167    cmp     r1, r3                      @ compare unsigned index, length
2168    bcc     .LOP_APUT_OBJECT_finish          @ we're okay, continue on
2169    b       common_errArrayIndex        @ index >= length, bail
2170
2171
2172/* ------------------------------ */
2173    .balign 64
2174.L_OP_APUT_BOOLEAN: /* 0x4e */
2175/* File: armv5te/OP_APUT_BOOLEAN.S */
2176/* File: armv5te/OP_APUT.S */
2177    /*
2178     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2179     *
2180     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2181     * instructions.  We use a pair of FETCH_Bs instead.
2182     *
2183     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2184     */
2185    /* op vAA, vBB, vCC */
2186    FETCH_B(r2, 1, 0)                   @ r2<- BB
2187    mov     r9, rINST, lsr #8           @ r9<- AA
2188    FETCH_B(r3, 1, 1)                   @ r3<- CC
2189    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2190    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2191    cmp     r0, #0                      @ null array object?
2192    beq     common_errNullObject        @ yes, bail
2193    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2194    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2195    cmp     r1, r3                      @ compare unsigned index, length
2196    bcs     common_errArrayIndex        @ index >= length, bail
2197    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2198    GET_VREG(r2, r9)                    @ r2<- vAA
2199    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2200    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2201    GOTO_OPCODE(ip)                     @ jump to next instruction
2202
2203
2204/* ------------------------------ */
2205    .balign 64
2206.L_OP_APUT_BYTE: /* 0x4f */
2207/* File: armv5te/OP_APUT_BYTE.S */
2208/* File: armv5te/OP_APUT.S */
2209    /*
2210     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2211     *
2212     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2213     * instructions.  We use a pair of FETCH_Bs instead.
2214     *
2215     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2216     */
2217    /* op vAA, vBB, vCC */
2218    FETCH_B(r2, 1, 0)                   @ r2<- BB
2219    mov     r9, rINST, lsr #8           @ r9<- AA
2220    FETCH_B(r3, 1, 1)                   @ r3<- CC
2221    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2222    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2223    cmp     r0, #0                      @ null array object?
2224    beq     common_errNullObject        @ yes, bail
2225    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2226    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2227    cmp     r1, r3                      @ compare unsigned index, length
2228    bcs     common_errArrayIndex        @ index >= length, bail
2229    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2230    GET_VREG(r2, r9)                    @ r2<- vAA
2231    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2232    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2233    GOTO_OPCODE(ip)                     @ jump to next instruction
2234
2235
2236/* ------------------------------ */
2237    .balign 64
2238.L_OP_APUT_CHAR: /* 0x50 */
2239/* File: armv5te/OP_APUT_CHAR.S */
2240/* File: armv5te/OP_APUT.S */
2241    /*
2242     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2243     *
2244     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2245     * instructions.  We use a pair of FETCH_Bs instead.
2246     *
2247     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2248     */
2249    /* op vAA, vBB, vCC */
2250    FETCH_B(r2, 1, 0)                   @ r2<- BB
2251    mov     r9, rINST, lsr #8           @ r9<- AA
2252    FETCH_B(r3, 1, 1)                   @ r3<- CC
2253    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2254    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2255    cmp     r0, #0                      @ null array object?
2256    beq     common_errNullObject        @ yes, bail
2257    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2258    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2259    cmp     r1, r3                      @ compare unsigned index, length
2260    bcs     common_errArrayIndex        @ index >= length, bail
2261    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2262    GET_VREG(r2, r9)                    @ r2<- vAA
2263    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2264    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2265    GOTO_OPCODE(ip)                     @ jump to next instruction
2266
2267
2268/* ------------------------------ */
2269    .balign 64
2270.L_OP_APUT_SHORT: /* 0x51 */
2271/* File: armv5te/OP_APUT_SHORT.S */
2272/* File: armv5te/OP_APUT.S */
2273    /*
2274     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2275     *
2276     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2277     * instructions.  We use a pair of FETCH_Bs instead.
2278     *
2279     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2280     */
2281    /* op vAA, vBB, vCC */
2282    FETCH_B(r2, 1, 0)                   @ r2<- BB
2283    mov     r9, rINST, lsr #8           @ r9<- AA
2284    FETCH_B(r3, 1, 1)                   @ r3<- CC
2285    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2286    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2287    cmp     r0, #0                      @ null array object?
2288    beq     common_errNullObject        @ yes, bail
2289    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2290    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2291    cmp     r1, r3                      @ compare unsigned index, length
2292    bcs     common_errArrayIndex        @ index >= length, bail
2293    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2294    GET_VREG(r2, r9)                    @ r2<- vAA
2295    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2296    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2297    GOTO_OPCODE(ip)                     @ jump to next instruction
2298
2299
2300/* ------------------------------ */
2301    .balign 64
2302.L_OP_IGET: /* 0x52 */
2303/* File: armv6t2/OP_IGET.S */
2304    /*
2305     * General 32-bit instance field get.
2306     *
2307     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2308     */
2309    /* op vA, vB, field@CCCC */
2310    mov     r0, rINST, lsr #12          @ r0<- B
2311    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2312    FETCH(r1, 1)                        @ r1<- field ref CCCC
2313    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2314    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2315    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2316    cmp     r0, #0                      @ is resolved entry null?
2317    bne     .LOP_IGET_finish          @ no, already resolved
23188:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2319    EXPORT_PC()                         @ resolve() could throw
2320    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2321    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2322    cmp     r0, #0
2323    bne     .LOP_IGET_finish
2324    b       common_exceptionThrown
2325
2326/* ------------------------------ */
2327    .balign 64
2328.L_OP_IGET_WIDE: /* 0x53 */
2329/* File: armv6t2/OP_IGET_WIDE.S */
2330    /*
2331     * Wide 32-bit instance field get.
2332     */
2333    /* iget-wide vA, vB, field@CCCC */
2334    mov     r0, rINST, lsr #12          @ r0<- B
2335    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2336    FETCH(r1, 1)                        @ r1<- field ref CCCC
2337    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
2338    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2339    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2340    cmp     r0, #0                      @ is resolved entry null?
2341    bne     .LOP_IGET_WIDE_finish          @ no, already resolved
23428:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
2343    EXPORT_PC()                         @ resolve() could throw
2344    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2345    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2346    cmp     r0, #0
2347    bne     .LOP_IGET_WIDE_finish
2348    b       common_exceptionThrown
2349
2350/* ------------------------------ */
2351    .balign 64
2352.L_OP_IGET_OBJECT: /* 0x54 */
2353/* File: armv5te/OP_IGET_OBJECT.S */
2354/* File: armv5te/OP_IGET.S */
2355    /*
2356     * General 32-bit instance field get.
2357     *
2358     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2359     */
2360    /* op vA, vB, field@CCCC */
2361    mov     r0, rINST, lsr #12          @ r0<- B
2362    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2363    FETCH(r1, 1)                        @ r1<- field ref CCCC
2364    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2365    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2366    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2367    cmp     r0, #0                      @ is resolved entry null?
2368    bne     .LOP_IGET_OBJECT_finish          @ no, already resolved
23698:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2370    EXPORT_PC()                         @ resolve() could throw
2371    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2372    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2373    cmp     r0, #0
2374    bne     .LOP_IGET_OBJECT_finish
2375    b       common_exceptionThrown
2376
2377
2378/* ------------------------------ */
2379    .balign 64
2380.L_OP_IGET_BOOLEAN: /* 0x55 */
2381/* File: armv5te/OP_IGET_BOOLEAN.S */
2382@include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" }
2383/* File: armv5te/OP_IGET.S */
2384    /*
2385     * General 32-bit instance field get.
2386     *
2387     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2388     */
2389    /* op vA, vB, field@CCCC */
2390    mov     r0, rINST, lsr #12          @ r0<- B
2391    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2392    FETCH(r1, 1)                        @ r1<- field ref CCCC
2393    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2394    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2395    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2396    cmp     r0, #0                      @ is resolved entry null?
2397    bne     .LOP_IGET_BOOLEAN_finish          @ no, already resolved
23988:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2399    EXPORT_PC()                         @ resolve() could throw
2400    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2401    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2402    cmp     r0, #0
2403    bne     .LOP_IGET_BOOLEAN_finish
2404    b       common_exceptionThrown
2405
2406
2407/* ------------------------------ */
2408    .balign 64
2409.L_OP_IGET_BYTE: /* 0x56 */
2410/* File: armv5te/OP_IGET_BYTE.S */
2411@include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" }
2412/* File: armv5te/OP_IGET.S */
2413    /*
2414     * General 32-bit instance field get.
2415     *
2416     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2417     */
2418    /* op vA, vB, field@CCCC */
2419    mov     r0, rINST, lsr #12          @ r0<- B
2420    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2421    FETCH(r1, 1)                        @ r1<- field ref CCCC
2422    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2423    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2424    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2425    cmp     r0, #0                      @ is resolved entry null?
2426    bne     .LOP_IGET_BYTE_finish          @ no, already resolved
24278:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2428    EXPORT_PC()                         @ resolve() could throw
2429    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2430    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2431    cmp     r0, #0
2432    bne     .LOP_IGET_BYTE_finish
2433    b       common_exceptionThrown
2434
2435
2436/* ------------------------------ */
2437    .balign 64
2438.L_OP_IGET_CHAR: /* 0x57 */
2439/* File: armv5te/OP_IGET_CHAR.S */
2440@include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" }
2441/* File: armv5te/OP_IGET.S */
2442    /*
2443     * General 32-bit instance field get.
2444     *
2445     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2446     */
2447    /* op vA, vB, field@CCCC */
2448    mov     r0, rINST, lsr #12          @ r0<- B
2449    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2450    FETCH(r1, 1)                        @ r1<- field ref CCCC
2451    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2452    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2453    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2454    cmp     r0, #0                      @ is resolved entry null?
2455    bne     .LOP_IGET_CHAR_finish          @ no, already resolved
24568:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2457    EXPORT_PC()                         @ resolve() could throw
2458    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2459    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2460    cmp     r0, #0
2461    bne     .LOP_IGET_CHAR_finish
2462    b       common_exceptionThrown
2463
2464
2465/* ------------------------------ */
2466    .balign 64
2467.L_OP_IGET_SHORT: /* 0x58 */
2468/* File: armv5te/OP_IGET_SHORT.S */
2469@include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" }
2470/* File: armv5te/OP_IGET.S */
2471    /*
2472     * General 32-bit instance field get.
2473     *
2474     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2475     */
2476    /* op vA, vB, field@CCCC */
2477    mov     r0, rINST, lsr #12          @ r0<- B
2478    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2479    FETCH(r1, 1)                        @ r1<- field ref CCCC
2480    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2481    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2482    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2483    cmp     r0, #0                      @ is resolved entry null?
2484    bne     .LOP_IGET_SHORT_finish          @ no, already resolved
24858:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2486    EXPORT_PC()                         @ resolve() could throw
2487    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2488    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2489    cmp     r0, #0
2490    bne     .LOP_IGET_SHORT_finish
2491    b       common_exceptionThrown
2492
2493
2494/* ------------------------------ */
2495    .balign 64
2496.L_OP_IPUT: /* 0x59 */
2497/* File: armv6t2/OP_IPUT.S */
2498    /*
2499     * General 32-bit instance field put.
2500     *
2501     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
2502     */
2503    /* op vA, vB, field@CCCC */
2504    mov     r0, rINST, lsr #12          @ r0<- B
2505    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2506    FETCH(r1, 1)                        @ r1<- field ref CCCC
2507    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2508    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2509    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2510    cmp     r0, #0                      @ is resolved entry null?
2511    bne     .LOP_IPUT_finish          @ no, already resolved
25128:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2513    EXPORT_PC()                         @ resolve() could throw
2514    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2515    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2516    cmp     r0, #0                      @ success?
2517    bne     .LOP_IPUT_finish          @ yes, finish up
2518    b       common_exceptionThrown
2519
2520/* ------------------------------ */
2521    .balign 64
2522.L_OP_IPUT_WIDE: /* 0x5a */
2523/* File: armv6t2/OP_IPUT_WIDE.S */
2524    /* iput-wide vA, vB, field@CCCC */
2525    mov     r0, rINST, lsr #12          @ r0<- B
2526    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2527    FETCH(r1, 1)                        @ r1<- field ref CCCC
2528    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
2529    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2530    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2531    cmp     r0, #0                      @ is resolved entry null?
2532    bne     .LOP_IPUT_WIDE_finish          @ no, already resolved
25338:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
2534    EXPORT_PC()                         @ resolve() could throw
2535    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2536    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2537    cmp     r0, #0                      @ success?
2538    bne     .LOP_IPUT_WIDE_finish          @ yes, finish up
2539    b       common_exceptionThrown
2540
2541/* ------------------------------ */
2542    .balign 64
2543.L_OP_IPUT_OBJECT: /* 0x5b */
2544/* File: armv5te/OP_IPUT_OBJECT.S */
2545    /*
2546     * 32-bit instance field put.
2547     *
2548     * for: iput-object, iput-object-volatile
2549     */
2550    /* op vA, vB, field@CCCC */
2551    mov     r0, rINST, lsr #12          @ r0<- B
2552    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2553    FETCH(r1, 1)                        @ r1<- field ref CCCC
2554    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2555    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2556    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2557    cmp     r0, #0                      @ is resolved entry null?
2558    bne     .LOP_IPUT_OBJECT_finish          @ no, already resolved
25598:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2560    EXPORT_PC()                         @ resolve() could throw
2561    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2562    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2563    cmp     r0, #0                      @ success?
2564    bne     .LOP_IPUT_OBJECT_finish          @ yes, finish up
2565    b       common_exceptionThrown
2566
2567/* ------------------------------ */
2568    .balign 64
2569.L_OP_IPUT_BOOLEAN: /* 0x5c */
2570/* File: armv5te/OP_IPUT_BOOLEAN.S */
2571@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" }
2572/* File: armv5te/OP_IPUT.S */
2573    /*
2574     * General 32-bit instance field put.
2575     *
2576     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2577     */
2578    /* op vA, vB, field@CCCC */
2579    mov     r0, rINST, lsr #12          @ r0<- B
2580    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2581    FETCH(r1, 1)                        @ r1<- field ref CCCC
2582    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2583    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2584    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2585    cmp     r0, #0                      @ is resolved entry null?
2586    bne     .LOP_IPUT_BOOLEAN_finish          @ no, already resolved
25878:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2588    EXPORT_PC()                         @ resolve() could throw
2589    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2590    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2591    cmp     r0, #0                      @ success?
2592    bne     .LOP_IPUT_BOOLEAN_finish          @ yes, finish up
2593    b       common_exceptionThrown
2594
2595
2596/* ------------------------------ */
2597    .balign 64
2598.L_OP_IPUT_BYTE: /* 0x5d */
2599/* File: armv5te/OP_IPUT_BYTE.S */
2600@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" }
2601/* File: armv5te/OP_IPUT.S */
2602    /*
2603     * General 32-bit instance field put.
2604     *
2605     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2606     */
2607    /* op vA, vB, field@CCCC */
2608    mov     r0, rINST, lsr #12          @ r0<- B
2609    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2610    FETCH(r1, 1)                        @ r1<- field ref CCCC
2611    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2612    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2613    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2614    cmp     r0, #0                      @ is resolved entry null?
2615    bne     .LOP_IPUT_BYTE_finish          @ no, already resolved
26168:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2617    EXPORT_PC()                         @ resolve() could throw
2618    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2619    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2620    cmp     r0, #0                      @ success?
2621    bne     .LOP_IPUT_BYTE_finish          @ yes, finish up
2622    b       common_exceptionThrown
2623
2624
2625/* ------------------------------ */
2626    .balign 64
2627.L_OP_IPUT_CHAR: /* 0x5e */
2628/* File: armv5te/OP_IPUT_CHAR.S */
2629@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" }
2630/* File: armv5te/OP_IPUT.S */
2631    /*
2632     * General 32-bit instance field put.
2633     *
2634     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2635     */
2636    /* op vA, vB, field@CCCC */
2637    mov     r0, rINST, lsr #12          @ r0<- B
2638    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2639    FETCH(r1, 1)                        @ r1<- field ref CCCC
2640    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2641    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2642    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2643    cmp     r0, #0                      @ is resolved entry null?
2644    bne     .LOP_IPUT_CHAR_finish          @ no, already resolved
26458:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2646    EXPORT_PC()                         @ resolve() could throw
2647    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2648    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2649    cmp     r0, #0                      @ success?
2650    bne     .LOP_IPUT_CHAR_finish          @ yes, finish up
2651    b       common_exceptionThrown
2652
2653
2654/* ------------------------------ */
2655    .balign 64
2656.L_OP_IPUT_SHORT: /* 0x5f */
2657/* File: armv5te/OP_IPUT_SHORT.S */
2658@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" }
2659/* File: armv5te/OP_IPUT.S */
2660    /*
2661     * General 32-bit instance field put.
2662     *
2663     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2664     */
2665    /* op vA, vB, field@CCCC */
2666    mov     r0, rINST, lsr #12          @ r0<- B
2667    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2668    FETCH(r1, 1)                        @ r1<- field ref CCCC
2669    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2670    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2671    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2672    cmp     r0, #0                      @ is resolved entry null?
2673    bne     .LOP_IPUT_SHORT_finish          @ no, already resolved
26748:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2675    EXPORT_PC()                         @ resolve() could throw
2676    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2677    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2678    cmp     r0, #0                      @ success?
2679    bne     .LOP_IPUT_SHORT_finish          @ yes, finish up
2680    b       common_exceptionThrown
2681
2682
2683/* ------------------------------ */
2684    .balign 64
2685.L_OP_SGET: /* 0x60 */
2686/* File: armv5te/OP_SGET.S */
2687    /*
2688     * General 32-bit SGET handler.
2689     *
2690     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2691     */
2692    /* op vAA, field@BBBB */
2693    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2694    FETCH(r1, 1)                        @ r1<- field ref BBBB
2695    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2696    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2697    cmp     r0, #0                      @ is resolved entry null?
2698    beq     .LOP_SGET_resolve         @ yes, do resolve
2699.LOP_SGET_finish: @ field ptr in r0
2700    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2701    @ no-op                             @ acquiring load
2702    mov     r2, rINST, lsr #8           @ r2<- AA
2703    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2704    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2705    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2706    GOTO_OPCODE(ip)                     @ jump to next instruction
2707
2708/* ------------------------------ */
2709    .balign 64
2710.L_OP_SGET_WIDE: /* 0x61 */
2711/* File: armv5te/OP_SGET_WIDE.S */
2712    /*
2713     * 64-bit SGET handler.
2714     */
2715    /* sget-wide vAA, field@BBBB */
2716    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2717    FETCH(r1, 1)                        @ r1<- field ref BBBB
2718    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2719    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2720    cmp     r0, #0                      @ is resolved entry null?
2721    beq     .LOP_SGET_WIDE_resolve         @ yes, do resolve
2722.LOP_SGET_WIDE_finish:
2723    mov     r9, rINST, lsr #8           @ r9<- AA
2724    .if 0
2725    add     r0, r0, #offStaticField_value @ r0<- pointer to data
2726    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
2727    .else
2728    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
2729    .endif
2730    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2731    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2732    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
2733    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2734    GOTO_OPCODE(ip)                     @ jump to next instruction
2735
2736/* ------------------------------ */
2737    .balign 64
2738.L_OP_SGET_OBJECT: /* 0x62 */
2739/* File: armv5te/OP_SGET_OBJECT.S */
2740/* File: armv5te/OP_SGET.S */
2741    /*
2742     * General 32-bit SGET handler.
2743     *
2744     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2745     */
2746    /* op vAA, field@BBBB */
2747    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2748    FETCH(r1, 1)                        @ r1<- field ref BBBB
2749    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2750    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2751    cmp     r0, #0                      @ is resolved entry null?
2752    beq     .LOP_SGET_OBJECT_resolve         @ yes, do resolve
2753.LOP_SGET_OBJECT_finish: @ field ptr in r0
2754    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2755    @ no-op                             @ acquiring load
2756    mov     r2, rINST, lsr #8           @ r2<- AA
2757    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2758    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2759    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2760    GOTO_OPCODE(ip)                     @ jump to next instruction
2761
2762
2763/* ------------------------------ */
2764    .balign 64
2765.L_OP_SGET_BOOLEAN: /* 0x63 */
2766/* File: armv5te/OP_SGET_BOOLEAN.S */
2767/* File: armv5te/OP_SGET.S */
2768    /*
2769     * General 32-bit SGET handler.
2770     *
2771     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2772     */
2773    /* op vAA, field@BBBB */
2774    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2775    FETCH(r1, 1)                        @ r1<- field ref BBBB
2776    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2777    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2778    cmp     r0, #0                      @ is resolved entry null?
2779    beq     .LOP_SGET_BOOLEAN_resolve         @ yes, do resolve
2780.LOP_SGET_BOOLEAN_finish: @ field ptr in r0
2781    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2782    @ no-op                             @ acquiring load
2783    mov     r2, rINST, lsr #8           @ r2<- AA
2784    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2785    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2786    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2787    GOTO_OPCODE(ip)                     @ jump to next instruction
2788
2789
2790/* ------------------------------ */
2791    .balign 64
2792.L_OP_SGET_BYTE: /* 0x64 */
2793/* File: armv5te/OP_SGET_BYTE.S */
2794/* File: armv5te/OP_SGET.S */
2795    /*
2796     * General 32-bit SGET handler.
2797     *
2798     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2799     */
2800    /* op vAA, field@BBBB */
2801    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2802    FETCH(r1, 1)                        @ r1<- field ref BBBB
2803    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2804    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2805    cmp     r0, #0                      @ is resolved entry null?
2806    beq     .LOP_SGET_BYTE_resolve         @ yes, do resolve
2807.LOP_SGET_BYTE_finish: @ field ptr in r0
2808    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2809    @ no-op                             @ acquiring load
2810    mov     r2, rINST, lsr #8           @ r2<- AA
2811    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2812    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2813    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2814    GOTO_OPCODE(ip)                     @ jump to next instruction
2815
2816
2817/* ------------------------------ */
2818    .balign 64
2819.L_OP_SGET_CHAR: /* 0x65 */
2820/* File: armv5te/OP_SGET_CHAR.S */
2821/* File: armv5te/OP_SGET.S */
2822    /*
2823     * General 32-bit SGET handler.
2824     *
2825     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2826     */
2827    /* op vAA, field@BBBB */
2828    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2829    FETCH(r1, 1)                        @ r1<- field ref BBBB
2830    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2831    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2832    cmp     r0, #0                      @ is resolved entry null?
2833    beq     .LOP_SGET_CHAR_resolve         @ yes, do resolve
2834.LOP_SGET_CHAR_finish: @ field ptr in r0
2835    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2836    @ no-op                             @ acquiring load
2837    mov     r2, rINST, lsr #8           @ r2<- AA
2838    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2839    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2840    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2841    GOTO_OPCODE(ip)                     @ jump to next instruction
2842
2843
2844/* ------------------------------ */
2845    .balign 64
2846.L_OP_SGET_SHORT: /* 0x66 */
2847/* File: armv5te/OP_SGET_SHORT.S */
2848/* File: armv5te/OP_SGET.S */
2849    /*
2850     * General 32-bit SGET handler.
2851     *
2852     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2853     */
2854    /* op vAA, field@BBBB */
2855    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2856    FETCH(r1, 1)                        @ r1<- field ref BBBB
2857    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2858    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2859    cmp     r0, #0                      @ is resolved entry null?
2860    beq     .LOP_SGET_SHORT_resolve         @ yes, do resolve
2861.LOP_SGET_SHORT_finish: @ field ptr in r0
2862    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2863    @ no-op                             @ acquiring load
2864    mov     r2, rINST, lsr #8           @ r2<- AA
2865    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2866    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2867    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2868    GOTO_OPCODE(ip)                     @ jump to next instruction
2869
2870
2871/* ------------------------------ */
2872    .balign 64
2873.L_OP_SPUT: /* 0x67 */
2874/* File: armv5te/OP_SPUT.S */
2875    /*
2876     * General 32-bit SPUT handler.
2877     *
2878     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2879     */
2880    /* op vAA, field@BBBB */
2881    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2882    FETCH(r1, 1)                        @ r1<- field ref BBBB
2883    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2884    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
2885    cmp     r0, #0                      @ is resolved entry null?
2886    beq     .LOP_SPUT_resolve         @ yes, do resolve
2887.LOP_SPUT_finish:   @ field ptr in r0
2888    mov     r2, rINST, lsr #8           @ r2<- AA
2889    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2890    GET_VREG(r1, r2)                    @ r1<- fp[AA]
2891    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2892    @ no-op                        @ releasing store
2893    str     r1, [r0, #offStaticField_value] @ field<- vAA
2894    @ no-op
2895    GOTO_OPCODE(ip)                     @ jump to next instruction
2896
2897/* ------------------------------ */
2898    .balign 64
2899.L_OP_SPUT_WIDE: /* 0x68 */
2900/* File: armv5te/OP_SPUT_WIDE.S */
2901    /*
2902     * 64-bit SPUT handler.
2903     */
2904    /* sput-wide vAA, field@BBBB */
2905    ldr     r0, [rSELF, #offThread_methodClassDex]  @ r0<- DvmDex
2906    FETCH(r1, 1)                        @ r1<- field ref BBBB
2907    ldr     r10, [r0, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2908    mov     r9, rINST, lsr #8           @ r9<- AA
2909    ldr     r2, [r10, r1, lsl #2]        @ r2<- resolved StaticField ptr
2910    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2911    cmp     r2, #0                      @ is resolved entry null?
2912    beq     .LOP_SPUT_WIDE_resolve         @ yes, do resolve
2913.LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9
2914    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2915    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
2916    GET_INST_OPCODE(r10)                @ extract opcode from rINST
2917    .if 0
2918    add     r2, r2, #offStaticField_value @ r2<- pointer to data
2919    bl      dvmQuasiAtomicSwap64Sync    @ stores r0/r1 into addr r2
2920    .else
2921    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
2922    .endif
2923    GOTO_OPCODE(r10)                    @ jump to next instruction
2924
2925/* ------------------------------ */
2926    .balign 64
2927.L_OP_SPUT_OBJECT: /* 0x69 */
2928/* File: armv5te/OP_SPUT_OBJECT.S */
2929    /*
2930     * 32-bit SPUT handler for objects
2931     *
2932     * for: sput-object, sput-object-volatile
2933     */
2934    /* op vAA, field@BBBB */
2935    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2936    FETCH(r1, 1)                        @ r1<- field ref BBBB
2937    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2938    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
2939    cmp     r0, #0                      @ is resolved entry null?
2940    beq     .LOP_SPUT_OBJECT_resolve         @ yes, do resolve
2941.LOP_SPUT_OBJECT_finish:   @ field ptr in r0
2942    mov     r2, rINST, lsr #8           @ r2<- AA
2943    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2944    GET_VREG(r1, r2)                    @ r1<- fp[AA]
2945    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
2946    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
2947    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2948    @ no-op                         @ releasing store
2949    b       .LOP_SPUT_OBJECT_end
2950
2951/* ------------------------------ */
2952    .balign 64
2953.L_OP_SPUT_BOOLEAN: /* 0x6a */
2954/* File: armv5te/OP_SPUT_BOOLEAN.S */
2955/* File: armv5te/OP_SPUT.S */
2956    /*
2957     * General 32-bit SPUT handler.
2958     *
2959     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2960     */
2961    /* op vAA, field@BBBB */
2962    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2963    FETCH(r1, 1)                        @ r1<- field ref BBBB
2964    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2965    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
2966    cmp     r0, #0                      @ is resolved entry null?
2967    beq     .LOP_SPUT_BOOLEAN_resolve         @ yes, do resolve
2968.LOP_SPUT_BOOLEAN_finish:   @ field ptr in r0
2969    mov     r2, rINST, lsr #8           @ r2<- AA
2970    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2971    GET_VREG(r1, r2)                    @ r1<- fp[AA]
2972    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2973    @ no-op                        @ releasing store
2974    str     r1, [r0, #offStaticField_value] @ field<- vAA
2975    @ no-op
2976    GOTO_OPCODE(ip)                     @ jump to next instruction
2977
2978
2979/* ------------------------------ */
2980    .balign 64
2981.L_OP_SPUT_BYTE: /* 0x6b */
2982/* File: armv5te/OP_SPUT_BYTE.S */
2983/* File: armv5te/OP_SPUT.S */
2984    /*
2985     * General 32-bit SPUT handler.
2986     *
2987     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2988     */
2989    /* op vAA, field@BBBB */
2990    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2991    FETCH(r1, 1)                        @ r1<- field ref BBBB
2992    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2993    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
2994    cmp     r0, #0                      @ is resolved entry null?
2995    beq     .LOP_SPUT_BYTE_resolve         @ yes, do resolve
2996.LOP_SPUT_BYTE_finish:   @ field ptr in r0
2997    mov     r2, rINST, lsr #8           @ r2<- AA
2998    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2999    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3000    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3001    @ no-op                        @ releasing store
3002    str     r1, [r0, #offStaticField_value] @ field<- vAA
3003    @ no-op
3004    GOTO_OPCODE(ip)                     @ jump to next instruction
3005
3006
3007/* ------------------------------ */
3008    .balign 64
3009.L_OP_SPUT_CHAR: /* 0x6c */
3010/* File: armv5te/OP_SPUT_CHAR.S */
3011/* File: armv5te/OP_SPUT.S */
3012    /*
3013     * General 32-bit SPUT handler.
3014     *
3015     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3016     */
3017    /* op vAA, field@BBBB */
3018    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
3019    FETCH(r1, 1)                        @ r1<- field ref BBBB
3020    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
3021    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
3022    cmp     r0, #0                      @ is resolved entry null?
3023    beq     .LOP_SPUT_CHAR_resolve         @ yes, do resolve
3024.LOP_SPUT_CHAR_finish:   @ field ptr in r0
3025    mov     r2, rINST, lsr #8           @ r2<- AA
3026    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3027    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3028    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3029    @ no-op                        @ releasing store
3030    str     r1, [r0, #offStaticField_value] @ field<- vAA
3031    @ no-op
3032    GOTO_OPCODE(ip)                     @ jump to next instruction
3033
3034
3035/* ------------------------------ */
3036    .balign 64
3037.L_OP_SPUT_SHORT: /* 0x6d */
3038/* File: armv5te/OP_SPUT_SHORT.S */
3039/* File: armv5te/OP_SPUT.S */
3040    /*
3041     * General 32-bit SPUT handler.
3042     *
3043     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3044     */
3045    /* op vAA, field@BBBB */
3046    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
3047    FETCH(r1, 1)                        @ r1<- field ref BBBB
3048    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
3049    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
3050    cmp     r0, #0                      @ is resolved entry null?
3051    beq     .LOP_SPUT_SHORT_resolve         @ yes, do resolve
3052.LOP_SPUT_SHORT_finish:   @ field ptr in r0
3053    mov     r2, rINST, lsr #8           @ r2<- AA
3054    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3055    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3056    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3057    @ no-op                        @ releasing store
3058    str     r1, [r0, #offStaticField_value] @ field<- vAA
3059    @ no-op
3060    GOTO_OPCODE(ip)                     @ jump to next instruction
3061
3062
3063/* ------------------------------ */
3064    .balign 64
3065.L_OP_INVOKE_VIRTUAL: /* 0x6e */
3066/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3067    /*
3068     * Handle a virtual method call.
3069     *
3070     * for: invoke-virtual, invoke-virtual/range
3071     */
3072    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3073    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3074    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3075    FETCH(r1, 1)                        @ r1<- BBBB
3076    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3077    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3078    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3079    .if     (!0)
3080    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3081    .endif
3082    cmp     r0, #0                      @ already resolved?
3083    EXPORT_PC()                         @ must export for invoke
3084    bne     .LOP_INVOKE_VIRTUAL_continue        @ yes, continue on
3085    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
3086    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3087    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3088    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3089    cmp     r0, #0                      @ got null?
3090    bne     .LOP_INVOKE_VIRTUAL_continue        @ no, continue
3091    b       common_exceptionThrown      @ yes, handle exception
3092
3093/* ------------------------------ */
3094    .balign 64
3095.L_OP_INVOKE_SUPER: /* 0x6f */
3096/* File: armv5te/OP_INVOKE_SUPER.S */
3097    /*
3098     * Handle a "super" method call.
3099     *
3100     * for: invoke-super, invoke-super/range
3101     */
3102    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3103    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3104    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3105    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3106    .if     (!0)
3107    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3108    .endif
3109    FETCH(r1, 1)                        @ r1<- BBBB
3110    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3111    GET_VREG(r9, r10)                   @ r9<- "this" ptr
3112    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3113    cmp     r9, #0                      @ null "this"?
3114    ldr     r10, [rSELF, #offThread_method] @ r10<- current method
3115    beq     common_errNullObject        @ null "this", throw exception
3116    cmp     r0, #0                      @ already resolved?
3117    ldr     r10, [r10, #offMethod_clazz]  @ r10<- method->clazz
3118    EXPORT_PC()                         @ must export for invoke
3119    bne     .LOP_INVOKE_SUPER_continue        @ resolved, continue on
3120    b       .LOP_INVOKE_SUPER_resolve         @ do resolve now
3121
3122/* ------------------------------ */
3123    .balign 64
3124.L_OP_INVOKE_DIRECT: /* 0x70 */
3125/* File: armv5te/OP_INVOKE_DIRECT.S */
3126    /*
3127     * Handle a direct method call.
3128     *
3129     * (We could defer the "is 'this' pointer null" test to the common
3130     * method invocation code, and use a flag to indicate that static
3131     * calls don't count.  If we do this as part of copying the arguments
3132     * out we could avoiding loading the first arg twice.)
3133     *
3134     * for: invoke-direct, invoke-direct/range
3135     */
3136    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3137    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3138    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3139    FETCH(r1, 1)                        @ r1<- BBBB
3140    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3141    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3142    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3143    .if     (!0)
3144    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3145    .endif
3146    cmp     r0, #0                      @ already resolved?
3147    EXPORT_PC()                         @ must export for invoke
3148    GET_VREG(r9, r10)                   @ r9<- "this" ptr
3149    beq     .LOP_INVOKE_DIRECT_resolve         @ not resolved, do it now
3150.LOP_INVOKE_DIRECT_finish:
3151    cmp     r9, #0                      @ null "this" ref?
3152    bne     common_invokeMethodNoRange   @ r0=method, r9="this"
3153    b       common_errNullObject        @ yes, throw exception
3154
3155/* ------------------------------ */
3156    .balign 64
3157.L_OP_INVOKE_STATIC: /* 0x71 */
3158/* File: armv5te/OP_INVOKE_STATIC.S */
3159    /*
3160     * Handle a static method call.
3161     *
3162     * for: invoke-static, invoke-static/range
3163     */
3164    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3165    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3166    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3167    FETCH(r1, 1)                        @ r1<- BBBB
3168    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3169    mov     r9, #0                      @ null "this" in delay slot
3170    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3171#if defined(WITH_JIT)
3172    add     r10, r3, r1, lsl #2         @ r10<- &resolved_methodToCall
3173#endif
3174    cmp     r0, #0                      @ already resolved?
3175    EXPORT_PC()                         @ must export for invoke
3176    bne     common_invokeMethodNoRange @ yes, continue on
3177    b       .LOP_INVOKE_STATIC_resolve
3178
3179/* ------------------------------ */
3180    .balign 64
3181.L_OP_INVOKE_INTERFACE: /* 0x72 */
3182/* File: armv5te/OP_INVOKE_INTERFACE.S */
3183    /*
3184     * Handle an interface method call.
3185     *
3186     * for: invoke-interface, invoke-interface/range
3187     */
3188    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3189    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3190    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3191    FETCH(r1, 1)                        @ r1<- BBBB
3192    .if     (!0)
3193    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3194    .endif
3195    EXPORT_PC()                         @ must export for invoke
3196    GET_VREG(r9, r2)                    @ r9<- first arg ("this")
3197    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- methodClassDex
3198    cmp     r9, #0                      @ null obj?
3199    ldr     r2, [rSELF, #offThread_method]  @ r2<- method
3200    beq     common_errNullObject        @ yes, fail
3201    ldr     r0, [r9, #offObject_clazz]  @ r0<- thisPtr->clazz
3202    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3203    cmp     r0, #0                      @ failed?
3204    beq     common_exceptionThrown      @ yes, handle exception
3205    b       common_invokeMethodNoRange @ (r0=method, r9="this")
3206
3207/* ------------------------------ */
3208    .balign 64
3209.L_OP_UNUSED_73: /* 0x73 */
3210/* File: armv5te/OP_UNUSED_73.S */
3211/* File: armv5te/unused.S */
3212    bl      common_abort
3213
3214
3215/* ------------------------------ */
3216    .balign 64
3217.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
3218/* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */
3219/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3220    /*
3221     * Handle a virtual method call.
3222     *
3223     * for: invoke-virtual, invoke-virtual/range
3224     */
3225    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3226    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3227    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3228    FETCH(r1, 1)                        @ r1<- BBBB
3229    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3230    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3231    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3232    .if     (!1)
3233    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3234    .endif
3235    cmp     r0, #0                      @ already resolved?
3236    EXPORT_PC()                         @ must export for invoke
3237    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ yes, continue on
3238    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
3239    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3240    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3241    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3242    cmp     r0, #0                      @ got null?
3243    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ no, continue
3244    b       common_exceptionThrown      @ yes, handle exception
3245
3246
3247/* ------------------------------ */
3248    .balign 64
3249.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */
3250/* File: armv5te/OP_INVOKE_SUPER_RANGE.S */
3251/* File: armv5te/OP_INVOKE_SUPER.S */
3252    /*
3253     * Handle a "super" method call.
3254     *
3255     * for: invoke-super, invoke-super/range
3256     */
3257    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3258    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3259    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3260    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3261    .if     (!1)
3262    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3263    .endif
3264    FETCH(r1, 1)                        @ r1<- BBBB
3265    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3266    GET_VREG(r9, r10)                   @ r9<- "this" ptr
3267    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3268    cmp     r9, #0                      @ null "this"?
3269    ldr     r10, [rSELF, #offThread_method] @ r10<- current method
3270    beq     common_errNullObject        @ null "this", throw exception
3271    cmp     r0, #0                      @ already resolved?
3272    ldr     r10, [r10, #offMethod_clazz]  @ r10<- method->clazz
3273    EXPORT_PC()                         @ must export for invoke
3274    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ resolved, continue on
3275    b       .LOP_INVOKE_SUPER_RANGE_resolve         @ do resolve now
3276
3277
3278/* ------------------------------ */
3279    .balign 64
3280.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
3281/* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */
3282/* File: armv5te/OP_INVOKE_DIRECT.S */
3283    /*
3284     * Handle a direct method call.
3285     *
3286     * (We could defer the "is 'this' pointer null" test to the common
3287     * method invocation code, and use a flag to indicate that static
3288     * calls don't count.  If we do this as part of copying the arguments
3289     * out we could avoiding loading the first arg twice.)
3290     *
3291     * for: invoke-direct, invoke-direct/range
3292     */
3293    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3294    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3295    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3296    FETCH(r1, 1)                        @ r1<- BBBB
3297    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3298    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3299    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3300    .if     (!1)
3301    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3302    .endif
3303    cmp     r0, #0                      @ already resolved?
3304    EXPORT_PC()                         @ must export for invoke
3305    GET_VREG(r9, r10)                   @ r9<- "this" ptr
3306    beq     .LOP_INVOKE_DIRECT_RANGE_resolve         @ not resolved, do it now
3307.LOP_INVOKE_DIRECT_RANGE_finish:
3308    cmp     r9, #0                      @ null "this" ref?
3309    bne     common_invokeMethodRange   @ r0=method, r9="this"
3310    b       common_errNullObject        @ yes, throw exception
3311
3312
3313/* ------------------------------ */
3314    .balign 64
3315.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */
3316/* File: armv5te/OP_INVOKE_STATIC_RANGE.S */
3317/* File: armv5te/OP_INVOKE_STATIC.S */
3318    /*
3319     * Handle a static method call.
3320     *
3321     * for: invoke-static, invoke-static/range
3322     */
3323    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3324    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3325    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3326    FETCH(r1, 1)                        @ r1<- BBBB
3327    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3328    mov     r9, #0                      @ null "this" in delay slot
3329    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3330#if defined(WITH_JIT)
3331    add     r10, r3, r1, lsl #2         @ r10<- &resolved_methodToCall
3332#endif
3333    cmp     r0, #0                      @ already resolved?
3334    EXPORT_PC()                         @ must export for invoke
3335    bne     common_invokeMethodRange @ yes, continue on
3336    b       .LOP_INVOKE_STATIC_RANGE_resolve
3337
3338
3339/* ------------------------------ */
3340    .balign 64
3341.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
3342/* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */
3343/* File: armv5te/OP_INVOKE_INTERFACE.S */
3344    /*
3345     * Handle an interface method call.
3346     *
3347     * for: invoke-interface, invoke-interface/range
3348     */
3349    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3350    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3351    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3352    FETCH(r1, 1)                        @ r1<- BBBB
3353    .if     (!1)
3354    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3355    .endif
3356    EXPORT_PC()                         @ must export for invoke
3357    GET_VREG(r9, r2)                    @ r9<- first arg ("this")
3358    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- methodClassDex
3359    cmp     r9, #0                      @ null obj?
3360    ldr     r2, [rSELF, #offThread_method]  @ r2<- method
3361    beq     common_errNullObject        @ yes, fail
3362    ldr     r0, [r9, #offObject_clazz]  @ r0<- thisPtr->clazz
3363    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3364    cmp     r0, #0                      @ failed?
3365    beq     common_exceptionThrown      @ yes, handle exception
3366    b       common_invokeMethodRange @ (r0=method, r9="this")
3367
3368
3369/* ------------------------------ */
3370    .balign 64
3371.L_OP_UNUSED_79: /* 0x79 */
3372/* File: armv5te/OP_UNUSED_79.S */
3373/* File: armv5te/unused.S */
3374    bl      common_abort
3375
3376
3377/* ------------------------------ */
3378    .balign 64
3379.L_OP_UNUSED_7A: /* 0x7a */
3380/* File: armv5te/OP_UNUSED_7A.S */
3381/* File: armv5te/unused.S */
3382    bl      common_abort
3383
3384
3385/* ------------------------------ */
3386    .balign 64
3387.L_OP_NEG_INT: /* 0x7b */
3388/* File: armv6t2/OP_NEG_INT.S */
3389/* File: armv6t2/unop.S */
3390    /*
3391     * Generic 32-bit unary operation.  Provide an "instr" line that
3392     * specifies an instruction that performs "result = op r0".
3393     * This could be an ARM instruction or a function call.
3394     *
3395     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3396     *      int-to-byte, int-to-char, int-to-short
3397     */
3398    /* unop vA, vB */
3399    mov     r3, rINST, lsr #12          @ r3<- B
3400    ubfx    r9, rINST, #8, #4           @ r9<- A
3401    GET_VREG(r0, r3)                    @ r0<- vB
3402                               @ optional op; may set condition codes
3403    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3404    rsb     r0, r0, #0                              @ r0<- op, r0-r3 changed
3405    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3406    SET_VREG(r0, r9)                    @ vAA<- r0
3407    GOTO_OPCODE(ip)                     @ jump to next instruction
3408    /* 8-9 instructions */
3409
3410
3411/* ------------------------------ */
3412    .balign 64
3413.L_OP_NOT_INT: /* 0x7c */
3414/* File: armv6t2/OP_NOT_INT.S */
3415/* File: armv6t2/unop.S */
3416    /*
3417     * Generic 32-bit unary operation.  Provide an "instr" line that
3418     * specifies an instruction that performs "result = op r0".
3419     * This could be an ARM instruction or a function call.
3420     *
3421     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3422     *      int-to-byte, int-to-char, int-to-short
3423     */
3424    /* unop vA, vB */
3425    mov     r3, rINST, lsr #12          @ r3<- B
3426    ubfx    r9, rINST, #8, #4           @ r9<- A
3427    GET_VREG(r0, r3)                    @ r0<- vB
3428                               @ optional op; may set condition codes
3429    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3430    mvn     r0, r0                              @ r0<- op, r0-r3 changed
3431    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3432    SET_VREG(r0, r9)                    @ vAA<- r0
3433    GOTO_OPCODE(ip)                     @ jump to next instruction
3434    /* 8-9 instructions */
3435
3436
3437/* ------------------------------ */
3438    .balign 64
3439.L_OP_NEG_LONG: /* 0x7d */
3440/* File: armv6t2/OP_NEG_LONG.S */
3441/* File: armv6t2/unopWide.S */
3442    /*
3443     * Generic 64-bit unary operation.  Provide an "instr" line that
3444     * specifies an instruction that performs "result = op r0/r1".
3445     * This could be an ARM instruction or a function call.
3446     *
3447     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3448     */
3449    /* unop vA, vB */
3450    mov     r3, rINST, lsr #12          @ r3<- B
3451    ubfx    r9, rINST, #8, #4           @ r9<- A
3452    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3453    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3454    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3455    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3456    rsbs    r0, r0, #0                           @ optional op; may set condition codes
3457    rsc     r1, r1, #0                              @ r0/r1<- op, r2-r3 changed
3458    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3459    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3460    GOTO_OPCODE(ip)                     @ jump to next instruction
3461    /* 10-11 instructions */
3462
3463
3464/* ------------------------------ */
3465    .balign 64
3466.L_OP_NOT_LONG: /* 0x7e */
3467/* File: armv6t2/OP_NOT_LONG.S */
3468/* File: armv6t2/unopWide.S */
3469    /*
3470     * Generic 64-bit unary operation.  Provide an "instr" line that
3471     * specifies an instruction that performs "result = op r0/r1".
3472     * This could be an ARM instruction or a function call.
3473     *
3474     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3475     */
3476    /* unop vA, vB */
3477    mov     r3, rINST, lsr #12          @ r3<- B
3478    ubfx    r9, rINST, #8, #4           @ r9<- A
3479    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3480    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3481    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3482    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3483    mvn     r0, r0                           @ optional op; may set condition codes
3484    mvn     r1, r1                              @ r0/r1<- op, r2-r3 changed
3485    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3486    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3487    GOTO_OPCODE(ip)                     @ jump to next instruction
3488    /* 10-11 instructions */
3489
3490
3491/* ------------------------------ */
3492    .balign 64
3493.L_OP_NEG_FLOAT: /* 0x7f */
3494/* File: armv6t2/OP_NEG_FLOAT.S */
3495/* File: armv6t2/unop.S */
3496    /*
3497     * Generic 32-bit unary operation.  Provide an "instr" line that
3498     * specifies an instruction that performs "result = op r0".
3499     * This could be an ARM instruction or a function call.
3500     *
3501     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3502     *      int-to-byte, int-to-char, int-to-short
3503     */
3504    /* unop vA, vB */
3505    mov     r3, rINST, lsr #12          @ r3<- B
3506    ubfx    r9, rINST, #8, #4           @ r9<- A
3507    GET_VREG(r0, r3)                    @ r0<- vB
3508                               @ optional op; may set condition codes
3509    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3510    add     r0, r0, #0x80000000                              @ r0<- op, r0-r3 changed
3511    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3512    SET_VREG(r0, r9)                    @ vAA<- r0
3513    GOTO_OPCODE(ip)                     @ jump to next instruction
3514    /* 8-9 instructions */
3515
3516
3517/* ------------------------------ */
3518    .balign 64
3519.L_OP_NEG_DOUBLE: /* 0x80 */
3520/* File: armv6t2/OP_NEG_DOUBLE.S */
3521/* File: armv6t2/unopWide.S */
3522    /*
3523     * Generic 64-bit unary operation.  Provide an "instr" line that
3524     * specifies an instruction that performs "result = op r0/r1".
3525     * This could be an ARM instruction or a function call.
3526     *
3527     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3528     */
3529    /* unop vA, vB */
3530    mov     r3, rINST, lsr #12          @ r3<- B
3531    ubfx    r9, rINST, #8, #4           @ r9<- A
3532    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3533    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3534    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3535    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3536                               @ optional op; may set condition codes
3537    add     r1, r1, #0x80000000                              @ r0/r1<- op, r2-r3 changed
3538    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3539    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3540    GOTO_OPCODE(ip)                     @ jump to next instruction
3541    /* 10-11 instructions */
3542
3543
3544/* ------------------------------ */
3545    .balign 64
3546.L_OP_INT_TO_LONG: /* 0x81 */
3547/* File: armv6t2/OP_INT_TO_LONG.S */
3548/* File: armv6t2/unopWider.S */
3549    /*
3550     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3551     * that specifies an instruction that performs "result = op r0", where
3552     * "result" is a 64-bit quantity in r0/r1.
3553     *
3554     * For: int-to-long, int-to-double, float-to-long, float-to-double
3555     */
3556    /* unop vA, vB */
3557    mov     r3, rINST, lsr #12          @ r3<- B
3558    ubfx    r9, rINST, #8, #4           @ r9<- A
3559    GET_VREG(r0, r3)                    @ r0<- vB
3560    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3561                               @ optional op; may set condition codes
3562    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3563    mov     r1, r0, asr #31                              @ r0<- op, r0-r3 changed
3564    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3565    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3566    GOTO_OPCODE(ip)                     @ jump to next instruction
3567    /* 9-10 instructions */
3568
3569
3570/* ------------------------------ */
3571    .balign 64
3572.L_OP_INT_TO_FLOAT: /* 0x82 */
3573/* File: arm-vfp/OP_INT_TO_FLOAT.S */
3574/* File: arm-vfp/funop.S */
3575    /*
3576     * Generic 32-bit unary floating-point operation.  Provide an "instr"
3577     * line that specifies an instruction that performs "s1 = op s0".
3578     *
3579     * for: int-to-float, float-to-int
3580     */
3581    /* unop vA, vB */
3582    mov     r3, rINST, lsr #12          @ r3<- B
3583    mov     r9, rINST, lsr #8           @ r9<- A+
3584    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3585    flds    s0, [r3]                    @ s0<- vB
3586    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3587    and     r9, r9, #15                 @ r9<- A
3588    fsitos  s1, s0                              @ s1<- op
3589    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3590    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3591    fsts    s1, [r9]                    @ vA<- s1
3592    GOTO_OPCODE(ip)                     @ jump to next instruction
3593
3594
3595/* ------------------------------ */
3596    .balign 64
3597.L_OP_INT_TO_DOUBLE: /* 0x83 */
3598/* File: arm-vfp/OP_INT_TO_DOUBLE.S */
3599/* File: arm-vfp/funopWider.S */
3600    /*
3601     * Generic 32bit-to-64bit floating point unary operation.  Provide an
3602     * "instr" line that specifies an instruction that performs "d0 = op s0".
3603     *
3604     * For: int-to-double, float-to-double
3605     */
3606    /* unop vA, vB */
3607    mov     r3, rINST, lsr #12          @ r3<- B
3608    mov     r9, rINST, lsr #8           @ r9<- A+
3609    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3610    flds    s0, [r3]                    @ s0<- vB
3611    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3612    and     r9, r9, #15                 @ r9<- A
3613    fsitod  d0, s0                              @ d0<- op
3614    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3615    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3616    fstd    d0, [r9]                    @ vA<- d0
3617    GOTO_OPCODE(ip)                     @ jump to next instruction
3618
3619
3620/* ------------------------------ */
3621    .balign 64
3622.L_OP_LONG_TO_INT: /* 0x84 */
3623/* File: armv5te/OP_LONG_TO_INT.S */
3624/* we ignore the high word, making this equivalent to a 32-bit reg move */
3625/* File: armv5te/OP_MOVE.S */
3626    /* for move, move-object, long-to-int */
3627    /* op vA, vB */
3628    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
3629    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
3630    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3631    GET_VREG(r2, r1)                    @ r2<- fp[B]
3632    and     r0, r0, #15
3633    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
3634    SET_VREG(r2, r0)                    @ fp[A]<- r2
3635    GOTO_OPCODE(ip)                     @ execute next instruction
3636
3637
3638/* ------------------------------ */
3639    .balign 64
3640.L_OP_LONG_TO_FLOAT: /* 0x85 */
3641/* File: armv6t2/OP_LONG_TO_FLOAT.S */
3642/* File: armv6t2/unopNarrower.S */
3643    /*
3644     * Generic 64bit-to-32bit unary operation.  Provide an "instr" line
3645     * that specifies an instruction that performs "result = op r0/r1", where
3646     * "result" is a 32-bit quantity in r0.
3647     *
3648     * For: long-to-float, double-to-int, double-to-float
3649     *
3650     * (This would work for long-to-int, but that instruction is actually
3651     * an exact match for OP_MOVE.)
3652     */
3653    /* unop vA, vB */
3654    mov     r3, rINST, lsr #12          @ r3<- B
3655    ubfx    r9, rINST, #8, #4           @ r9<- A
3656    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3657    ldmia   r3, {r0-r1}                 @ r0/r1<- vB/vB+1
3658    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3659                               @ optional op; may set condition codes
3660    bl      __aeabi_l2f                              @ r0<- op, r0-r3 changed
3661    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3662    SET_VREG(r0, r9)                    @ vA<- r0
3663    GOTO_OPCODE(ip)                     @ jump to next instruction
3664    /* 9-10 instructions */
3665
3666
3667/* ------------------------------ */
3668    .balign 64
3669.L_OP_LONG_TO_DOUBLE: /* 0x86 */
3670/* File: armv6t2/OP_LONG_TO_DOUBLE.S */
3671/* File: armv6t2/unopWide.S */
3672    /*
3673     * Generic 64-bit unary operation.  Provide an "instr" line that
3674     * specifies an instruction that performs "result = op r0/r1".
3675     * This could be an ARM instruction or a function call.
3676     *
3677     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3678     */
3679    /* unop vA, vB */
3680    mov     r3, rINST, lsr #12          @ r3<- B
3681    ubfx    r9, rINST, #8, #4           @ r9<- A
3682    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3683    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3684    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3685    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3686                               @ optional op; may set condition codes
3687    bl      __aeabi_l2d                              @ r0/r1<- op, r2-r3 changed
3688    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3689    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3690    GOTO_OPCODE(ip)                     @ jump to next instruction
3691    /* 10-11 instructions */
3692
3693
3694/* ------------------------------ */
3695    .balign 64
3696.L_OP_FLOAT_TO_INT: /* 0x87 */
3697/* File: arm-vfp/OP_FLOAT_TO_INT.S */
3698/* File: arm-vfp/funop.S */
3699    /*
3700     * Generic 32-bit unary floating-point operation.  Provide an "instr"
3701     * line that specifies an instruction that performs "s1 = op s0".
3702     *
3703     * for: int-to-float, float-to-int
3704     */
3705    /* unop vA, vB */
3706    mov     r3, rINST, lsr #12          @ r3<- B
3707    mov     r9, rINST, lsr #8           @ r9<- A+
3708    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3709    flds    s0, [r3]                    @ s0<- vB
3710    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3711    and     r9, r9, #15                 @ r9<- A
3712    ftosizs s1, s0                              @ s1<- op
3713    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3714    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3715    fsts    s1, [r9]                    @ vA<- s1
3716    GOTO_OPCODE(ip)                     @ jump to next instruction
3717
3718
3719/* ------------------------------ */
3720    .balign 64
3721.L_OP_FLOAT_TO_LONG: /* 0x88 */
3722/* File: armv6t2/OP_FLOAT_TO_LONG.S */
3723@include "armv6t2/unopWider.S" {"instr":"bl      __aeabi_f2lz"}
3724/* File: armv6t2/unopWider.S */
3725    /*
3726     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3727     * that specifies an instruction that performs "result = op r0", where
3728     * "result" is a 64-bit quantity in r0/r1.
3729     *
3730     * For: int-to-long, int-to-double, float-to-long, float-to-double
3731     */
3732    /* unop vA, vB */
3733    mov     r3, rINST, lsr #12          @ r3<- B
3734    ubfx    r9, rINST, #8, #4           @ r9<- A
3735    GET_VREG(r0, r3)                    @ r0<- vB
3736    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3737                               @ optional op; may set condition codes
3738    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3739    bl      f2l_doconv                              @ r0<- op, r0-r3 changed
3740    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3741    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3742    GOTO_OPCODE(ip)                     @ jump to next instruction
3743    /* 9-10 instructions */
3744
3745
3746
3747/* ------------------------------ */
3748    .balign 64
3749.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */
3750/* File: arm-vfp/OP_FLOAT_TO_DOUBLE.S */
3751/* File: arm-vfp/funopWider.S */
3752    /*
3753     * Generic 32bit-to-64bit floating point unary operation.  Provide an
3754     * "instr" line that specifies an instruction that performs "d0 = op s0".
3755     *
3756     * For: int-to-double, float-to-double
3757     */
3758    /* unop vA, vB */
3759    mov     r3, rINST, lsr #12          @ r3<- B
3760    mov     r9, rINST, lsr #8           @ r9<- A+
3761    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3762    flds    s0, [r3]                    @ s0<- vB
3763    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3764    and     r9, r9, #15                 @ r9<- A
3765    fcvtds  d0, s0                              @ d0<- op
3766    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3767    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3768    fstd    d0, [r9]                    @ vA<- d0
3769    GOTO_OPCODE(ip)                     @ jump to next instruction
3770
3771
3772/* ------------------------------ */
3773    .balign 64
3774.L_OP_DOUBLE_TO_INT: /* 0x8a */
3775/* File: arm-vfp/OP_DOUBLE_TO_INT.S */
3776/* File: arm-vfp/funopNarrower.S */
3777    /*
3778     * Generic 64bit-to-32bit unary floating point operation.  Provide an
3779     * "instr" line that specifies an instruction that performs "s0 = op d0".
3780     *
3781     * For: double-to-int, double-to-float
3782     */
3783    /* unop vA, vB */
3784    mov     r3, rINST, lsr #12          @ r3<- B
3785    mov     r9, rINST, lsr #8           @ r9<- A+
3786    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3787    fldd    d0, [r3]                    @ d0<- vB
3788    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3789    and     r9, r9, #15                 @ r9<- A
3790    ftosizd  s0, d0                              @ s0<- op
3791    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3792    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3793    fsts    s0, [r9]                    @ vA<- s0
3794    GOTO_OPCODE(ip)                     @ jump to next instruction
3795
3796
3797/* ------------------------------ */
3798    .balign 64
3799.L_OP_DOUBLE_TO_LONG: /* 0x8b */
3800/* File: armv6t2/OP_DOUBLE_TO_LONG.S */
3801@include "armv6t2/unopWide.S" {"instr":"bl      __aeabi_d2lz"}
3802/* File: armv6t2/unopWide.S */
3803    /*
3804     * Generic 64-bit unary operation.  Provide an "instr" line that
3805     * specifies an instruction that performs "result = op r0/r1".
3806     * This could be an ARM instruction or a function call.
3807     *
3808     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3809     */
3810    /* unop vA, vB */
3811    mov     r3, rINST, lsr #12          @ r3<- B
3812    ubfx    r9, rINST, #8, #4           @ r9<- A
3813    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3814    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3815    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3816    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3817                               @ optional op; may set condition codes
3818    bl      d2l_doconv                              @ r0/r1<- op, r2-r3 changed
3819    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3820    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3821    GOTO_OPCODE(ip)                     @ jump to next instruction
3822    /* 10-11 instructions */
3823
3824
3825
3826/* ------------------------------ */
3827    .balign 64
3828.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */
3829/* File: arm-vfp/OP_DOUBLE_TO_FLOAT.S */
3830/* File: arm-vfp/funopNarrower.S */
3831    /*
3832     * Generic 64bit-to-32bit unary floating point operation.  Provide an
3833     * "instr" line that specifies an instruction that performs "s0 = op d0".
3834     *
3835     * For: double-to-int, double-to-float
3836     */
3837    /* unop vA, vB */
3838    mov     r3, rINST, lsr #12          @ r3<- B
3839    mov     r9, rINST, lsr #8           @ r9<- A+
3840    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3841    fldd    d0, [r3]                    @ d0<- vB
3842    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3843    and     r9, r9, #15                 @ r9<- A
3844    fcvtsd  s0, d0                              @ s0<- op
3845    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3846    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3847    fsts    s0, [r9]                    @ vA<- s0
3848    GOTO_OPCODE(ip)                     @ jump to next instruction
3849
3850
3851/* ------------------------------ */
3852    .balign 64
3853.L_OP_INT_TO_BYTE: /* 0x8d */
3854/* File: armv6t2/OP_INT_TO_BYTE.S */
3855/* File: armv6t2/unop.S */
3856    /*
3857     * Generic 32-bit unary operation.  Provide an "instr" line that
3858     * specifies an instruction that performs "result = op r0".
3859     * This could be an ARM instruction or a function call.
3860     *
3861     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3862     *      int-to-byte, int-to-char, int-to-short
3863     */
3864    /* unop vA, vB */
3865    mov     r3, rINST, lsr #12          @ r3<- B
3866    ubfx    r9, rINST, #8, #4           @ r9<- A
3867    GET_VREG(r0, r3)                    @ r0<- vB
3868                               @ optional op; may set condition codes
3869    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3870    sxtb    r0, r0                              @ r0<- op, r0-r3 changed
3871    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3872    SET_VREG(r0, r9)                    @ vAA<- r0
3873    GOTO_OPCODE(ip)                     @ jump to next instruction
3874    /* 8-9 instructions */
3875
3876
3877/* ------------------------------ */
3878    .balign 64
3879.L_OP_INT_TO_CHAR: /* 0x8e */
3880/* File: armv6t2/OP_INT_TO_CHAR.S */
3881/* File: armv6t2/unop.S */
3882    /*
3883     * Generic 32-bit unary operation.  Provide an "instr" line that
3884     * specifies an instruction that performs "result = op r0".
3885     * This could be an ARM instruction or a function call.
3886     *
3887     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3888     *      int-to-byte, int-to-char, int-to-short
3889     */
3890    /* unop vA, vB */
3891    mov     r3, rINST, lsr #12          @ r3<- B
3892    ubfx    r9, rINST, #8, #4           @ r9<- A
3893    GET_VREG(r0, r3)                    @ r0<- vB
3894                               @ optional op; may set condition codes
3895    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3896    uxth    r0, r0                              @ r0<- op, r0-r3 changed
3897    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3898    SET_VREG(r0, r9)                    @ vAA<- r0
3899    GOTO_OPCODE(ip)                     @ jump to next instruction
3900    /* 8-9 instructions */
3901
3902
3903/* ------------------------------ */
3904    .balign 64
3905.L_OP_INT_TO_SHORT: /* 0x8f */
3906/* File: armv6t2/OP_INT_TO_SHORT.S */
3907/* File: armv6t2/unop.S */
3908    /*
3909     * Generic 32-bit unary operation.  Provide an "instr" line that
3910     * specifies an instruction that performs "result = op r0".
3911     * This could be an ARM instruction or a function call.
3912     *
3913     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3914     *      int-to-byte, int-to-char, int-to-short
3915     */
3916    /* unop vA, vB */
3917    mov     r3, rINST, lsr #12          @ r3<- B
3918    ubfx    r9, rINST, #8, #4           @ r9<- A
3919    GET_VREG(r0, r3)                    @ r0<- vB
3920                               @ optional op; may set condition codes
3921    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3922    sxth    r0, r0                              @ r0<- op, r0-r3 changed
3923    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3924    SET_VREG(r0, r9)                    @ vAA<- r0
3925    GOTO_OPCODE(ip)                     @ jump to next instruction
3926    /* 8-9 instructions */
3927
3928
3929/* ------------------------------ */
3930    .balign 64
3931.L_OP_ADD_INT: /* 0x90 */
3932/* File: armv5te/OP_ADD_INT.S */
3933/* File: armv5te/binop.S */
3934    /*
3935     * Generic 32-bit binary operation.  Provide an "instr" line that
3936     * specifies an instruction that performs "result = r0 op r1".
3937     * This could be an ARM instruction or a function call.  (If the result
3938     * comes back in a register other than r0, you can override "result".)
3939     *
3940     * If "chkzero" is set to 1, we perform a divide-by-zero check on
3941     * vCC (r1).  Useful for integer division and modulus.  Note that we
3942     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
3943     * handles it correctly.
3944     *
3945     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
3946     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
3947     *      mul-float, div-float, rem-float
3948     */
3949    /* binop vAA, vBB, vCC */
3950    FETCH(r0, 1)                        @ r0<- CCBB
3951    mov     r9, rINST, lsr #8           @ r9<- AA
3952    mov     r3, r0, lsr #8              @ r3<- CC
3953    and     r2, r0, #255                @ r2<- BB
3954    GET_VREG(r1, r3)                    @ r1<- vCC
3955    GET_VREG(r0, r2)                    @ r0<- vBB
3956    .if 0
3957    cmp     r1, #0                      @ is second operand zero?
3958    beq     common_errDivideByZero
3959    .endif
3960
3961    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3962                               @ optional op; may set condition codes
3963    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
3964    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3965    SET_VREG(r0, r9)               @ vAA<- r0
3966    GOTO_OPCODE(ip)                     @ jump to next instruction
3967    /* 11-14 instructions */
3968
3969
3970/* ------------------------------ */
3971    .balign 64
3972.L_OP_SUB_INT: /* 0x91 */
3973/* File: armv5te/OP_SUB_INT.S */
3974/* File: armv5te/binop.S */
3975    /*
3976     * Generic 32-bit binary operation.  Provide an "instr" line that
3977     * specifies an instruction that performs "result = r0 op r1".
3978     * This could be an ARM instruction or a function call.  (If the result
3979     * comes back in a register other than r0, you can override "result".)
3980     *
3981     * If "chkzero" is set to 1, we perform a divide-by-zero check on
3982     * vCC (r1).  Useful for integer division and modulus.  Note that we
3983     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
3984     * handles it correctly.
3985     *
3986     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
3987     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
3988     *      mul-float, div-float, rem-float
3989     */
3990    /* binop vAA, vBB, vCC */
3991    FETCH(r0, 1)                        @ r0<- CCBB
3992    mov     r9, rINST, lsr #8           @ r9<- AA
3993    mov     r3, r0, lsr #8              @ r3<- CC
3994    and     r2, r0, #255                @ r2<- BB
3995    GET_VREG(r1, r3)                    @ r1<- vCC
3996    GET_VREG(r0, r2)                    @ r0<- vBB
3997    .if 0
3998    cmp     r1, #0                      @ is second operand zero?
3999    beq     common_errDivideByZero
4000    .endif
4001
4002    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4003                               @ optional op; may set condition codes
4004    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
4005    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4006    SET_VREG(r0, r9)               @ vAA<- r0
4007    GOTO_OPCODE(ip)                     @ jump to next instruction
4008    /* 11-14 instructions */
4009
4010
4011/* ------------------------------ */
4012    .balign 64
4013.L_OP_MUL_INT: /* 0x92 */
4014/* File: armv5te/OP_MUL_INT.S */
4015/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
4016/* File: armv5te/binop.S */
4017    /*
4018     * Generic 32-bit binary operation.  Provide an "instr" line that
4019     * specifies an instruction that performs "result = r0 op r1".
4020     * This could be an ARM instruction or a function call.  (If the result
4021     * comes back in a register other than r0, you can override "result".)
4022     *
4023     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4024     * vCC (r1).  Useful for integer division and modulus.  Note that we
4025     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4026     * handles it correctly.
4027     *
4028     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4029     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4030     *      mul-float, div-float, rem-float
4031     */
4032    /* binop vAA, vBB, vCC */
4033    FETCH(r0, 1)                        @ r0<- CCBB
4034    mov     r9, rINST, lsr #8           @ r9<- AA
4035    mov     r3, r0, lsr #8              @ r3<- CC
4036    and     r2, r0, #255                @ r2<- BB
4037    GET_VREG(r1, r3)                    @ r1<- vCC
4038    GET_VREG(r0, r2)                    @ r0<- vBB
4039    .if 0
4040    cmp     r1, #0                      @ is second operand zero?
4041    beq     common_errDivideByZero
4042    .endif
4043
4044    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4045                               @ optional op; may set condition codes
4046    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
4047    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4048    SET_VREG(r0, r9)               @ vAA<- r0
4049    GOTO_OPCODE(ip)                     @ jump to next instruction
4050    /* 11-14 instructions */
4051
4052
4053/* ------------------------------ */
4054    .balign 64
4055.L_OP_DIV_INT: /* 0x93 */
4056/* File: armv5te/OP_DIV_INT.S */
4057/* File: armv5te/binop.S */
4058    /*
4059     * Generic 32-bit binary operation.  Provide an "instr" line that
4060     * specifies an instruction that performs "result = r0 op r1".
4061     * This could be an ARM instruction or a function call.  (If the result
4062     * comes back in a register other than r0, you can override "result".)
4063     *
4064     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4065     * vCC (r1).  Useful for integer division and modulus.  Note that we
4066     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4067     * handles it correctly.
4068     *
4069     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4070     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4071     *      mul-float, div-float, rem-float
4072     */
4073    /* binop vAA, vBB, vCC */
4074    FETCH(r0, 1)                        @ r0<- CCBB
4075    mov     r9, rINST, lsr #8           @ r9<- AA
4076    mov     r3, r0, lsr #8              @ r3<- CC
4077    and     r2, r0, #255                @ r2<- BB
4078    GET_VREG(r1, r3)                    @ r1<- vCC
4079    GET_VREG(r0, r2)                    @ r0<- vBB
4080    .if 1
4081    cmp     r1, #0                      @ is second operand zero?
4082    beq     common_errDivideByZero
4083    .endif
4084
4085    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4086                               @ optional op; may set condition codes
4087    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
4088    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4089    SET_VREG(r0, r9)               @ vAA<- r0
4090    GOTO_OPCODE(ip)                     @ jump to next instruction
4091    /* 11-14 instructions */
4092
4093
4094/* ------------------------------ */
4095    .balign 64
4096.L_OP_REM_INT: /* 0x94 */
4097/* File: armv5te/OP_REM_INT.S */
4098/* idivmod returns quotient in r0 and remainder in r1 */
4099/* File: armv5te/binop.S */
4100    /*
4101     * Generic 32-bit binary operation.  Provide an "instr" line that
4102     * specifies an instruction that performs "result = r0 op r1".
4103     * This could be an ARM instruction or a function call.  (If the result
4104     * comes back in a register other than r0, you can override "result".)
4105     *
4106     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4107     * vCC (r1).  Useful for integer division and modulus.  Note that we
4108     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4109     * handles it correctly.
4110     *
4111     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4112     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4113     *      mul-float, div-float, rem-float
4114     */
4115    /* binop vAA, vBB, vCC */
4116    FETCH(r0, 1)                        @ r0<- CCBB
4117    mov     r9, rINST, lsr #8           @ r9<- AA
4118    mov     r3, r0, lsr #8              @ r3<- CC
4119    and     r2, r0, #255                @ r2<- BB
4120    GET_VREG(r1, r3)                    @ r1<- vCC
4121    GET_VREG(r0, r2)                    @ r0<- vBB
4122    .if 1
4123    cmp     r1, #0                      @ is second operand zero?
4124    beq     common_errDivideByZero
4125    .endif
4126
4127    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4128                               @ optional op; may set condition codes
4129    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
4130    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4131    SET_VREG(r1, r9)               @ vAA<- r1
4132    GOTO_OPCODE(ip)                     @ jump to next instruction
4133    /* 11-14 instructions */
4134
4135
4136/* ------------------------------ */
4137    .balign 64
4138.L_OP_AND_INT: /* 0x95 */
4139/* File: armv5te/OP_AND_INT.S */
4140/* File: armv5te/binop.S */
4141    /*
4142     * Generic 32-bit binary operation.  Provide an "instr" line that
4143     * specifies an instruction that performs "result = r0 op r1".
4144     * This could be an ARM instruction or a function call.  (If the result
4145     * comes back in a register other than r0, you can override "result".)
4146     *
4147     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4148     * vCC (r1).  Useful for integer division and modulus.  Note that we
4149     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4150     * handles it correctly.
4151     *
4152     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4153     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4154     *      mul-float, div-float, rem-float
4155     */
4156    /* binop vAA, vBB, vCC */
4157    FETCH(r0, 1)                        @ r0<- CCBB
4158    mov     r9, rINST, lsr #8           @ r9<- AA
4159    mov     r3, r0, lsr #8              @ r3<- CC
4160    and     r2, r0, #255                @ r2<- BB
4161    GET_VREG(r1, r3)                    @ r1<- vCC
4162    GET_VREG(r0, r2)                    @ r0<- vBB
4163    .if 0
4164    cmp     r1, #0                      @ is second operand zero?
4165    beq     common_errDivideByZero
4166    .endif
4167
4168    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4169                               @ optional op; may set condition codes
4170    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
4171    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4172    SET_VREG(r0, r9)               @ vAA<- r0
4173    GOTO_OPCODE(ip)                     @ jump to next instruction
4174    /* 11-14 instructions */
4175
4176
4177/* ------------------------------ */
4178    .balign 64
4179.L_OP_OR_INT: /* 0x96 */
4180/* File: armv5te/OP_OR_INT.S */
4181/* File: armv5te/binop.S */
4182    /*
4183     * Generic 32-bit binary operation.  Provide an "instr" line that
4184     * specifies an instruction that performs "result = r0 op r1".
4185     * This could be an ARM instruction or a function call.  (If the result
4186     * comes back in a register other than r0, you can override "result".)
4187     *
4188     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4189     * vCC (r1).  Useful for integer division and modulus.  Note that we
4190     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4191     * handles it correctly.
4192     *
4193     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4194     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4195     *      mul-float, div-float, rem-float
4196     */
4197    /* binop vAA, vBB, vCC */
4198    FETCH(r0, 1)                        @ r0<- CCBB
4199    mov     r9, rINST, lsr #8           @ r9<- AA
4200    mov     r3, r0, lsr #8              @ r3<- CC
4201    and     r2, r0, #255                @ r2<- BB
4202    GET_VREG(r1, r3)                    @ r1<- vCC
4203    GET_VREG(r0, r2)                    @ r0<- vBB
4204    .if 0
4205    cmp     r1, #0                      @ is second operand zero?
4206    beq     common_errDivideByZero
4207    .endif
4208
4209    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4210                               @ optional op; may set condition codes
4211    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
4212    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4213    SET_VREG(r0, r9)               @ vAA<- r0
4214    GOTO_OPCODE(ip)                     @ jump to next instruction
4215    /* 11-14 instructions */
4216
4217
4218/* ------------------------------ */
4219    .balign 64
4220.L_OP_XOR_INT: /* 0x97 */
4221/* File: armv5te/OP_XOR_INT.S */
4222/* File: armv5te/binop.S */
4223    /*
4224     * Generic 32-bit binary operation.  Provide an "instr" line that
4225     * specifies an instruction that performs "result = r0 op r1".
4226     * This could be an ARM instruction or a function call.  (If the result
4227     * comes back in a register other than r0, you can override "result".)
4228     *
4229     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4230     * vCC (r1).  Useful for integer division and modulus.  Note that we
4231     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4232     * handles it correctly.
4233     *
4234     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4235     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4236     *      mul-float, div-float, rem-float
4237     */
4238    /* binop vAA, vBB, vCC */
4239    FETCH(r0, 1)                        @ r0<- CCBB
4240    mov     r9, rINST, lsr #8           @ r9<- AA
4241    mov     r3, r0, lsr #8              @ r3<- CC
4242    and     r2, r0, #255                @ r2<- BB
4243    GET_VREG(r1, r3)                    @ r1<- vCC
4244    GET_VREG(r0, r2)                    @ r0<- vBB
4245    .if 0
4246    cmp     r1, #0                      @ is second operand zero?
4247    beq     common_errDivideByZero
4248    .endif
4249
4250    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4251                               @ optional op; may set condition codes
4252    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
4253    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4254    SET_VREG(r0, r9)               @ vAA<- r0
4255    GOTO_OPCODE(ip)                     @ jump to next instruction
4256    /* 11-14 instructions */
4257
4258
4259/* ------------------------------ */
4260    .balign 64
4261.L_OP_SHL_INT: /* 0x98 */
4262/* File: armv5te/OP_SHL_INT.S */
4263/* File: armv5te/binop.S */
4264    /*
4265     * Generic 32-bit binary operation.  Provide an "instr" line that
4266     * specifies an instruction that performs "result = r0 op r1".
4267     * This could be an ARM instruction or a function call.  (If the result
4268     * comes back in a register other than r0, you can override "result".)
4269     *
4270     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4271     * vCC (r1).  Useful for integer division and modulus.  Note that we
4272     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4273     * handles it correctly.
4274     *
4275     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4276     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4277     *      mul-float, div-float, rem-float
4278     */
4279    /* binop vAA, vBB, vCC */
4280    FETCH(r0, 1)                        @ r0<- CCBB
4281    mov     r9, rINST, lsr #8           @ r9<- AA
4282    mov     r3, r0, lsr #8              @ r3<- CC
4283    and     r2, r0, #255                @ r2<- BB
4284    GET_VREG(r1, r3)                    @ r1<- vCC
4285    GET_VREG(r0, r2)                    @ r0<- vBB
4286    .if 0
4287    cmp     r1, #0                      @ is second operand zero?
4288    beq     common_errDivideByZero
4289    .endif
4290
4291    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4292    and     r1, r1, #31                           @ optional op; may set condition codes
4293    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
4294    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4295    SET_VREG(r0, r9)               @ vAA<- r0
4296    GOTO_OPCODE(ip)                     @ jump to next instruction
4297    /* 11-14 instructions */
4298
4299
4300/* ------------------------------ */
4301    .balign 64
4302.L_OP_SHR_INT: /* 0x99 */
4303/* File: armv5te/OP_SHR_INT.S */
4304/* File: armv5te/binop.S */
4305    /*
4306     * Generic 32-bit binary operation.  Provide an "instr" line that
4307     * specifies an instruction that performs "result = r0 op r1".
4308     * This could be an ARM instruction or a function call.  (If the result
4309     * comes back in a register other than r0, you can override "result".)
4310     *
4311     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4312     * vCC (r1).  Useful for integer division and modulus.  Note that we
4313     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4314     * handles it correctly.
4315     *
4316     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4317     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4318     *      mul-float, div-float, rem-float
4319     */
4320    /* binop vAA, vBB, vCC */
4321    FETCH(r0, 1)                        @ r0<- CCBB
4322    mov     r9, rINST, lsr #8           @ r9<- AA
4323    mov     r3, r0, lsr #8              @ r3<- CC
4324    and     r2, r0, #255                @ r2<- BB
4325    GET_VREG(r1, r3)                    @ r1<- vCC
4326    GET_VREG(r0, r2)                    @ r0<- vBB
4327    .if 0
4328    cmp     r1, #0                      @ is second operand zero?
4329    beq     common_errDivideByZero
4330    .endif
4331
4332    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4333    and     r1, r1, #31                           @ optional op; may set condition codes
4334    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
4335    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4336    SET_VREG(r0, r9)               @ vAA<- r0
4337    GOTO_OPCODE(ip)                     @ jump to next instruction
4338    /* 11-14 instructions */
4339
4340
4341/* ------------------------------ */
4342    .balign 64
4343.L_OP_USHR_INT: /* 0x9a */
4344/* File: armv5te/OP_USHR_INT.S */
4345/* File: armv5te/binop.S */
4346    /*
4347     * Generic 32-bit binary operation.  Provide an "instr" line that
4348     * specifies an instruction that performs "result = r0 op r1".
4349     * This could be an ARM instruction or a function call.  (If the result
4350     * comes back in a register other than r0, you can override "result".)
4351     *
4352     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4353     * vCC (r1).  Useful for integer division and modulus.  Note that we
4354     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4355     * handles it correctly.
4356     *
4357     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4358     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4359     *      mul-float, div-float, rem-float
4360     */
4361    /* binop vAA, vBB, vCC */
4362    FETCH(r0, 1)                        @ r0<- CCBB
4363    mov     r9, rINST, lsr #8           @ r9<- AA
4364    mov     r3, r0, lsr #8              @ r3<- CC
4365    and     r2, r0, #255                @ r2<- BB
4366    GET_VREG(r1, r3)                    @ r1<- vCC
4367    GET_VREG(r0, r2)                    @ r0<- vBB
4368    .if 0
4369    cmp     r1, #0                      @ is second operand zero?
4370    beq     common_errDivideByZero
4371    .endif
4372
4373    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4374    and     r1, r1, #31                           @ optional op; may set condition codes
4375    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
4376    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4377    SET_VREG(r0, r9)               @ vAA<- r0
4378    GOTO_OPCODE(ip)                     @ jump to next instruction
4379    /* 11-14 instructions */
4380
4381
4382/* ------------------------------ */
4383    .balign 64
4384.L_OP_ADD_LONG: /* 0x9b */
4385/* File: armv5te/OP_ADD_LONG.S */
4386/* File: armv5te/binopWide.S */
4387    /*
4388     * Generic 64-bit binary operation.  Provide an "instr" line that
4389     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4390     * This could be an ARM instruction or a function call.  (If the result
4391     * comes back in a register other than r0, you can override "result".)
4392     *
4393     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4394     * vCC (r1).  Useful for integer division and modulus.
4395     *
4396     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4397     *      xor-long, add-double, sub-double, mul-double, div-double,
4398     *      rem-double
4399     *
4400     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4401     */
4402    /* binop vAA, vBB, vCC */
4403    FETCH(r0, 1)                        @ r0<- CCBB
4404    mov     r9, rINST, lsr #8           @ r9<- AA
4405    and     r2, r0, #255                @ r2<- BB
4406    mov     r3, r0, lsr #8              @ r3<- CC
4407    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4408    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4409    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4410    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4411    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4412    .if 0
4413    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4414    beq     common_errDivideByZero
4415    .endif
4416    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4417
4418    adds    r0, r0, r2                           @ optional op; may set condition codes
4419    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
4420    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4421    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4422    GOTO_OPCODE(ip)                     @ jump to next instruction
4423    /* 14-17 instructions */
4424
4425
4426/* ------------------------------ */
4427    .balign 64
4428.L_OP_SUB_LONG: /* 0x9c */
4429/* File: armv5te/OP_SUB_LONG.S */
4430/* File: armv5te/binopWide.S */
4431    /*
4432     * Generic 64-bit binary operation.  Provide an "instr" line that
4433     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4434     * This could be an ARM instruction or a function call.  (If the result
4435     * comes back in a register other than r0, you can override "result".)
4436     *
4437     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4438     * vCC (r1).  Useful for integer division and modulus.
4439     *
4440     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4441     *      xor-long, add-double, sub-double, mul-double, div-double,
4442     *      rem-double
4443     *
4444     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4445     */
4446    /* binop vAA, vBB, vCC */
4447    FETCH(r0, 1)                        @ r0<- CCBB
4448    mov     r9, rINST, lsr #8           @ r9<- AA
4449    and     r2, r0, #255                @ r2<- BB
4450    mov     r3, r0, lsr #8              @ r3<- CC
4451    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4452    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4453    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4454    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4455    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4456    .if 0
4457    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4458    beq     common_errDivideByZero
4459    .endif
4460    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4461
4462    subs    r0, r0, r2                           @ optional op; may set condition codes
4463    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
4464    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4465    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4466    GOTO_OPCODE(ip)                     @ jump to next instruction
4467    /* 14-17 instructions */
4468
4469
4470/* ------------------------------ */
4471    .balign 64
4472.L_OP_MUL_LONG: /* 0x9d */
4473/* File: armv5te/OP_MUL_LONG.S */
4474    /*
4475     * Signed 64-bit integer multiply.
4476     *
4477     * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
4478     *        WX
4479     *      x YZ
4480     *  --------
4481     *     ZW ZX
4482     *  YW YX
4483     *
4484     * The low word of the result holds ZX, the high word holds
4485     * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
4486     * it doesn't fit in the low 64 bits.
4487     *
4488     * Unlike most ARM math operations, multiply instructions have
4489     * restrictions on using the same register more than once (Rd and Rm
4490     * cannot be the same).
4491     */
4492    /* mul-long vAA, vBB, vCC */
4493    FETCH(r0, 1)                        @ r0<- CCBB
4494    and     r2, r0, #255                @ r2<- BB
4495    mov     r3, r0, lsr #8              @ r3<- CC
4496    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4497    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4498    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4499    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4500    mul     ip, r2, r1                  @  ip<- ZxW
4501    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
4502    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
4503    mov     r0, rINST, lsr #8           @ r0<- AA
4504    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
4505    add     r0, rFP, r0, lsl #2         @ r0<- &fp[AA]
4506    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4507    b       .LOP_MUL_LONG_finish
4508
4509/* ------------------------------ */
4510    .balign 64
4511.L_OP_DIV_LONG: /* 0x9e */
4512/* File: armv5te/OP_DIV_LONG.S */
4513/* File: armv5te/binopWide.S */
4514    /*
4515     * Generic 64-bit binary operation.  Provide an "instr" line that
4516     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4517     * This could be an ARM instruction or a function call.  (If the result
4518     * comes back in a register other than r0, you can override "result".)
4519     *
4520     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4521     * vCC (r1).  Useful for integer division and modulus.
4522     *
4523     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4524     *      xor-long, add-double, sub-double, mul-double, div-double,
4525     *      rem-double
4526     *
4527     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4528     */
4529    /* binop vAA, vBB, vCC */
4530    FETCH(r0, 1)                        @ r0<- CCBB
4531    mov     r9, rINST, lsr #8           @ r9<- AA
4532    and     r2, r0, #255                @ r2<- BB
4533    mov     r3, r0, lsr #8              @ r3<- CC
4534    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4535    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4536    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4537    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4538    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4539    .if 1
4540    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4541    beq     common_errDivideByZero
4542    .endif
4543    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4544
4545                               @ optional op; may set condition codes
4546    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4547    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4548    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4549    GOTO_OPCODE(ip)                     @ jump to next instruction
4550    /* 14-17 instructions */
4551
4552
4553/* ------------------------------ */
4554    .balign 64
4555.L_OP_REM_LONG: /* 0x9f */
4556/* File: armv5te/OP_REM_LONG.S */
4557/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
4558/* File: armv5te/binopWide.S */
4559    /*
4560     * Generic 64-bit binary operation.  Provide an "instr" line that
4561     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4562     * This could be an ARM instruction or a function call.  (If the result
4563     * comes back in a register other than r0, you can override "result".)
4564     *
4565     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4566     * vCC (r1).  Useful for integer division and modulus.
4567     *
4568     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4569     *      xor-long, add-double, sub-double, mul-double, div-double,
4570     *      rem-double
4571     *
4572     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4573     */
4574    /* binop vAA, vBB, vCC */
4575    FETCH(r0, 1)                        @ r0<- CCBB
4576    mov     r9, rINST, lsr #8           @ r9<- AA
4577    and     r2, r0, #255                @ r2<- BB
4578    mov     r3, r0, lsr #8              @ r3<- CC
4579    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4580    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4581    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4582    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4583    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4584    .if 1
4585    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4586    beq     common_errDivideByZero
4587    .endif
4588    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4589
4590                               @ optional op; may set condition codes
4591    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4592    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4593    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
4594    GOTO_OPCODE(ip)                     @ jump to next instruction
4595    /* 14-17 instructions */
4596
4597
4598/* ------------------------------ */
4599    .balign 64
4600.L_OP_AND_LONG: /* 0xa0 */
4601/* File: armv5te/OP_AND_LONG.S */
4602/* File: armv5te/binopWide.S */
4603    /*
4604     * Generic 64-bit binary operation.  Provide an "instr" line that
4605     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4606     * This could be an ARM instruction or a function call.  (If the result
4607     * comes back in a register other than r0, you can override "result".)
4608     *
4609     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4610     * vCC (r1).  Useful for integer division and modulus.
4611     *
4612     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4613     *      xor-long, add-double, sub-double, mul-double, div-double,
4614     *      rem-double
4615     *
4616     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4617     */
4618    /* binop vAA, vBB, vCC */
4619    FETCH(r0, 1)                        @ r0<- CCBB
4620    mov     r9, rINST, lsr #8           @ r9<- AA
4621    and     r2, r0, #255                @ r2<- BB
4622    mov     r3, r0, lsr #8              @ r3<- CC
4623    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4624    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4625    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4626    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4627    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4628    .if 0
4629    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4630    beq     common_errDivideByZero
4631    .endif
4632    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4633
4634    and     r0, r0, r2                           @ optional op; may set condition codes
4635    and     r1, r1, r3                              @ result<- op, r0-r3 changed
4636    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4637    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4638    GOTO_OPCODE(ip)                     @ jump to next instruction
4639    /* 14-17 instructions */
4640
4641
4642/* ------------------------------ */
4643    .balign 64
4644.L_OP_OR_LONG: /* 0xa1 */
4645/* File: armv5te/OP_OR_LONG.S */
4646/* File: armv5te/binopWide.S */
4647    /*
4648     * Generic 64-bit binary operation.  Provide an "instr" line that
4649     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4650     * This could be an ARM instruction or a function call.  (If the result
4651     * comes back in a register other than r0, you can override "result".)
4652     *
4653     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4654     * vCC (r1).  Useful for integer division and modulus.
4655     *
4656     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4657     *      xor-long, add-double, sub-double, mul-double, div-double,
4658     *      rem-double
4659     *
4660     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4661     */
4662    /* binop vAA, vBB, vCC */
4663    FETCH(r0, 1)                        @ r0<- CCBB
4664    mov     r9, rINST, lsr #8           @ r9<- AA
4665    and     r2, r0, #255                @ r2<- BB
4666    mov     r3, r0, lsr #8              @ r3<- CC
4667    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4668    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4669    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4670    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4671    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4672    .if 0
4673    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4674    beq     common_errDivideByZero
4675    .endif
4676    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4677
4678    orr     r0, r0, r2                           @ optional op; may set condition codes
4679    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
4680    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4681    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4682    GOTO_OPCODE(ip)                     @ jump to next instruction
4683    /* 14-17 instructions */
4684
4685
4686/* ------------------------------ */
4687    .balign 64
4688.L_OP_XOR_LONG: /* 0xa2 */
4689/* File: armv5te/OP_XOR_LONG.S */
4690/* File: armv5te/binopWide.S */
4691    /*
4692     * Generic 64-bit binary operation.  Provide an "instr" line that
4693     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4694     * This could be an ARM instruction or a function call.  (If the result
4695     * comes back in a register other than r0, you can override "result".)
4696     *
4697     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4698     * vCC (r1).  Useful for integer division and modulus.
4699     *
4700     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4701     *      xor-long, add-double, sub-double, mul-double, div-double,
4702     *      rem-double
4703     *
4704     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4705     */
4706    /* binop vAA, vBB, vCC */
4707    FETCH(r0, 1)                        @ r0<- CCBB
4708    mov     r9, rINST, lsr #8           @ r9<- AA
4709    and     r2, r0, #255                @ r2<- BB
4710    mov     r3, r0, lsr #8              @ r3<- CC
4711    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4712    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4713    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4714    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4715    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4716    .if 0
4717    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4718    beq     common_errDivideByZero
4719    .endif
4720    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4721
4722    eor     r0, r0, r2                           @ optional op; may set condition codes
4723    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
4724    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4725    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4726    GOTO_OPCODE(ip)                     @ jump to next instruction
4727    /* 14-17 instructions */
4728
4729
4730/* ------------------------------ */
4731    .balign 64
4732.L_OP_SHL_LONG: /* 0xa3 */
4733/* File: armv5te/OP_SHL_LONG.S */
4734    /*
4735     * Long integer shift.  This is different from the generic 32/64-bit
4736     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4737     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4738     * 6 bits of the shift distance.
4739     */
4740    /* shl-long vAA, vBB, vCC */
4741    FETCH(r0, 1)                        @ r0<- CCBB
4742    mov     r9, rINST, lsr #8           @ r9<- AA
4743    and     r3, r0, #255                @ r3<- BB
4744    mov     r0, r0, lsr #8              @ r0<- CC
4745    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4746    GET_VREG(r2, r0)                    @ r2<- vCC
4747    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4748    and     r2, r2, #63                 @ r2<- r2 & 0x3f
4749    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4750
4751    mov     r1, r1, asl r2              @  r1<- r1 << r2
4752    rsb     r3, r2, #32                 @  r3<- 32 - r2
4753    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
4754    subs    ip, r2, #32                 @  ip<- r2 - 32
4755    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
4756    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4757    b       .LOP_SHL_LONG_finish
4758
4759/* ------------------------------ */
4760    .balign 64
4761.L_OP_SHR_LONG: /* 0xa4 */
4762/* File: armv5te/OP_SHR_LONG.S */
4763    /*
4764     * Long integer shift.  This is different from the generic 32/64-bit
4765     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4766     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4767     * 6 bits of the shift distance.
4768     */
4769    /* shr-long vAA, vBB, vCC */
4770    FETCH(r0, 1)                        @ r0<- CCBB
4771    mov     r9, rINST, lsr #8           @ r9<- AA
4772    and     r3, r0, #255                @ r3<- BB
4773    mov     r0, r0, lsr #8              @ r0<- CC
4774    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4775    GET_VREG(r2, r0)                    @ r2<- vCC
4776    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4777    and     r2, r2, #63                 @ r0<- r0 & 0x3f
4778    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4779
4780    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
4781    rsb     r3, r2, #32                 @  r3<- 32 - r2
4782    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
4783    subs    ip, r2, #32                 @  ip<- r2 - 32
4784    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
4785    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4786    b       .LOP_SHR_LONG_finish
4787
4788/* ------------------------------ */
4789    .balign 64
4790.L_OP_USHR_LONG: /* 0xa5 */
4791/* File: armv5te/OP_USHR_LONG.S */
4792    /*
4793     * Long integer shift.  This is different from the generic 32/64-bit
4794     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4795     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4796     * 6 bits of the shift distance.
4797     */
4798    /* ushr-long vAA, vBB, vCC */
4799    FETCH(r0, 1)                        @ r0<- CCBB
4800    mov     r9, rINST, lsr #8           @ r9<- AA
4801    and     r3, r0, #255                @ r3<- BB
4802    mov     r0, r0, lsr #8              @ r0<- CC
4803    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4804    GET_VREG(r2, r0)                    @ r2<- vCC
4805    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4806    and     r2, r2, #63                 @ r0<- r0 & 0x3f
4807    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4808
4809    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
4810    rsb     r3, r2, #32                 @  r3<- 32 - r2
4811    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
4812    subs    ip, r2, #32                 @  ip<- r2 - 32
4813    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
4814    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4815    b       .LOP_USHR_LONG_finish
4816
4817/* ------------------------------ */
4818    .balign 64
4819.L_OP_ADD_FLOAT: /* 0xa6 */
4820/* File: arm-vfp/OP_ADD_FLOAT.S */
4821/* File: arm-vfp/fbinop.S */
4822    /*
4823     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4824     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4825     * use the "softfp" ABI, this must be an instruction, not a function call.
4826     *
4827     * For: add-float, sub-float, mul-float, div-float
4828     */
4829    /* floatop vAA, vBB, vCC */
4830    FETCH(r0, 1)                        @ r0<- CCBB
4831    mov     r9, rINST, lsr #8           @ r9<- AA
4832    mov     r3, r0, lsr #8              @ r3<- CC
4833    and     r2, r0, #255                @ r2<- BB
4834    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4835    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4836    flds    s1, [r3]                    @ s1<- vCC
4837    flds    s0, [r2]                    @ s0<- vBB
4838
4839    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4840    fadds   s2, s0, s1                              @ s2<- op
4841    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4842    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4843    fsts    s2, [r9]                    @ vAA<- s2
4844    GOTO_OPCODE(ip)                     @ jump to next instruction
4845
4846
4847/* ------------------------------ */
4848    .balign 64
4849.L_OP_SUB_FLOAT: /* 0xa7 */
4850/* File: arm-vfp/OP_SUB_FLOAT.S */
4851/* File: arm-vfp/fbinop.S */
4852    /*
4853     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4854     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4855     * use the "softfp" ABI, this must be an instruction, not a function call.
4856     *
4857     * For: add-float, sub-float, mul-float, div-float
4858     */
4859    /* floatop vAA, vBB, vCC */
4860    FETCH(r0, 1)                        @ r0<- CCBB
4861    mov     r9, rINST, lsr #8           @ r9<- AA
4862    mov     r3, r0, lsr #8              @ r3<- CC
4863    and     r2, r0, #255                @ r2<- BB
4864    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4865    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4866    flds    s1, [r3]                    @ s1<- vCC
4867    flds    s0, [r2]                    @ s0<- vBB
4868
4869    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4870    fsubs   s2, s0, s1                              @ s2<- op
4871    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4872    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4873    fsts    s2, [r9]                    @ vAA<- s2
4874    GOTO_OPCODE(ip)                     @ jump to next instruction
4875
4876
4877/* ------------------------------ */
4878    .balign 64
4879.L_OP_MUL_FLOAT: /* 0xa8 */
4880/* File: arm-vfp/OP_MUL_FLOAT.S */
4881/* File: arm-vfp/fbinop.S */
4882    /*
4883     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4884     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4885     * use the "softfp" ABI, this must be an instruction, not a function call.
4886     *
4887     * For: add-float, sub-float, mul-float, div-float
4888     */
4889    /* floatop vAA, vBB, vCC */
4890    FETCH(r0, 1)                        @ r0<- CCBB
4891    mov     r9, rINST, lsr #8           @ r9<- AA
4892    mov     r3, r0, lsr #8              @ r3<- CC
4893    and     r2, r0, #255                @ r2<- BB
4894    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4895    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4896    flds    s1, [r3]                    @ s1<- vCC
4897    flds    s0, [r2]                    @ s0<- vBB
4898
4899    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4900    fmuls   s2, s0, s1                              @ s2<- op
4901    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4902    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4903    fsts    s2, [r9]                    @ vAA<- s2
4904    GOTO_OPCODE(ip)                     @ jump to next instruction
4905
4906
4907/* ------------------------------ */
4908    .balign 64
4909.L_OP_DIV_FLOAT: /* 0xa9 */
4910/* File: arm-vfp/OP_DIV_FLOAT.S */
4911/* File: arm-vfp/fbinop.S */
4912    /*
4913     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4914     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4915     * use the "softfp" ABI, this must be an instruction, not a function call.
4916     *
4917     * For: add-float, sub-float, mul-float, div-float
4918     */
4919    /* floatop vAA, vBB, vCC */
4920    FETCH(r0, 1)                        @ r0<- CCBB
4921    mov     r9, rINST, lsr #8           @ r9<- AA
4922    mov     r3, r0, lsr #8              @ r3<- CC
4923    and     r2, r0, #255                @ r2<- BB
4924    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4925    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4926    flds    s1, [r3]                    @ s1<- vCC
4927    flds    s0, [r2]                    @ s0<- vBB
4928
4929    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4930    fdivs   s2, s0, s1                              @ s2<- op
4931    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4932    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4933    fsts    s2, [r9]                    @ vAA<- s2
4934    GOTO_OPCODE(ip)                     @ jump to next instruction
4935
4936
4937/* ------------------------------ */
4938    .balign 64
4939.L_OP_REM_FLOAT: /* 0xaa */
4940/* File: armv5te/OP_REM_FLOAT.S */
4941/* EABI doesn't define a float remainder function, but libm does */
4942/* File: armv5te/binop.S */
4943    /*
4944     * Generic 32-bit binary operation.  Provide an "instr" line that
4945     * specifies an instruction that performs "result = r0 op r1".
4946     * This could be an ARM instruction or a function call.  (If the result
4947     * comes back in a register other than r0, you can override "result".)
4948     *
4949     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4950     * vCC (r1).  Useful for integer division and modulus.  Note that we
4951     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4952     * handles it correctly.
4953     *
4954     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4955     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4956     *      mul-float, div-float, rem-float
4957     */
4958    /* binop vAA, vBB, vCC */
4959    FETCH(r0, 1)                        @ r0<- CCBB
4960    mov     r9, rINST, lsr #8           @ r9<- AA
4961    mov     r3, r0, lsr #8              @ r3<- CC
4962    and     r2, r0, #255                @ r2<- BB
4963    GET_VREG(r1, r3)                    @ r1<- vCC
4964    GET_VREG(r0, r2)                    @ r0<- vBB
4965    .if 0
4966    cmp     r1, #0                      @ is second operand zero?
4967    beq     common_errDivideByZero
4968    .endif
4969
4970    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4971                               @ optional op; may set condition codes
4972    bl      fmodf                              @ r0<- op, r0-r3 changed
4973    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4974    SET_VREG(r0, r9)               @ vAA<- r0
4975    GOTO_OPCODE(ip)                     @ jump to next instruction
4976    /* 11-14 instructions */
4977
4978
4979/* ------------------------------ */
4980    .balign 64
4981.L_OP_ADD_DOUBLE: /* 0xab */
4982/* File: arm-vfp/OP_ADD_DOUBLE.S */
4983/* File: arm-vfp/fbinopWide.S */
4984    /*
4985     * Generic 64-bit double-precision floating point binary operation.
4986     * Provide an "instr" line that specifies an instruction that performs
4987     * "d2 = d0 op d1".
4988     *
4989     * for: add-double, sub-double, mul-double, div-double
4990     */
4991    /* doubleop vAA, vBB, vCC */
4992    FETCH(r0, 1)                        @ r0<- CCBB
4993    mov     r9, rINST, lsr #8           @ r9<- AA
4994    mov     r3, r0, lsr #8              @ r3<- CC
4995    and     r2, r0, #255                @ r2<- BB
4996    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4997    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4998    fldd    d1, [r3]                    @ d1<- vCC
4999    fldd    d0, [r2]                    @ d0<- vBB
5000
5001    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5002    faddd   d2, d0, d1                              @ s2<- op
5003    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5004    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5005    fstd    d2, [r9]                    @ vAA<- d2
5006    GOTO_OPCODE(ip)                     @ jump to next instruction
5007
5008
5009/* ------------------------------ */
5010    .balign 64
5011.L_OP_SUB_DOUBLE: /* 0xac */
5012/* File: arm-vfp/OP_SUB_DOUBLE.S */
5013/* File: arm-vfp/fbinopWide.S */
5014    /*
5015     * Generic 64-bit double-precision floating point binary operation.
5016     * Provide an "instr" line that specifies an instruction that performs
5017     * "d2 = d0 op d1".
5018     *
5019     * for: add-double, sub-double, mul-double, div-double
5020     */
5021    /* doubleop vAA, vBB, vCC */
5022    FETCH(r0, 1)                        @ r0<- CCBB
5023    mov     r9, rINST, lsr #8           @ r9<- AA
5024    mov     r3, r0, lsr #8              @ r3<- CC
5025    and     r2, r0, #255                @ r2<- BB
5026    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5027    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5028    fldd    d1, [r3]                    @ d1<- vCC
5029    fldd    d0, [r2]                    @ d0<- vBB
5030
5031    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5032    fsubd   d2, d0, d1                              @ s2<- op
5033    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5034    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5035    fstd    d2, [r9]                    @ vAA<- d2
5036    GOTO_OPCODE(ip)                     @ jump to next instruction
5037
5038
5039/* ------------------------------ */
5040    .balign 64
5041.L_OP_MUL_DOUBLE: /* 0xad */
5042/* File: arm-vfp/OP_MUL_DOUBLE.S */
5043/* File: arm-vfp/fbinopWide.S */
5044    /*
5045     * Generic 64-bit double-precision floating point binary operation.
5046     * Provide an "instr" line that specifies an instruction that performs
5047     * "d2 = d0 op d1".
5048     *
5049     * for: add-double, sub-double, mul-double, div-double
5050     */
5051    /* doubleop vAA, vBB, vCC */
5052    FETCH(r0, 1)                        @ r0<- CCBB
5053    mov     r9, rINST, lsr #8           @ r9<- AA
5054    mov     r3, r0, lsr #8              @ r3<- CC
5055    and     r2, r0, #255                @ r2<- BB
5056    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5057    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5058    fldd    d1, [r3]                    @ d1<- vCC
5059    fldd    d0, [r2]                    @ d0<- vBB
5060
5061    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5062    fmuld   d2, d0, d1                              @ s2<- op
5063    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5064    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5065    fstd    d2, [r9]                    @ vAA<- d2
5066    GOTO_OPCODE(ip)                     @ jump to next instruction
5067
5068
5069/* ------------------------------ */
5070    .balign 64
5071.L_OP_DIV_DOUBLE: /* 0xae */
5072/* File: arm-vfp/OP_DIV_DOUBLE.S */
5073/* File: arm-vfp/fbinopWide.S */
5074    /*
5075     * Generic 64-bit double-precision floating point binary operation.
5076     * Provide an "instr" line that specifies an instruction that performs
5077     * "d2 = d0 op d1".
5078     *
5079     * for: add-double, sub-double, mul-double, div-double
5080     */
5081    /* doubleop vAA, vBB, vCC */
5082    FETCH(r0, 1)                        @ r0<- CCBB
5083    mov     r9, rINST, lsr #8           @ r9<- AA
5084    mov     r3, r0, lsr #8              @ r3<- CC
5085    and     r2, r0, #255                @ r2<- BB
5086    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5087    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5088    fldd    d1, [r3]                    @ d1<- vCC
5089    fldd    d0, [r2]                    @ d0<- vBB
5090
5091    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5092    fdivd   d2, d0, d1                              @ s2<- op
5093    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5094    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5095    fstd    d2, [r9]                    @ vAA<- d2
5096    GOTO_OPCODE(ip)                     @ jump to next instruction
5097
5098
5099/* ------------------------------ */
5100    .balign 64
5101.L_OP_REM_DOUBLE: /* 0xaf */
5102/* File: armv5te/OP_REM_DOUBLE.S */
5103/* EABI doesn't define a double remainder function, but libm does */
5104/* File: armv5te/binopWide.S */
5105    /*
5106     * Generic 64-bit binary operation.  Provide an "instr" line that
5107     * specifies an instruction that performs "result = r0-r1 op r2-r3".
5108     * This could be an ARM instruction or a function call.  (If the result
5109     * comes back in a register other than r0, you can override "result".)
5110     *
5111     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5112     * vCC (r1).  Useful for integer division and modulus.
5113     *
5114     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
5115     *      xor-long, add-double, sub-double, mul-double, div-double,
5116     *      rem-double
5117     *
5118     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
5119     */
5120    /* binop vAA, vBB, vCC */
5121    FETCH(r0, 1)                        @ r0<- CCBB
5122    mov     r9, rINST, lsr #8           @ r9<- AA
5123    and     r2, r0, #255                @ r2<- BB
5124    mov     r3, r0, lsr #8              @ r3<- CC
5125    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5126    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
5127    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
5128    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5129    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
5130    .if 0
5131    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5132    beq     common_errDivideByZero
5133    .endif
5134    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5135
5136                               @ optional op; may set condition codes
5137    bl      fmod                              @ result<- op, r0-r3 changed
5138    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5139    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5140    GOTO_OPCODE(ip)                     @ jump to next instruction
5141    /* 14-17 instructions */
5142
5143
5144/* ------------------------------ */
5145    .balign 64
5146.L_OP_ADD_INT_2ADDR: /* 0xb0 */
5147/* File: armv6t2/OP_ADD_INT_2ADDR.S */
5148/* File: armv6t2/binop2addr.S */
5149    /*
5150     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5151     * that specifies an instruction that performs "result = r0 op r1".
5152     * This could be an ARM instruction or a function call.  (If the result
5153     * comes back in a register other than r0, you can override "result".)
5154     *
5155     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5156     * vCC (r1).  Useful for integer division and modulus.
5157     *
5158     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5159     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5160     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5161     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5162     */
5163    /* binop/2addr vA, vB */
5164    mov     r3, rINST, lsr #12          @ r3<- B
5165    ubfx    r9, rINST, #8, #4           @ r9<- A
5166    GET_VREG(r1, r3)                    @ r1<- vB
5167    GET_VREG(r0, r9)                    @ r0<- vA
5168    .if 0
5169    cmp     r1, #0                      @ is second operand zero?
5170    beq     common_errDivideByZero
5171    .endif
5172    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5173
5174                               @ optional op; may set condition codes
5175    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
5176    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5177    SET_VREG(r0, r9)               @ vAA<- r0
5178    GOTO_OPCODE(ip)                     @ jump to next instruction
5179    /* 10-13 instructions */
5180
5181
5182/* ------------------------------ */
5183    .balign 64
5184.L_OP_SUB_INT_2ADDR: /* 0xb1 */
5185/* File: armv6t2/OP_SUB_INT_2ADDR.S */
5186/* File: armv6t2/binop2addr.S */
5187    /*
5188     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5189     * that specifies an instruction that performs "result = r0 op r1".
5190     * This could be an ARM instruction or a function call.  (If the result
5191     * comes back in a register other than r0, you can override "result".)
5192     *
5193     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5194     * vCC (r1).  Useful for integer division and modulus.
5195     *
5196     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5197     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5198     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5199     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5200     */
5201    /* binop/2addr vA, vB */
5202    mov     r3, rINST, lsr #12          @ r3<- B
5203    ubfx    r9, rINST, #8, #4           @ r9<- A
5204    GET_VREG(r1, r3)                    @ r1<- vB
5205    GET_VREG(r0, r9)                    @ r0<- vA
5206    .if 0
5207    cmp     r1, #0                      @ is second operand zero?
5208    beq     common_errDivideByZero
5209    .endif
5210    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5211
5212                               @ optional op; may set condition codes
5213    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
5214    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5215    SET_VREG(r0, r9)               @ vAA<- r0
5216    GOTO_OPCODE(ip)                     @ jump to next instruction
5217    /* 10-13 instructions */
5218
5219
5220/* ------------------------------ */
5221    .balign 64
5222.L_OP_MUL_INT_2ADDR: /* 0xb2 */
5223/* File: armv6t2/OP_MUL_INT_2ADDR.S */
5224/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
5225/* File: armv6t2/binop2addr.S */
5226    /*
5227     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5228     * that specifies an instruction that performs "result = r0 op r1".
5229     * This could be an ARM instruction or a function call.  (If the result
5230     * comes back in a register other than r0, you can override "result".)
5231     *
5232     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5233     * vCC (r1).  Useful for integer division and modulus.
5234     *
5235     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5236     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5237     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5238     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5239     */
5240    /* binop/2addr vA, vB */
5241    mov     r3, rINST, lsr #12          @ r3<- B
5242    ubfx    r9, rINST, #8, #4           @ r9<- A
5243    GET_VREG(r1, r3)                    @ r1<- vB
5244    GET_VREG(r0, r9)                    @ r0<- vA
5245    .if 0
5246    cmp     r1, #0                      @ is second operand zero?
5247    beq     common_errDivideByZero
5248    .endif
5249    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5250
5251                               @ optional op; may set condition codes
5252    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
5253    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5254    SET_VREG(r0, r9)               @ vAA<- r0
5255    GOTO_OPCODE(ip)                     @ jump to next instruction
5256    /* 10-13 instructions */
5257
5258
5259/* ------------------------------ */
5260    .balign 64
5261.L_OP_DIV_INT_2ADDR: /* 0xb3 */
5262/* File: armv6t2/OP_DIV_INT_2ADDR.S */
5263/* File: armv6t2/binop2addr.S */
5264    /*
5265     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5266     * that specifies an instruction that performs "result = r0 op r1".
5267     * This could be an ARM instruction or a function call.  (If the result
5268     * comes back in a register other than r0, you can override "result".)
5269     *
5270     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5271     * vCC (r1).  Useful for integer division and modulus.
5272     *
5273     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5274     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5275     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5276     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5277     */
5278    /* binop/2addr vA, vB */
5279    mov     r3, rINST, lsr #12          @ r3<- B
5280    ubfx    r9, rINST, #8, #4           @ r9<- A
5281    GET_VREG(r1, r3)                    @ r1<- vB
5282    GET_VREG(r0, r9)                    @ r0<- vA
5283    .if 1
5284    cmp     r1, #0                      @ is second operand zero?
5285    beq     common_errDivideByZero
5286    .endif
5287    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5288
5289                               @ optional op; may set condition codes
5290    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
5291    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5292    SET_VREG(r0, r9)               @ vAA<- r0
5293    GOTO_OPCODE(ip)                     @ jump to next instruction
5294    /* 10-13 instructions */
5295
5296
5297/* ------------------------------ */
5298    .balign 64
5299.L_OP_REM_INT_2ADDR: /* 0xb4 */
5300/* File: armv6t2/OP_REM_INT_2ADDR.S */
5301/* idivmod returns quotient in r0 and remainder in r1 */
5302/* File: armv6t2/binop2addr.S */
5303    /*
5304     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5305     * that specifies an instruction that performs "result = r0 op r1".
5306     * This could be an ARM instruction or a function call.  (If the result
5307     * comes back in a register other than r0, you can override "result".)
5308     *
5309     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5310     * vCC (r1).  Useful for integer division and modulus.
5311     *
5312     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5313     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5314     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5315     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5316     */
5317    /* binop/2addr vA, vB */
5318    mov     r3, rINST, lsr #12          @ r3<- B
5319    ubfx    r9, rINST, #8, #4           @ r9<- A
5320    GET_VREG(r1, r3)                    @ r1<- vB
5321    GET_VREG(r0, r9)                    @ r0<- vA
5322    .if 1
5323    cmp     r1, #0                      @ is second operand zero?
5324    beq     common_errDivideByZero
5325    .endif
5326    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5327
5328                               @ optional op; may set condition codes
5329    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
5330    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5331    SET_VREG(r1, r9)               @ vAA<- r1
5332    GOTO_OPCODE(ip)                     @ jump to next instruction
5333    /* 10-13 instructions */
5334
5335
5336/* ------------------------------ */
5337    .balign 64
5338.L_OP_AND_INT_2ADDR: /* 0xb5 */
5339/* File: armv6t2/OP_AND_INT_2ADDR.S */
5340/* File: armv6t2/binop2addr.S */
5341    /*
5342     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5343     * that specifies an instruction that performs "result = r0 op r1".
5344     * This could be an ARM instruction or a function call.  (If the result
5345     * comes back in a register other than r0, you can override "result".)
5346     *
5347     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5348     * vCC (r1).  Useful for integer division and modulus.
5349     *
5350     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5351     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5352     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5353     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5354     */
5355    /* binop/2addr vA, vB */
5356    mov     r3, rINST, lsr #12          @ r3<- B
5357    ubfx    r9, rINST, #8, #4           @ r9<- A
5358    GET_VREG(r1, r3)                    @ r1<- vB
5359    GET_VREG(r0, r9)                    @ r0<- vA
5360    .if 0
5361    cmp     r1, #0                      @ is second operand zero?
5362    beq     common_errDivideByZero
5363    .endif
5364    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5365
5366                               @ optional op; may set condition codes
5367    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
5368    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5369    SET_VREG(r0, r9)               @ vAA<- r0
5370    GOTO_OPCODE(ip)                     @ jump to next instruction
5371    /* 10-13 instructions */
5372
5373
5374/* ------------------------------ */
5375    .balign 64
5376.L_OP_OR_INT_2ADDR: /* 0xb6 */
5377/* File: armv6t2/OP_OR_INT_2ADDR.S */
5378/* File: armv6t2/binop2addr.S */
5379    /*
5380     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5381     * that specifies an instruction that performs "result = r0 op r1".
5382     * This could be an ARM instruction or a function call.  (If the result
5383     * comes back in a register other than r0, you can override "result".)
5384     *
5385     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5386     * vCC (r1).  Useful for integer division and modulus.
5387     *
5388     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5389     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5390     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5391     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5392     */
5393    /* binop/2addr vA, vB */
5394    mov     r3, rINST, lsr #12          @ r3<- B
5395    ubfx    r9, rINST, #8, #4           @ r9<- A
5396    GET_VREG(r1, r3)                    @ r1<- vB
5397    GET_VREG(r0, r9)                    @ r0<- vA
5398    .if 0
5399    cmp     r1, #0                      @ is second operand zero?
5400    beq     common_errDivideByZero
5401    .endif
5402    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5403
5404                               @ optional op; may set condition codes
5405    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
5406    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5407    SET_VREG(r0, r9)               @ vAA<- r0
5408    GOTO_OPCODE(ip)                     @ jump to next instruction
5409    /* 10-13 instructions */
5410
5411
5412/* ------------------------------ */
5413    .balign 64
5414.L_OP_XOR_INT_2ADDR: /* 0xb7 */
5415/* File: armv6t2/OP_XOR_INT_2ADDR.S */
5416/* File: armv6t2/binop2addr.S */
5417    /*
5418     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5419     * that specifies an instruction that performs "result = r0 op r1".
5420     * This could be an ARM instruction or a function call.  (If the result
5421     * comes back in a register other than r0, you can override "result".)
5422     *
5423     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5424     * vCC (r1).  Useful for integer division and modulus.
5425     *
5426     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5427     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5428     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5429     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5430     */
5431    /* binop/2addr vA, vB */
5432    mov     r3, rINST, lsr #12          @ r3<- B
5433    ubfx    r9, rINST, #8, #4           @ r9<- A
5434    GET_VREG(r1, r3)                    @ r1<- vB
5435    GET_VREG(r0, r9)                    @ r0<- vA
5436    .if 0
5437    cmp     r1, #0                      @ is second operand zero?
5438    beq     common_errDivideByZero
5439    .endif
5440    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5441
5442                               @ optional op; may set condition codes
5443    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
5444    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5445    SET_VREG(r0, r9)               @ vAA<- r0
5446    GOTO_OPCODE(ip)                     @ jump to next instruction
5447    /* 10-13 instructions */
5448
5449
5450/* ------------------------------ */
5451    .balign 64
5452.L_OP_SHL_INT_2ADDR: /* 0xb8 */
5453/* File: armv6t2/OP_SHL_INT_2ADDR.S */
5454/* File: armv6t2/binop2addr.S */
5455    /*
5456     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5457     * that specifies an instruction that performs "result = r0 op r1".
5458     * This could be an ARM instruction or a function call.  (If the result
5459     * comes back in a register other than r0, you can override "result".)
5460     *
5461     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5462     * vCC (r1).  Useful for integer division and modulus.
5463     *
5464     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5465     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5466     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5467     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5468     */
5469    /* binop/2addr vA, vB */
5470    mov     r3, rINST, lsr #12          @ r3<- B
5471    ubfx    r9, rINST, #8, #4           @ r9<- A
5472    GET_VREG(r1, r3)                    @ r1<- vB
5473    GET_VREG(r0, r9)                    @ r0<- vA
5474    .if 0
5475    cmp     r1, #0                      @ is second operand zero?
5476    beq     common_errDivideByZero
5477    .endif
5478    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5479
5480    and     r1, r1, #31                           @ optional op; may set condition codes
5481    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
5482    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5483    SET_VREG(r0, r9)               @ vAA<- r0
5484    GOTO_OPCODE(ip)                     @ jump to next instruction
5485    /* 10-13 instructions */
5486
5487
5488/* ------------------------------ */
5489    .balign 64
5490.L_OP_SHR_INT_2ADDR: /* 0xb9 */
5491/* File: armv6t2/OP_SHR_INT_2ADDR.S */
5492/* File: armv6t2/binop2addr.S */
5493    /*
5494     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5495     * that specifies an instruction that performs "result = r0 op r1".
5496     * This could be an ARM instruction or a function call.  (If the result
5497     * comes back in a register other than r0, you can override "result".)
5498     *
5499     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5500     * vCC (r1).  Useful for integer division and modulus.
5501     *
5502     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5503     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5504     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5505     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5506     */
5507    /* binop/2addr vA, vB */
5508    mov     r3, rINST, lsr #12          @ r3<- B
5509    ubfx    r9, rINST, #8, #4           @ r9<- A
5510    GET_VREG(r1, r3)                    @ r1<- vB
5511    GET_VREG(r0, r9)                    @ r0<- vA
5512    .if 0
5513    cmp     r1, #0                      @ is second operand zero?
5514    beq     common_errDivideByZero
5515    .endif
5516    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5517
5518    and     r1, r1, #31                           @ optional op; may set condition codes
5519    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
5520    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5521    SET_VREG(r0, r9)               @ vAA<- r0
5522    GOTO_OPCODE(ip)                     @ jump to next instruction
5523    /* 10-13 instructions */
5524
5525
5526/* ------------------------------ */
5527    .balign 64
5528.L_OP_USHR_INT_2ADDR: /* 0xba */
5529/* File: armv6t2/OP_USHR_INT_2ADDR.S */
5530/* File: armv6t2/binop2addr.S */
5531    /*
5532     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5533     * that specifies an instruction that performs "result = r0 op r1".
5534     * This could be an ARM instruction or a function call.  (If the result
5535     * comes back in a register other than r0, you can override "result".)
5536     *
5537     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5538     * vCC (r1).  Useful for integer division and modulus.
5539     *
5540     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5541     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5542     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5543     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5544     */
5545    /* binop/2addr vA, vB */
5546    mov     r3, rINST, lsr #12          @ r3<- B
5547    ubfx    r9, rINST, #8, #4           @ r9<- A
5548    GET_VREG(r1, r3)                    @ r1<- vB
5549    GET_VREG(r0, r9)                    @ r0<- vA
5550    .if 0
5551    cmp     r1, #0                      @ is second operand zero?
5552    beq     common_errDivideByZero
5553    .endif
5554    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5555
5556    and     r1, r1, #31                           @ optional op; may set condition codes
5557    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
5558    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5559    SET_VREG(r0, r9)               @ vAA<- r0
5560    GOTO_OPCODE(ip)                     @ jump to next instruction
5561    /* 10-13 instructions */
5562
5563
5564/* ------------------------------ */
5565    .balign 64
5566.L_OP_ADD_LONG_2ADDR: /* 0xbb */
5567/* File: armv6t2/OP_ADD_LONG_2ADDR.S */
5568/* File: armv6t2/binopWide2addr.S */
5569    /*
5570     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5571     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5572     * This could be an ARM instruction or a function call.  (If the result
5573     * comes back in a register other than r0, you can override "result".)
5574     *
5575     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5576     * vCC (r1).  Useful for integer division and modulus.
5577     *
5578     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5579     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5580     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5581     *      rem-double/2addr
5582     */
5583    /* binop/2addr vA, vB */
5584    mov     r1, rINST, lsr #12          @ r1<- B
5585    ubfx    r9, rINST, #8, #4           @ r9<- A
5586    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5587    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5588    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5589    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5590    .if 0
5591    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5592    beq     common_errDivideByZero
5593    .endif
5594    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5595
5596    adds    r0, r0, r2                           @ optional op; may set condition codes
5597    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
5598    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5599    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5600    GOTO_OPCODE(ip)                     @ jump to next instruction
5601    /* 12-15 instructions */
5602
5603
5604/* ------------------------------ */
5605    .balign 64
5606.L_OP_SUB_LONG_2ADDR: /* 0xbc */
5607/* File: armv6t2/OP_SUB_LONG_2ADDR.S */
5608/* File: armv6t2/binopWide2addr.S */
5609    /*
5610     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5611     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5612     * This could be an ARM instruction or a function call.  (If the result
5613     * comes back in a register other than r0, you can override "result".)
5614     *
5615     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5616     * vCC (r1).  Useful for integer division and modulus.
5617     *
5618     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5619     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5620     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5621     *      rem-double/2addr
5622     */
5623    /* binop/2addr vA, vB */
5624    mov     r1, rINST, lsr #12          @ r1<- B
5625    ubfx    r9, rINST, #8, #4           @ r9<- A
5626    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5627    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5628    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5629    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5630    .if 0
5631    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5632    beq     common_errDivideByZero
5633    .endif
5634    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5635
5636    subs    r0, r0, r2                           @ optional op; may set condition codes
5637    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
5638    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5639    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5640    GOTO_OPCODE(ip)                     @ jump to next instruction
5641    /* 12-15 instructions */
5642
5643
5644/* ------------------------------ */
5645    .balign 64
5646.L_OP_MUL_LONG_2ADDR: /* 0xbd */
5647/* File: armv6t2/OP_MUL_LONG_2ADDR.S */
5648    /*
5649     * Signed 64-bit integer multiply, "/2addr" version.
5650     *
5651     * See OP_MUL_LONG for an explanation.
5652     *
5653     * We get a little tight on registers, so to avoid looking up &fp[A]
5654     * again we stuff it into rINST.
5655     */
5656    /* mul-long/2addr vA, vB */
5657    mov     r1, rINST, lsr #12          @ r1<- B
5658    ubfx    r9, rINST, #8, #4           @ r9<- A
5659    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5660    add     rINST, rFP, r9, lsl #2      @ rINST<- &fp[A]
5661    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5662    ldmia   rINST, {r0-r1}              @ r0/r1<- vAA/vAA+1
5663    mul     ip, r2, r1                  @  ip<- ZxW
5664    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
5665    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
5666    mov     r0, rINST                   @ r0<- &fp[A] (free up rINST)
5667    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5668    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
5669    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5670    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
5671    GOTO_OPCODE(ip)                     @ jump to next instruction
5672
5673/* ------------------------------ */
5674    .balign 64
5675.L_OP_DIV_LONG_2ADDR: /* 0xbe */
5676/* File: armv6t2/OP_DIV_LONG_2ADDR.S */
5677/* File: armv6t2/binopWide2addr.S */
5678    /*
5679     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5680     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5681     * This could be an ARM instruction or a function call.  (If the result
5682     * comes back in a register other than r0, you can override "result".)
5683     *
5684     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5685     * vCC (r1).  Useful for integer division and modulus.
5686     *
5687     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5688     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5689     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5690     *      rem-double/2addr
5691     */
5692    /* binop/2addr vA, vB */
5693    mov     r1, rINST, lsr #12          @ r1<- B
5694    ubfx    r9, rINST, #8, #4           @ r9<- A
5695    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5696    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5697    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5698    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5699    .if 1
5700    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5701    beq     common_errDivideByZero
5702    .endif
5703    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5704
5705                               @ optional op; may set condition codes
5706    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
5707    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5708    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5709    GOTO_OPCODE(ip)                     @ jump to next instruction
5710    /* 12-15 instructions */
5711
5712
5713/* ------------------------------ */
5714    .balign 64
5715.L_OP_REM_LONG_2ADDR: /* 0xbf */
5716/* File: armv6t2/OP_REM_LONG_2ADDR.S */
5717/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
5718/* File: armv6t2/binopWide2addr.S */
5719    /*
5720     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5721     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5722     * This could be an ARM instruction or a function call.  (If the result
5723     * comes back in a register other than r0, you can override "result".)
5724     *
5725     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5726     * vCC (r1).  Useful for integer division and modulus.
5727     *
5728     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5729     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5730     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5731     *      rem-double/2addr
5732     */
5733    /* binop/2addr vA, vB */
5734    mov     r1, rINST, lsr #12          @ r1<- B
5735    ubfx    r9, rINST, #8, #4           @ r9<- A
5736    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5737    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5738    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5739    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5740    .if 1
5741    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5742    beq     common_errDivideByZero
5743    .endif
5744    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5745
5746                               @ optional op; may set condition codes
5747    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
5748    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5749    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
5750    GOTO_OPCODE(ip)                     @ jump to next instruction
5751    /* 12-15 instructions */
5752
5753
5754/* ------------------------------ */
5755    .balign 64
5756.L_OP_AND_LONG_2ADDR: /* 0xc0 */
5757/* File: armv6t2/OP_AND_LONG_2ADDR.S */
5758/* File: armv6t2/binopWide2addr.S */
5759    /*
5760     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5761     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5762     * This could be an ARM instruction or a function call.  (If the result
5763     * comes back in a register other than r0, you can override "result".)
5764     *
5765     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5766     * vCC (r1).  Useful for integer division and modulus.
5767     *
5768     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5769     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5770     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5771     *      rem-double/2addr
5772     */
5773    /* binop/2addr vA, vB */
5774    mov     r1, rINST, lsr #12          @ r1<- B
5775    ubfx    r9, rINST, #8, #4           @ r9<- A
5776    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5777    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5778    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5779    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5780    .if 0
5781    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5782    beq     common_errDivideByZero
5783    .endif
5784    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5785
5786    and     r0, r0, r2                           @ optional op; may set condition codes
5787    and     r1, r1, r3                              @ result<- op, r0-r3 changed
5788    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5789    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5790    GOTO_OPCODE(ip)                     @ jump to next instruction
5791    /* 12-15 instructions */
5792
5793
5794/* ------------------------------ */
5795    .balign 64
5796.L_OP_OR_LONG_2ADDR: /* 0xc1 */
5797/* File: armv6t2/OP_OR_LONG_2ADDR.S */
5798/* File: armv6t2/binopWide2addr.S */
5799    /*
5800     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5801     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5802     * This could be an ARM instruction or a function call.  (If the result
5803     * comes back in a register other than r0, you can override "result".)
5804     *
5805     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5806     * vCC (r1).  Useful for integer division and modulus.
5807     *
5808     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5809     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5810     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5811     *      rem-double/2addr
5812     */
5813    /* binop/2addr vA, vB */
5814    mov     r1, rINST, lsr #12          @ r1<- B
5815    ubfx    r9, rINST, #8, #4           @ r9<- A
5816    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5817    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5818    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5819    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5820    .if 0
5821    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5822    beq     common_errDivideByZero
5823    .endif
5824    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5825
5826    orr     r0, r0, r2                           @ optional op; may set condition codes
5827    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
5828    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5829    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5830    GOTO_OPCODE(ip)                     @ jump to next instruction
5831    /* 12-15 instructions */
5832
5833
5834/* ------------------------------ */
5835    .balign 64
5836.L_OP_XOR_LONG_2ADDR: /* 0xc2 */
5837/* File: armv6t2/OP_XOR_LONG_2ADDR.S */
5838/* File: armv6t2/binopWide2addr.S */
5839    /*
5840     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5841     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5842     * This could be an ARM instruction or a function call.  (If the result
5843     * comes back in a register other than r0, you can override "result".)
5844     *
5845     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5846     * vCC (r1).  Useful for integer division and modulus.
5847     *
5848     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5849     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5850     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5851     *      rem-double/2addr
5852     */
5853    /* binop/2addr vA, vB */
5854    mov     r1, rINST, lsr #12          @ r1<- B
5855    ubfx    r9, rINST, #8, #4           @ r9<- A
5856    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5857    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5858    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5859    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5860    .if 0
5861    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5862    beq     common_errDivideByZero
5863    .endif
5864    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5865
5866    eor     r0, r0, r2                           @ optional op; may set condition codes
5867    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
5868    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5869    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5870    GOTO_OPCODE(ip)                     @ jump to next instruction
5871    /* 12-15 instructions */
5872
5873
5874/* ------------------------------ */
5875    .balign 64
5876.L_OP_SHL_LONG_2ADDR: /* 0xc3 */
5877/* File: armv6t2/OP_SHL_LONG_2ADDR.S */
5878    /*
5879     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5880     * 32-bit shift distance.
5881     */
5882    /* shl-long/2addr vA, vB */
5883    mov     r3, rINST, lsr #12          @ r3<- B
5884    ubfx    r9, rINST, #8, #4           @ r9<- A
5885    GET_VREG(r2, r3)                    @ r2<- vB
5886    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5887    and     r2, r2, #63                 @ r2<- r2 & 0x3f
5888    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5889
5890    mov     r1, r1, asl r2              @  r1<- r1 << r2
5891    rsb     r3, r2, #32                 @  r3<- 32 - r2
5892    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
5893    subs    ip, r2, #32                 @  ip<- r2 - 32
5894    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5895    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
5896    mov     r0, r0, asl r2              @  r0<- r0 << r2
5897    b       .LOP_SHL_LONG_2ADDR_finish
5898
5899/* ------------------------------ */
5900    .balign 64
5901.L_OP_SHR_LONG_2ADDR: /* 0xc4 */
5902/* File: armv6t2/OP_SHR_LONG_2ADDR.S */
5903    /*
5904     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5905     * 32-bit shift distance.
5906     */
5907    /* shr-long/2addr vA, vB */
5908    mov     r3, rINST, lsr #12          @ r3<- B
5909    ubfx    r9, rINST, #8, #4           @ r9<- A
5910    GET_VREG(r2, r3)                    @ r2<- vB
5911    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5912    and     r2, r2, #63                 @ r2<- r2 & 0x3f
5913    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5914
5915    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
5916    rsb     r3, r2, #32                 @  r3<- 32 - r2
5917    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
5918    subs    ip, r2, #32                 @  ip<- r2 - 32
5919    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5920    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
5921    mov     r1, r1, asr r2              @  r1<- r1 >> r2
5922    b       .LOP_SHR_LONG_2ADDR_finish
5923
5924/* ------------------------------ */
5925    .balign 64
5926.L_OP_USHR_LONG_2ADDR: /* 0xc5 */
5927/* File: armv6t2/OP_USHR_LONG_2ADDR.S */
5928    /*
5929     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5930     * 32-bit shift distance.
5931     */
5932    /* ushr-long/2addr vA, vB */
5933    mov     r3, rINST, lsr #12          @ r3<- B
5934    ubfx    r9, rINST, #8, #4           @ r9<- A
5935    GET_VREG(r2, r3)                    @ r2<- vB
5936    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5937    and     r2, r2, #63                 @ r2<- r2 & 0x3f
5938    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5939
5940    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
5941    rsb     r3, r2, #32                 @  r3<- 32 - r2
5942    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
5943    subs    ip, r2, #32                 @  ip<- r2 - 32
5944    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5945    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
5946    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
5947    b       .LOP_USHR_LONG_2ADDR_finish
5948
5949/* ------------------------------ */
5950    .balign 64
5951.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
5952/* File: arm-vfp/OP_ADD_FLOAT_2ADDR.S */
5953/* File: arm-vfp/fbinop2addr.S */
5954    /*
5955     * Generic 32-bit floating point "/2addr" binary operation.  Provide
5956     * an "instr" line that specifies an instruction that performs
5957     * "s2 = s0 op s1".
5958     *
5959     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
5960     */
5961    /* binop/2addr vA, vB */
5962    mov     r3, rINST, lsr #12          @ r3<- B
5963    mov     r9, rINST, lsr #8           @ r9<- A+
5964    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
5965    and     r9, r9, #15                 @ r9<- A
5966    flds    s1, [r3]                    @ s1<- vB
5967    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
5968    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5969    flds    s0, [r9]                    @ s0<- vA
5970
5971    fadds   s2, s0, s1                              @ s2<- op
5972    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5973    fsts    s2, [r9]                    @ vAA<- s2
5974    GOTO_OPCODE(ip)                     @ jump to next instruction
5975
5976
5977/* ------------------------------ */
5978    .balign 64
5979.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
5980/* File: arm-vfp/OP_SUB_FLOAT_2ADDR.S */
5981/* File: arm-vfp/fbinop2addr.S */
5982    /*
5983     * Generic 32-bit floating point "/2addr" binary operation.  Provide
5984     * an "instr" line that specifies an instruction that performs
5985     * "s2 = s0 op s1".
5986     *
5987     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
5988     */
5989    /* binop/2addr vA, vB */
5990    mov     r3, rINST, lsr #12          @ r3<- B
5991    mov     r9, rINST, lsr #8           @ r9<- A+
5992    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
5993    and     r9, r9, #15                 @ r9<- A
5994    flds    s1, [r3]                    @ s1<- vB
5995    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
5996    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5997    flds    s0, [r9]                    @ s0<- vA
5998
5999    fsubs   s2, s0, s1                              @ s2<- op
6000    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6001    fsts    s2, [r9]                    @ vAA<- s2
6002    GOTO_OPCODE(ip)                     @ jump to next instruction
6003
6004
6005/* ------------------------------ */
6006    .balign 64
6007.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
6008/* File: arm-vfp/OP_MUL_FLOAT_2ADDR.S */
6009/* File: arm-vfp/fbinop2addr.S */
6010    /*
6011     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6012     * an "instr" line that specifies an instruction that performs
6013     * "s2 = s0 op s1".
6014     *
6015     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6016     */
6017    /* binop/2addr vA, vB */
6018    mov     r3, rINST, lsr #12          @ r3<- B
6019    mov     r9, rINST, lsr #8           @ r9<- A+
6020    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6021    and     r9, r9, #15                 @ r9<- A
6022    flds    s1, [r3]                    @ s1<- vB
6023    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6024    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6025    flds    s0, [r9]                    @ s0<- vA
6026
6027    fmuls   s2, s0, s1                              @ s2<- op
6028    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6029    fsts    s2, [r9]                    @ vAA<- s2
6030    GOTO_OPCODE(ip)                     @ jump to next instruction
6031
6032
6033/* ------------------------------ */
6034    .balign 64
6035.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
6036/* File: arm-vfp/OP_DIV_FLOAT_2ADDR.S */
6037/* File: arm-vfp/fbinop2addr.S */
6038    /*
6039     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6040     * an "instr" line that specifies an instruction that performs
6041     * "s2 = s0 op s1".
6042     *
6043     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6044     */
6045    /* binop/2addr vA, vB */
6046    mov     r3, rINST, lsr #12          @ r3<- B
6047    mov     r9, rINST, lsr #8           @ r9<- A+
6048    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6049    and     r9, r9, #15                 @ r9<- A
6050    flds    s1, [r3]                    @ s1<- vB
6051    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6052    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6053    flds    s0, [r9]                    @ s0<- vA
6054
6055    fdivs   s2, s0, s1                              @ s2<- op
6056    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6057    fsts    s2, [r9]                    @ vAA<- s2
6058    GOTO_OPCODE(ip)                     @ jump to next instruction
6059
6060
6061/* ------------------------------ */
6062    .balign 64
6063.L_OP_REM_FLOAT_2ADDR: /* 0xca */
6064/* File: armv6t2/OP_REM_FLOAT_2ADDR.S */
6065/* EABI doesn't define a float remainder function, but libm does */
6066/* File: armv6t2/binop2addr.S */
6067    /*
6068     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6069     * that specifies an instruction that performs "result = r0 op r1".
6070     * This could be an ARM instruction or a function call.  (If the result
6071     * comes back in a register other than r0, you can override "result".)
6072     *
6073     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6074     * vCC (r1).  Useful for integer division and modulus.
6075     *
6076     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6077     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6078     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6079     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6080     */
6081    /* binop/2addr vA, vB */
6082    mov     r3, rINST, lsr #12          @ r3<- B
6083    ubfx    r9, rINST, #8, #4           @ r9<- A
6084    GET_VREG(r1, r3)                    @ r1<- vB
6085    GET_VREG(r0, r9)                    @ r0<- vA
6086    .if 0
6087    cmp     r1, #0                      @ is second operand zero?
6088    beq     common_errDivideByZero
6089    .endif
6090    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6091
6092                               @ optional op; may set condition codes
6093    bl      fmodf                              @ r0<- op, r0-r3 changed
6094    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6095    SET_VREG(r0, r9)               @ vAA<- r0
6096    GOTO_OPCODE(ip)                     @ jump to next instruction
6097    /* 10-13 instructions */
6098
6099
6100/* ------------------------------ */
6101    .balign 64
6102.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
6103/* File: arm-vfp/OP_ADD_DOUBLE_2ADDR.S */
6104/* File: arm-vfp/fbinopWide2addr.S */
6105    /*
6106     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6107     * an "instr" line that specifies an instruction that performs
6108     * "d2 = d0 op d1".
6109     *
6110     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6111     *      div-double/2addr
6112     */
6113    /* binop/2addr vA, vB */
6114    mov     r3, rINST, lsr #12          @ r3<- B
6115    mov     r9, rINST, lsr #8           @ r9<- A+
6116    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6117    and     r9, r9, #15                 @ r9<- A
6118    fldd    d1, [r3]                    @ d1<- vB
6119    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6120    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6121    fldd    d0, [r9]                    @ d0<- vA
6122
6123    faddd   d2, d0, d1                              @ d2<- op
6124    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6125    fstd    d2, [r9]                    @ vAA<- d2
6126    GOTO_OPCODE(ip)                     @ jump to next instruction
6127
6128
6129/* ------------------------------ */
6130    .balign 64
6131.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
6132/* File: arm-vfp/OP_SUB_DOUBLE_2ADDR.S */
6133/* File: arm-vfp/fbinopWide2addr.S */
6134    /*
6135     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6136     * an "instr" line that specifies an instruction that performs
6137     * "d2 = d0 op d1".
6138     *
6139     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6140     *      div-double/2addr
6141     */
6142    /* binop/2addr vA, vB */
6143    mov     r3, rINST, lsr #12          @ r3<- B
6144    mov     r9, rINST, lsr #8           @ r9<- A+
6145    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6146    and     r9, r9, #15                 @ r9<- A
6147    fldd    d1, [r3]                    @ d1<- vB
6148    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6149    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6150    fldd    d0, [r9]                    @ d0<- vA
6151
6152    fsubd   d2, d0, d1                              @ d2<- op
6153    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6154    fstd    d2, [r9]                    @ vAA<- d2
6155    GOTO_OPCODE(ip)                     @ jump to next instruction
6156
6157
6158/* ------------------------------ */
6159    .balign 64
6160.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
6161/* File: arm-vfp/OP_MUL_DOUBLE_2ADDR.S */
6162/* File: arm-vfp/fbinopWide2addr.S */
6163    /*
6164     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6165     * an "instr" line that specifies an instruction that performs
6166     * "d2 = d0 op d1".
6167     *
6168     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6169     *      div-double/2addr
6170     */
6171    /* binop/2addr vA, vB */
6172    mov     r3, rINST, lsr #12          @ r3<- B
6173    mov     r9, rINST, lsr #8           @ r9<- A+
6174    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6175    and     r9, r9, #15                 @ r9<- A
6176    fldd    d1, [r3]                    @ d1<- vB
6177    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6178    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6179    fldd    d0, [r9]                    @ d0<- vA
6180
6181    fmuld   d2, d0, d1                              @ d2<- op
6182    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6183    fstd    d2, [r9]                    @ vAA<- d2
6184    GOTO_OPCODE(ip)                     @ jump to next instruction
6185
6186
6187/* ------------------------------ */
6188    .balign 64
6189.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */
6190/* File: arm-vfp/OP_DIV_DOUBLE_2ADDR.S */
6191/* File: arm-vfp/fbinopWide2addr.S */
6192    /*
6193     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6194     * an "instr" line that specifies an instruction that performs
6195     * "d2 = d0 op d1".
6196     *
6197     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6198     *      div-double/2addr
6199     */
6200    /* binop/2addr vA, vB */
6201    mov     r3, rINST, lsr #12          @ r3<- B
6202    mov     r9, rINST, lsr #8           @ r9<- A+
6203    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6204    and     r9, r9, #15                 @ r9<- A
6205    fldd    d1, [r3]                    @ d1<- vB
6206    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6207    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6208    fldd    d0, [r9]                    @ d0<- vA
6209
6210    fdivd   d2, d0, d1                              @ d2<- op
6211    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6212    fstd    d2, [r9]                    @ vAA<- d2
6213    GOTO_OPCODE(ip)                     @ jump to next instruction
6214
6215
6216/* ------------------------------ */
6217    .balign 64
6218.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */
6219/* File: armv6t2/OP_REM_DOUBLE_2ADDR.S */
6220/* EABI doesn't define a double remainder function, but libm does */
6221/* File: armv6t2/binopWide2addr.S */
6222    /*
6223     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6224     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6225     * This could be an ARM instruction or a function call.  (If the result
6226     * comes back in a register other than r0, you can override "result".)
6227     *
6228     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6229     * vCC (r1).  Useful for integer division and modulus.
6230     *
6231     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6232     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6233     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6234     *      rem-double/2addr
6235     */
6236    /* binop/2addr vA, vB */
6237    mov     r1, rINST, lsr #12          @ r1<- B
6238    ubfx    r9, rINST, #8, #4           @ r9<- A
6239    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6240    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6241    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6242    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6243    .if 0
6244    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6245    beq     common_errDivideByZero
6246    .endif
6247    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6248
6249                               @ optional op; may set condition codes
6250    bl      fmod                              @ result<- op, r0-r3 changed
6251    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6252    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6253    GOTO_OPCODE(ip)                     @ jump to next instruction
6254    /* 12-15 instructions */
6255
6256
6257/* ------------------------------ */
6258    .balign 64
6259.L_OP_ADD_INT_LIT16: /* 0xd0 */
6260/* File: armv6t2/OP_ADD_INT_LIT16.S */
6261/* File: armv6t2/binopLit16.S */
6262    /*
6263     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6264     * that specifies an instruction that performs "result = r0 op r1".
6265     * This could be an ARM instruction or a function call.  (If the result
6266     * comes back in a register other than r0, you can override "result".)
6267     *
6268     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6269     * vCC (r1).  Useful for integer division and modulus.
6270     *
6271     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6272     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6273     */
6274    /* binop/lit16 vA, vB, #+CCCC */
6275    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6276    mov     r2, rINST, lsr #12          @ r2<- B
6277    ubfx    r9, rINST, #8, #4           @ r9<- A
6278    GET_VREG(r0, r2)                    @ r0<- vB
6279    .if 0
6280    cmp     r1, #0                      @ is second operand zero?
6281    beq     common_errDivideByZero
6282    .endif
6283    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6284
6285    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
6286    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6287    SET_VREG(r0, r9)               @ vAA<- r0
6288    GOTO_OPCODE(ip)                     @ jump to next instruction
6289    /* 10-13 instructions */
6290
6291
6292/* ------------------------------ */
6293    .balign 64
6294.L_OP_RSUB_INT: /* 0xd1 */
6295/* File: armv6t2/OP_RSUB_INT.S */
6296/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
6297/* File: armv6t2/binopLit16.S */
6298    /*
6299     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6300     * that specifies an instruction that performs "result = r0 op r1".
6301     * This could be an ARM instruction or a function call.  (If the result
6302     * comes back in a register other than r0, you can override "result".)
6303     *
6304     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6305     * vCC (r1).  Useful for integer division and modulus.
6306     *
6307     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6308     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6309     */
6310    /* binop/lit16 vA, vB, #+CCCC */
6311    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6312    mov     r2, rINST, lsr #12          @ r2<- B
6313    ubfx    r9, rINST, #8, #4           @ r9<- A
6314    GET_VREG(r0, r2)                    @ r0<- vB
6315    .if 0
6316    cmp     r1, #0                      @ is second operand zero?
6317    beq     common_errDivideByZero
6318    .endif
6319    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6320
6321    rsb     r0, r0, r1                              @ r0<- op, r0-r3 changed
6322    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6323    SET_VREG(r0, r9)               @ vAA<- r0
6324    GOTO_OPCODE(ip)                     @ jump to next instruction
6325    /* 10-13 instructions */
6326
6327
6328/* ------------------------------ */
6329    .balign 64
6330.L_OP_MUL_INT_LIT16: /* 0xd2 */
6331/* File: armv6t2/OP_MUL_INT_LIT16.S */
6332/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
6333/* File: armv6t2/binopLit16.S */
6334    /*
6335     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6336     * that specifies an instruction that performs "result = r0 op r1".
6337     * This could be an ARM instruction or a function call.  (If the result
6338     * comes back in a register other than r0, you can override "result".)
6339     *
6340     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6341     * vCC (r1).  Useful for integer division and modulus.
6342     *
6343     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6344     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6345     */
6346    /* binop/lit16 vA, vB, #+CCCC */
6347    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6348    mov     r2, rINST, lsr #12          @ r2<- B
6349    ubfx    r9, rINST, #8, #4           @ r9<- A
6350    GET_VREG(r0, r2)                    @ r0<- vB
6351    .if 0
6352    cmp     r1, #0                      @ is second operand zero?
6353    beq     common_errDivideByZero
6354    .endif
6355    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6356
6357    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
6358    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6359    SET_VREG(r0, r9)               @ vAA<- r0
6360    GOTO_OPCODE(ip)                     @ jump to next instruction
6361    /* 10-13 instructions */
6362
6363
6364/* ------------------------------ */
6365    .balign 64
6366.L_OP_DIV_INT_LIT16: /* 0xd3 */
6367/* File: armv6t2/OP_DIV_INT_LIT16.S */
6368/* File: armv6t2/binopLit16.S */
6369    /*
6370     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6371     * that specifies an instruction that performs "result = r0 op r1".
6372     * This could be an ARM instruction or a function call.  (If the result
6373     * comes back in a register other than r0, you can override "result".)
6374     *
6375     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6376     * vCC (r1).  Useful for integer division and modulus.
6377     *
6378     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6379     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6380     */
6381    /* binop/lit16 vA, vB, #+CCCC */
6382    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6383    mov     r2, rINST, lsr #12          @ r2<- B
6384    ubfx    r9, rINST, #8, #4           @ r9<- A
6385    GET_VREG(r0, r2)                    @ r0<- vB
6386    .if 1
6387    cmp     r1, #0                      @ is second operand zero?
6388    beq     common_errDivideByZero
6389    .endif
6390    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6391
6392    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
6393    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6394    SET_VREG(r0, r9)               @ vAA<- r0
6395    GOTO_OPCODE(ip)                     @ jump to next instruction
6396    /* 10-13 instructions */
6397
6398
6399/* ------------------------------ */
6400    .balign 64
6401.L_OP_REM_INT_LIT16: /* 0xd4 */
6402/* File: armv6t2/OP_REM_INT_LIT16.S */
6403/* idivmod returns quotient in r0 and remainder in r1 */
6404/* File: armv6t2/binopLit16.S */
6405    /*
6406     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6407     * that specifies an instruction that performs "result = r0 op r1".
6408     * This could be an ARM instruction or a function call.  (If the result
6409     * comes back in a register other than r0, you can override "result".)
6410     *
6411     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6412     * vCC (r1).  Useful for integer division and modulus.
6413     *
6414     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6415     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6416     */
6417    /* binop/lit16 vA, vB, #+CCCC */
6418    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6419    mov     r2, rINST, lsr #12          @ r2<- B
6420    ubfx    r9, rINST, #8, #4           @ r9<- A
6421    GET_VREG(r0, r2)                    @ r0<- vB
6422    .if 1
6423    cmp     r1, #0                      @ is second operand zero?
6424    beq     common_errDivideByZero
6425    .endif
6426    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6427
6428    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
6429    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6430    SET_VREG(r1, r9)               @ vAA<- r1
6431    GOTO_OPCODE(ip)                     @ jump to next instruction
6432    /* 10-13 instructions */
6433
6434
6435/* ------------------------------ */
6436    .balign 64
6437.L_OP_AND_INT_LIT16: /* 0xd5 */
6438/* File: armv6t2/OP_AND_INT_LIT16.S */
6439/* File: armv6t2/binopLit16.S */
6440    /*
6441     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6442     * that specifies an instruction that performs "result = r0 op r1".
6443     * This could be an ARM instruction or a function call.  (If the result
6444     * comes back in a register other than r0, you can override "result".)
6445     *
6446     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6447     * vCC (r1).  Useful for integer division and modulus.
6448     *
6449     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6450     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6451     */
6452    /* binop/lit16 vA, vB, #+CCCC */
6453    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6454    mov     r2, rINST, lsr #12          @ r2<- B
6455    ubfx    r9, rINST, #8, #4           @ r9<- A
6456    GET_VREG(r0, r2)                    @ r0<- vB
6457    .if 0
6458    cmp     r1, #0                      @ is second operand zero?
6459    beq     common_errDivideByZero
6460    .endif
6461    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6462
6463    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
6464    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6465    SET_VREG(r0, r9)               @ vAA<- r0
6466    GOTO_OPCODE(ip)                     @ jump to next instruction
6467    /* 10-13 instructions */
6468
6469
6470/* ------------------------------ */
6471    .balign 64
6472.L_OP_OR_INT_LIT16: /* 0xd6 */
6473/* File: armv6t2/OP_OR_INT_LIT16.S */
6474/* File: armv6t2/binopLit16.S */
6475    /*
6476     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6477     * that specifies an instruction that performs "result = r0 op r1".
6478     * This could be an ARM instruction or a function call.  (If the result
6479     * comes back in a register other than r0, you can override "result".)
6480     *
6481     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6482     * vCC (r1).  Useful for integer division and modulus.
6483     *
6484     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6485     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6486     */
6487    /* binop/lit16 vA, vB, #+CCCC */
6488    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6489    mov     r2, rINST, lsr #12          @ r2<- B
6490    ubfx    r9, rINST, #8, #4           @ r9<- A
6491    GET_VREG(r0, r2)                    @ r0<- vB
6492    .if 0
6493    cmp     r1, #0                      @ is second operand zero?
6494    beq     common_errDivideByZero
6495    .endif
6496    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6497
6498    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
6499    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6500    SET_VREG(r0, r9)               @ vAA<- r0
6501    GOTO_OPCODE(ip)                     @ jump to next instruction
6502    /* 10-13 instructions */
6503
6504
6505/* ------------------------------ */
6506    .balign 64
6507.L_OP_XOR_INT_LIT16: /* 0xd7 */
6508/* File: armv6t2/OP_XOR_INT_LIT16.S */
6509/* File: armv6t2/binopLit16.S */
6510    /*
6511     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6512     * that specifies an instruction that performs "result = r0 op r1".
6513     * This could be an ARM instruction or a function call.  (If the result
6514     * comes back in a register other than r0, you can override "result".)
6515     *
6516     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6517     * vCC (r1).  Useful for integer division and modulus.
6518     *
6519     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6520     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6521     */
6522    /* binop/lit16 vA, vB, #+CCCC */
6523    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6524    mov     r2, rINST, lsr #12          @ r2<- B
6525    ubfx    r9, rINST, #8, #4           @ r9<- A
6526    GET_VREG(r0, r2)                    @ r0<- vB
6527    .if 0
6528    cmp     r1, #0                      @ is second operand zero?
6529    beq     common_errDivideByZero
6530    .endif
6531    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6532
6533    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
6534    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6535    SET_VREG(r0, r9)               @ vAA<- r0
6536    GOTO_OPCODE(ip)                     @ jump to next instruction
6537    /* 10-13 instructions */
6538
6539
6540/* ------------------------------ */
6541    .balign 64
6542.L_OP_ADD_INT_LIT8: /* 0xd8 */
6543/* File: armv5te/OP_ADD_INT_LIT8.S */
6544/* File: armv5te/binopLit8.S */
6545    /*
6546     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6547     * that specifies an instruction that performs "result = r0 op r1".
6548     * This could be an ARM instruction or a function call.  (If the result
6549     * comes back in a register other than r0, you can override "result".)
6550     *
6551     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6552     * vCC (r1).  Useful for integer division and modulus.
6553     *
6554     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6555     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6556     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6557     */
6558    /* binop/lit8 vAA, vBB, #+CC */
6559    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6560    mov     r9, rINST, lsr #8           @ r9<- AA
6561    and     r2, r3, #255                @ r2<- BB
6562    GET_VREG(r0, r2)                    @ r0<- vBB
6563    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6564    .if 0
6565    @cmp     r1, #0                      @ is second operand zero?
6566    beq     common_errDivideByZero
6567    .endif
6568    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6569
6570                               @ optional op; may set condition codes
6571    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
6572    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6573    SET_VREG(r0, r9)               @ vAA<- r0
6574    GOTO_OPCODE(ip)                     @ jump to next instruction
6575    /* 10-12 instructions */
6576
6577
6578/* ------------------------------ */
6579    .balign 64
6580.L_OP_RSUB_INT_LIT8: /* 0xd9 */
6581/* File: armv5te/OP_RSUB_INT_LIT8.S */
6582/* File: armv5te/binopLit8.S */
6583    /*
6584     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6585     * that specifies an instruction that performs "result = r0 op r1".
6586     * This could be an ARM instruction or a function call.  (If the result
6587     * comes back in a register other than r0, you can override "result".)
6588     *
6589     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6590     * vCC (r1).  Useful for integer division and modulus.
6591     *
6592     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6593     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6594     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6595     */
6596    /* binop/lit8 vAA, vBB, #+CC */
6597    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6598    mov     r9, rINST, lsr #8           @ r9<- AA
6599    and     r2, r3, #255                @ r2<- BB
6600    GET_VREG(r0, r2)                    @ r0<- vBB
6601    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6602    .if 0
6603    @cmp     r1, #0                      @ is second operand zero?
6604    beq     common_errDivideByZero
6605    .endif
6606    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6607
6608                               @ optional op; may set condition codes
6609    rsb     r0, r0, r1                              @ r0<- op, r0-r3 changed
6610    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6611    SET_VREG(r0, r9)               @ vAA<- r0
6612    GOTO_OPCODE(ip)                     @ jump to next instruction
6613    /* 10-12 instructions */
6614
6615
6616/* ------------------------------ */
6617    .balign 64
6618.L_OP_MUL_INT_LIT8: /* 0xda */
6619/* File: armv5te/OP_MUL_INT_LIT8.S */
6620/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
6621/* File: armv5te/binopLit8.S */
6622    /*
6623     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6624     * that specifies an instruction that performs "result = r0 op r1".
6625     * This could be an ARM instruction or a function call.  (If the result
6626     * comes back in a register other than r0, you can override "result".)
6627     *
6628     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6629     * vCC (r1).  Useful for integer division and modulus.
6630     *
6631     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6632     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6633     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6634     */
6635    /* binop/lit8 vAA, vBB, #+CC */
6636    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6637    mov     r9, rINST, lsr #8           @ r9<- AA
6638    and     r2, r3, #255                @ r2<- BB
6639    GET_VREG(r0, r2)                    @ r0<- vBB
6640    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6641    .if 0
6642    @cmp     r1, #0                      @ is second operand zero?
6643    beq     common_errDivideByZero
6644    .endif
6645    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6646
6647                               @ optional op; may set condition codes
6648    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
6649    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6650    SET_VREG(r0, r9)               @ vAA<- r0
6651    GOTO_OPCODE(ip)                     @ jump to next instruction
6652    /* 10-12 instructions */
6653
6654
6655/* ------------------------------ */
6656    .balign 64
6657.L_OP_DIV_INT_LIT8: /* 0xdb */
6658/* File: armv5te/OP_DIV_INT_LIT8.S */
6659/* File: armv5te/binopLit8.S */
6660    /*
6661     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6662     * that specifies an instruction that performs "result = r0 op r1".
6663     * This could be an ARM instruction or a function call.  (If the result
6664     * comes back in a register other than r0, you can override "result".)
6665     *
6666     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6667     * vCC (r1).  Useful for integer division and modulus.
6668     *
6669     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6670     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6671     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6672     */
6673    /* binop/lit8 vAA, vBB, #+CC */
6674    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6675    mov     r9, rINST, lsr #8           @ r9<- AA
6676    and     r2, r3, #255                @ r2<- BB
6677    GET_VREG(r0, r2)                    @ r0<- vBB
6678    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6679    .if 1
6680    @cmp     r1, #0                      @ is second operand zero?
6681    beq     common_errDivideByZero
6682    .endif
6683    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6684
6685                               @ optional op; may set condition codes
6686    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
6687    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6688    SET_VREG(r0, r9)               @ vAA<- r0
6689    GOTO_OPCODE(ip)                     @ jump to next instruction
6690    /* 10-12 instructions */
6691
6692
6693/* ------------------------------ */
6694    .balign 64
6695.L_OP_REM_INT_LIT8: /* 0xdc */
6696/* File: armv5te/OP_REM_INT_LIT8.S */
6697/* idivmod returns quotient in r0 and remainder in r1 */
6698/* File: armv5te/binopLit8.S */
6699    /*
6700     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6701     * that specifies an instruction that performs "result = r0 op r1".
6702     * This could be an ARM instruction or a function call.  (If the result
6703     * comes back in a register other than r0, you can override "result".)
6704     *
6705     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6706     * vCC (r1).  Useful for integer division and modulus.
6707     *
6708     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6709     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6710     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6711     */
6712    /* binop/lit8 vAA, vBB, #+CC */
6713    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6714    mov     r9, rINST, lsr #8           @ r9<- AA
6715    and     r2, r3, #255                @ r2<- BB
6716    GET_VREG(r0, r2)                    @ r0<- vBB
6717    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6718    .if 1
6719    @cmp     r1, #0                      @ is second operand zero?
6720    beq     common_errDivideByZero
6721    .endif
6722    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6723
6724                               @ optional op; may set condition codes
6725    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
6726    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6727    SET_VREG(r1, r9)               @ vAA<- r1
6728    GOTO_OPCODE(ip)                     @ jump to next instruction
6729    /* 10-12 instructions */
6730
6731
6732/* ------------------------------ */
6733    .balign 64
6734.L_OP_AND_INT_LIT8: /* 0xdd */
6735/* File: armv5te/OP_AND_INT_LIT8.S */
6736/* File: armv5te/binopLit8.S */
6737    /*
6738     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6739     * that specifies an instruction that performs "result = r0 op r1".
6740     * This could be an ARM instruction or a function call.  (If the result
6741     * comes back in a register other than r0, you can override "result".)
6742     *
6743     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6744     * vCC (r1).  Useful for integer division and modulus.
6745     *
6746     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6747     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6748     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6749     */
6750    /* binop/lit8 vAA, vBB, #+CC */
6751    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6752    mov     r9, rINST, lsr #8           @ r9<- AA
6753    and     r2, r3, #255                @ r2<- BB
6754    GET_VREG(r0, r2)                    @ r0<- vBB
6755    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6756    .if 0
6757    @cmp     r1, #0                      @ is second operand zero?
6758    beq     common_errDivideByZero
6759    .endif
6760    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6761
6762                               @ optional op; may set condition codes
6763    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
6764    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6765    SET_VREG(r0, r9)               @ vAA<- r0
6766    GOTO_OPCODE(ip)                     @ jump to next instruction
6767    /* 10-12 instructions */
6768
6769
6770/* ------------------------------ */
6771    .balign 64
6772.L_OP_OR_INT_LIT8: /* 0xde */
6773/* File: armv5te/OP_OR_INT_LIT8.S */
6774/* File: armv5te/binopLit8.S */
6775    /*
6776     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6777     * that specifies an instruction that performs "result = r0 op r1".
6778     * This could be an ARM instruction or a function call.  (If the result
6779     * comes back in a register other than r0, you can override "result".)
6780     *
6781     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6782     * vCC (r1).  Useful for integer division and modulus.
6783     *
6784     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6785     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6786     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6787     */
6788    /* binop/lit8 vAA, vBB, #+CC */
6789    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6790    mov     r9, rINST, lsr #8           @ r9<- AA
6791    and     r2, r3, #255                @ r2<- BB
6792    GET_VREG(r0, r2)                    @ r0<- vBB
6793    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6794    .if 0
6795    @cmp     r1, #0                      @ is second operand zero?
6796    beq     common_errDivideByZero
6797    .endif
6798    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6799
6800                               @ optional op; may set condition codes
6801    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
6802    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6803    SET_VREG(r0, r9)               @ vAA<- r0
6804    GOTO_OPCODE(ip)                     @ jump to next instruction
6805    /* 10-12 instructions */
6806
6807
6808/* ------------------------------ */
6809    .balign 64
6810.L_OP_XOR_INT_LIT8: /* 0xdf */
6811/* File: armv5te/OP_XOR_INT_LIT8.S */
6812/* File: armv5te/binopLit8.S */
6813    /*
6814     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6815     * that specifies an instruction that performs "result = r0 op r1".
6816     * This could be an ARM instruction or a function call.  (If the result
6817     * comes back in a register other than r0, you can override "result".)
6818     *
6819     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6820     * vCC (r1).  Useful for integer division and modulus.
6821     *
6822     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6823     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6824     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6825     */
6826    /* binop/lit8 vAA, vBB, #+CC */
6827    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6828    mov     r9, rINST, lsr #8           @ r9<- AA
6829    and     r2, r3, #255                @ r2<- BB
6830    GET_VREG(r0, r2)                    @ r0<- vBB
6831    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6832    .if 0
6833    @cmp     r1, #0                      @ is second operand zero?
6834    beq     common_errDivideByZero
6835    .endif
6836    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6837
6838                               @ optional op; may set condition codes
6839    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
6840    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6841    SET_VREG(r0, r9)               @ vAA<- r0
6842    GOTO_OPCODE(ip)                     @ jump to next instruction
6843    /* 10-12 instructions */
6844
6845
6846/* ------------------------------ */
6847    .balign 64
6848.L_OP_SHL_INT_LIT8: /* 0xe0 */
6849/* File: armv5te/OP_SHL_INT_LIT8.S */
6850/* File: armv5te/binopLit8.S */
6851    /*
6852     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6853     * that specifies an instruction that performs "result = r0 op r1".
6854     * This could be an ARM instruction or a function call.  (If the result
6855     * comes back in a register other than r0, you can override "result".)
6856     *
6857     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6858     * vCC (r1).  Useful for integer division and modulus.
6859     *
6860     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6861     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6862     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6863     */
6864    /* binop/lit8 vAA, vBB, #+CC */
6865    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6866    mov     r9, rINST, lsr #8           @ r9<- AA
6867    and     r2, r3, #255                @ r2<- BB
6868    GET_VREG(r0, r2)                    @ r0<- vBB
6869    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6870    .if 0
6871    @cmp     r1, #0                      @ is second operand zero?
6872    beq     common_errDivideByZero
6873    .endif
6874    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6875
6876    and     r1, r1, #31                           @ optional op; may set condition codes
6877    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
6878    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6879    SET_VREG(r0, r9)               @ vAA<- r0
6880    GOTO_OPCODE(ip)                     @ jump to next instruction
6881    /* 10-12 instructions */
6882
6883
6884/* ------------------------------ */
6885    .balign 64
6886.L_OP_SHR_INT_LIT8: /* 0xe1 */
6887/* File: armv5te/OP_SHR_INT_LIT8.S */
6888/* File: armv5te/binopLit8.S */
6889    /*
6890     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6891     * that specifies an instruction that performs "result = r0 op r1".
6892     * This could be an ARM instruction or a function call.  (If the result
6893     * comes back in a register other than r0, you can override "result".)
6894     *
6895     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6896     * vCC (r1).  Useful for integer division and modulus.
6897     *
6898     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6899     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6900     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6901     */
6902    /* binop/lit8 vAA, vBB, #+CC */
6903    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6904    mov     r9, rINST, lsr #8           @ r9<- AA
6905    and     r2, r3, #255                @ r2<- BB
6906    GET_VREG(r0, r2)                    @ r0<- vBB
6907    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6908    .if 0
6909    @cmp     r1, #0                      @ is second operand zero?
6910    beq     common_errDivideByZero
6911    .endif
6912    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6913
6914    and     r1, r1, #31                           @ optional op; may set condition codes
6915    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
6916    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6917    SET_VREG(r0, r9)               @ vAA<- r0
6918    GOTO_OPCODE(ip)                     @ jump to next instruction
6919    /* 10-12 instructions */
6920
6921
6922/* ------------------------------ */
6923    .balign 64
6924.L_OP_USHR_INT_LIT8: /* 0xe2 */
6925/* File: armv5te/OP_USHR_INT_LIT8.S */
6926/* File: armv5te/binopLit8.S */
6927    /*
6928     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6929     * that specifies an instruction that performs "result = r0 op r1".
6930     * This could be an ARM instruction or a function call.  (If the result
6931     * comes back in a register other than r0, you can override "result".)
6932     *
6933     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6934     * vCC (r1).  Useful for integer division and modulus.
6935     *
6936     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6937     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6938     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6939     */
6940    /* binop/lit8 vAA, vBB, #+CC */
6941    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6942    mov     r9, rINST, lsr #8           @ r9<- AA
6943    and     r2, r3, #255                @ r2<- BB
6944    GET_VREG(r0, r2)                    @ r0<- vBB
6945    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6946    .if 0
6947    @cmp     r1, #0                      @ is second operand zero?
6948    beq     common_errDivideByZero
6949    .endif
6950    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6951
6952    and     r1, r1, #31                           @ optional op; may set condition codes
6953    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
6954    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6955    SET_VREG(r0, r9)               @ vAA<- r0
6956    GOTO_OPCODE(ip)                     @ jump to next instruction
6957    /* 10-12 instructions */
6958
6959
6960/* ------------------------------ */
6961    .balign 64
6962.L_OP_IGET_VOLATILE: /* 0xe3 */
6963/* File: armv5te/OP_IGET_VOLATILE.S */
6964/* File: armv5te/OP_IGET.S */
6965    /*
6966     * General 32-bit instance field get.
6967     *
6968     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
6969     */
6970    /* op vA, vB, field@CCCC */
6971    mov     r0, rINST, lsr #12          @ r0<- B
6972    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
6973    FETCH(r1, 1)                        @ r1<- field ref CCCC
6974    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
6975    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
6976    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
6977    cmp     r0, #0                      @ is resolved entry null?
6978    bne     .LOP_IGET_VOLATILE_finish          @ no, already resolved
69798:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
6980    EXPORT_PC()                         @ resolve() could throw
6981    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
6982    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
6983    cmp     r0, #0
6984    bne     .LOP_IGET_VOLATILE_finish
6985    b       common_exceptionThrown
6986
6987
6988/* ------------------------------ */
6989    .balign 64
6990.L_OP_IPUT_VOLATILE: /* 0xe4 */
6991/* File: armv5te/OP_IPUT_VOLATILE.S */
6992/* File: armv5te/OP_IPUT.S */
6993    /*
6994     * General 32-bit instance field put.
6995     *
6996     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
6997     */
6998    /* op vA, vB, field@CCCC */
6999    mov     r0, rINST, lsr #12          @ r0<- B
7000    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7001    FETCH(r1, 1)                        @ r1<- field ref CCCC
7002    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7003    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7004    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7005    cmp     r0, #0                      @ is resolved entry null?
7006    bne     .LOP_IPUT_VOLATILE_finish          @ no, already resolved
70078:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7008    EXPORT_PC()                         @ resolve() could throw
7009    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7010    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7011    cmp     r0, #0                      @ success?
7012    bne     .LOP_IPUT_VOLATILE_finish          @ yes, finish up
7013    b       common_exceptionThrown
7014
7015
7016/* ------------------------------ */
7017    .balign 64
7018.L_OP_SGET_VOLATILE: /* 0xe5 */
7019/* File: armv5te/OP_SGET_VOLATILE.S */
7020/* File: armv5te/OP_SGET.S */
7021    /*
7022     * General 32-bit SGET handler.
7023     *
7024     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7025     */
7026    /* op vAA, field@BBBB */
7027    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7028    FETCH(r1, 1)                        @ r1<- field ref BBBB
7029    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
7030    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
7031    cmp     r0, #0                      @ is resolved entry null?
7032    beq     .LOP_SGET_VOLATILE_resolve         @ yes, do resolve
7033.LOP_SGET_VOLATILE_finish: @ field ptr in r0
7034    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7035    SMP_DMB                            @ acquiring load
7036    mov     r2, rINST, lsr #8           @ r2<- AA
7037    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7038    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7039    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7040    GOTO_OPCODE(ip)                     @ jump to next instruction
7041
7042
7043/* ------------------------------ */
7044    .balign 64
7045.L_OP_SPUT_VOLATILE: /* 0xe6 */
7046/* File: armv5te/OP_SPUT_VOLATILE.S */
7047/* File: armv5te/OP_SPUT.S */
7048    /*
7049     * General 32-bit SPUT handler.
7050     *
7051     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
7052     */
7053    /* op vAA, field@BBBB */
7054    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7055    FETCH(r1, 1)                        @ r1<- field ref BBBB
7056    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
7057    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
7058    cmp     r0, #0                      @ is resolved entry null?
7059    beq     .LOP_SPUT_VOLATILE_resolve         @ yes, do resolve
7060.LOP_SPUT_VOLATILE_finish:   @ field ptr in r0
7061    mov     r2, rINST, lsr #8           @ r2<- AA
7062    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7063    GET_VREG(r1, r2)                    @ r1<- fp[AA]
7064    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7065    SMP_DMB_ST                        @ releasing store
7066    str     r1, [r0, #offStaticField_value] @ field<- vAA
7067    SMP_DMB
7068    GOTO_OPCODE(ip)                     @ jump to next instruction
7069
7070
7071/* ------------------------------ */
7072    .balign 64
7073.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
7074/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */
7075/* File: armv5te/OP_IGET.S */
7076    /*
7077     * General 32-bit instance field get.
7078     *
7079     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7080     */
7081    /* op vA, vB, field@CCCC */
7082    mov     r0, rINST, lsr #12          @ r0<- B
7083    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7084    FETCH(r1, 1)                        @ r1<- field ref CCCC
7085    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7086    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7087    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7088    cmp     r0, #0                      @ is resolved entry null?
7089    bne     .LOP_IGET_OBJECT_VOLATILE_finish          @ no, already resolved
70908:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7091    EXPORT_PC()                         @ resolve() could throw
7092    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7093    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7094    cmp     r0, #0
7095    bne     .LOP_IGET_OBJECT_VOLATILE_finish
7096    b       common_exceptionThrown
7097
7098
7099/* ------------------------------ */
7100    .balign 64
7101.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
7102/* File: armv5te/OP_IGET_WIDE_VOLATILE.S */
7103/* File: armv5te/OP_IGET_WIDE.S */
7104    /*
7105     * Wide 32-bit instance field get.
7106     */
7107    /* iget-wide vA, vB, field@CCCC */
7108    mov     r0, rINST, lsr #12          @ r0<- B
7109    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7110    FETCH(r1, 1)                        @ r1<- field ref CCCC
7111    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7112    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7113    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7114    cmp     r0, #0                      @ is resolved entry null?
7115    bne     .LOP_IGET_WIDE_VOLATILE_finish          @ no, already resolved
71168:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
7117    EXPORT_PC()                         @ resolve() could throw
7118    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7119    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7120    cmp     r0, #0
7121    bne     .LOP_IGET_WIDE_VOLATILE_finish
7122    b       common_exceptionThrown
7123
7124
7125/* ------------------------------ */
7126    .balign 64
7127.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
7128/* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */
7129/* File: armv5te/OP_IPUT_WIDE.S */
7130    /* iput-wide vA, vB, field@CCCC */
7131    mov     r0, rINST, lsr #12          @ r0<- B
7132    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7133    FETCH(r1, 1)                        @ r1<- field ref CCCC
7134    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7135    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7136    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7137    cmp     r0, #0                      @ is resolved entry null?
7138    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ no, already resolved
71398:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
7140    EXPORT_PC()                         @ resolve() could throw
7141    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7142    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7143    cmp     r0, #0                      @ success?
7144    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ yes, finish up
7145    b       common_exceptionThrown
7146
7147
7148/* ------------------------------ */
7149    .balign 64
7150.L_OP_SGET_WIDE_VOLATILE: /* 0xea */
7151/* File: armv5te/OP_SGET_WIDE_VOLATILE.S */
7152/* File: armv5te/OP_SGET_WIDE.S */
7153    /*
7154     * 64-bit SGET handler.
7155     */
7156    /* sget-wide vAA, field@BBBB */
7157    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7158    FETCH(r1, 1)                        @ r1<- field ref BBBB
7159    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
7160    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
7161    cmp     r0, #0                      @ is resolved entry null?
7162    beq     .LOP_SGET_WIDE_VOLATILE_resolve         @ yes, do resolve
7163.LOP_SGET_WIDE_VOLATILE_finish:
7164    mov     r9, rINST, lsr #8           @ r9<- AA
7165    .if 1
7166    add     r0, r0, #offStaticField_value @ r0<- pointer to data
7167    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
7168    .else
7169    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
7170    .endif
7171    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7172    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7173    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
7174    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7175    GOTO_OPCODE(ip)                     @ jump to next instruction
7176
7177
7178/* ------------------------------ */
7179    .balign 64
7180.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
7181/* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */
7182/* File: armv5te/OP_SPUT_WIDE.S */
7183    /*
7184     * 64-bit SPUT handler.
7185     */
7186    /* sput-wide vAA, field@BBBB */
7187    ldr     r0, [rSELF, #offThread_methodClassDex]  @ r0<- DvmDex
7188    FETCH(r1, 1)                        @ r1<- field ref BBBB
7189    ldr     r10, [r0, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
7190    mov     r9, rINST, lsr #8           @ r9<- AA
7191    ldr     r2, [r10, r1, lsl #2]        @ r2<- resolved StaticField ptr
7192    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7193    cmp     r2, #0                      @ is resolved entry null?
7194    beq     .LOP_SPUT_WIDE_VOLATILE_resolve         @ yes, do resolve
7195.LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9
7196    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7197    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
7198    GET_INST_OPCODE(r10)                @ extract opcode from rINST
7199    .if 1
7200    add     r2, r2, #offStaticField_value @ r2<- pointer to data
7201    bl      dvmQuasiAtomicSwap64Sync    @ stores r0/r1 into addr r2
7202    .else
7203    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
7204    .endif
7205    GOTO_OPCODE(r10)                    @ jump to next instruction
7206
7207
7208/* ------------------------------ */
7209    .balign 64
7210.L_OP_BREAKPOINT: /* 0xec */
7211/* File: armv5te/OP_BREAKPOINT.S */
7212    /*
7213     * Breakpoint handler.
7214     *
7215     * Restart this instruction with the original opcode.  By
7216     * the time we get here, the breakpoint will have already been
7217     * handled.
7218     */
7219    mov     r0, rPC
7220    bl      dvmGetOriginalOpcode        @ (rPC)
7221    FETCH(rINST, 0)                     @ reload OP_BREAKPOINT + rest of inst
7222    ldr     r1, [rSELF, #offThread_mainHandlerTable]
7223    and     rINST, #0xff00
7224    orr     rINST, rINST, r0
7225    GOTO_OPCODE_BASE(r1, r0)
7226
7227/* ------------------------------ */
7228    .balign 64
7229.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
7230/* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */
7231    /*
7232     * Handle a throw-verification-error instruction.  This throws an
7233     * exception for an error discovered during verification.  The
7234     * exception is indicated by AA, with some detail provided by BBBB.
7235     */
7236    /* op AA, ref@BBBB */
7237    ldr     r0, [rSELF, #offThread_method]    @ r0<- self->method
7238    FETCH(r2, 1)                        @ r2<- BBBB
7239    EXPORT_PC()                         @ export the PC
7240    mov     r1, rINST, lsr #8           @ r1<- AA
7241    bl      dvmThrowVerificationError   @ always throws
7242    b       common_exceptionThrown      @ handle exception
7243
7244/* ------------------------------ */
7245    .balign 64
7246.L_OP_EXECUTE_INLINE: /* 0xee */
7247/* File: armv5te/OP_EXECUTE_INLINE.S */
7248    /*
7249     * Execute a "native inline" instruction.
7250     *
7251     * We need to call an InlineOp4Func:
7252     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7253     *
7254     * The first four args are in r0-r3, pointer to return value storage
7255     * is on the stack.  The function's return value is a flag that tells
7256     * us if an exception was thrown.
7257     *
7258     * TUNING: could maintain two tables, pointer in Thread and
7259     * swap if profiler/debuggger active.
7260     */
7261    /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
7262    ldrh    r2, [rSELF, #offThread_subMode]
7263    FETCH(r10, 1)                       @ r10<- BBBB
7264    EXPORT_PC()                         @ can throw
7265    ands    r2, #kSubModeDebugProfile   @ Any going on?
7266    bne     .LOP_EXECUTE_INLINE_debugmode       @ yes - take slow path
7267.LOP_EXECUTE_INLINE_resume:
7268    add     r1, rSELF, #offThread_retval  @ r1<- &self->retval
7269    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7270    mov     r0, rINST, lsr #12          @ r0<- B
7271    str     r1, [sp]                    @ push &self->retval
7272    bl      .LOP_EXECUTE_INLINE_continue        @ make call; will return after
7273    add     sp, sp, #8                  @ pop stack
7274    cmp     r0, #0                      @ test boolean result of inline
7275    beq     common_exceptionThrown      @ returned false, handle exception
7276    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7277    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7278    GOTO_OPCODE(ip)                     @ jump to next instruction
7279
7280/* ------------------------------ */
7281    .balign 64
7282.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
7283/* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */
7284    /*
7285     * Execute a "native inline" instruction, using "/range" semantics.
7286     * Same idea as execute-inline, but we get the args differently.
7287     *
7288     * We need to call an InlineOp4Func:
7289     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7290     *
7291     * The first four args are in r0-r3, pointer to return value storage
7292     * is on the stack.  The function's return value is a flag that tells
7293     * us if an exception was thrown.
7294     */
7295    /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */
7296    ldrh    r2, [rSELF, #offThread_subMode]
7297    FETCH(r10, 1)                       @ r10<- BBBB
7298    EXPORT_PC()                         @ can throw
7299    ands    r2, #kSubModeDebugProfile   @ Any going on?
7300    bne     .LOP_EXECUTE_INLINE_RANGE_debugmode       @ yes - take slow path
7301.LOP_EXECUTE_INLINE_RANGE_resume:
7302    add     r1, rSELF, #offThread_retval  @ r1<- &self->retval
7303    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7304    mov     r0, rINST, lsr #8           @ r0<- AA
7305    str     r1, [sp]                    @ push &self->retval
7306    bl      .LOP_EXECUTE_INLINE_RANGE_continue        @ make call; will return after
7307    add     sp, sp, #8                  @ pop stack
7308    cmp     r0, #0                      @ test boolean result of inline
7309    beq     common_exceptionThrown      @ returned false, handle exception
7310    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7311    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7312    GOTO_OPCODE(ip)                     @ jump to next instruction
7313
7314/* ------------------------------ */
7315    .balign 64
7316.L_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */
7317/* File: armv5te/OP_INVOKE_OBJECT_INIT_RANGE.S */
7318    /*
7319     * Invoke Object.<init> on an object.  In practice we know that
7320     * Object's nullary constructor doesn't do anything, so we just
7321     * skip it unless a debugger is active.
7322     */
7323    FETCH(r1, 2)                  @ r1<- CCCC
7324    GET_VREG(r0, r1)                    @ r0<- "this" ptr
7325    cmp     r0, #0                      @ check for NULL
7326    beq     common_errNullObject        @ export PC and throw NPE
7327    ldr     r1, [r0, #offObject_clazz]  @ r1<- obj->clazz
7328    ldr     r2, [r1, #offClassObject_accessFlags] @ r2<- clazz->accessFlags
7329    tst     r2, #CLASS_ISFINALIZABLE    @ is this class finalizable?
7330    bne     .LOP_INVOKE_OBJECT_INIT_RANGE_setFinal        @ yes, go
7331.LOP_INVOKE_OBJECT_INIT_RANGE_finish:
7332    ldrh    r1, [rSELF, #offThread_subMode]
7333    ands    r1, #kSubModeDebuggerActive @ debugger active?
7334    bne     .LOP_INVOKE_OBJECT_INIT_RANGE_debugger        @ Yes - skip optimization
7335    FETCH_ADVANCE_INST(2+1)       @ advance to next instr, load rINST
7336    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
7337    GOTO_OPCODE(ip)                     @ execute it
7338
7339/* ------------------------------ */
7340    .balign 64
7341.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */
7342/* File: armv5te/OP_RETURN_VOID_BARRIER.S */
7343    SMP_DMB_ST
7344    b       common_returnFromMethod
7345
7346/* ------------------------------ */
7347    .balign 64
7348.L_OP_IGET_QUICK: /* 0xf2 */
7349/* File: armv6t2/OP_IGET_QUICK.S */
7350    /* For: iget-quick, iget-object-quick */
7351    /* op vA, vB, offset@CCCC */
7352    mov     r2, rINST, lsr #12          @ r2<- B
7353    FETCH(r1, 1)                        @ r1<- field byte offset
7354    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7355    ubfx    r2, rINST, #8, #4           @ r2<- A
7356    cmp     r3, #0                      @ check object for null
7357    beq     common_errNullObject        @ object was null
7358    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7359    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7360    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7361    SET_VREG(r0, r2)                    @ fp[A]<- r0
7362    GOTO_OPCODE(ip)                     @ jump to next instruction
7363
7364/* ------------------------------ */
7365    .balign 64
7366.L_OP_IGET_WIDE_QUICK: /* 0xf3 */
7367/* File: armv6t2/OP_IGET_WIDE_QUICK.S */
7368    /* iget-wide-quick vA, vB, offset@CCCC */
7369    mov     r2, rINST, lsr #12          @ r2<- B
7370    FETCH(ip, 1)                        @ ip<- field byte offset
7371    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7372    ubfx    r2, rINST, #8, #4           @ r2<- A
7373    cmp     r3, #0                      @ check object for null
7374    beq     common_errNullObject        @ object was null
7375    ldrd    r0, [r3, ip]                @ r0<- obj.field (64 bits, aligned)
7376    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7377    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
7378    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7379    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
7380    GOTO_OPCODE(ip)                     @ jump to next instruction
7381
7382/* ------------------------------ */
7383    .balign 64
7384.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */
7385/* File: armv5te/OP_IGET_OBJECT_QUICK.S */
7386/* File: armv5te/OP_IGET_QUICK.S */
7387    /* For: iget-quick, iget-object-quick */
7388    /* op vA, vB, offset@CCCC */
7389    mov     r2, rINST, lsr #12          @ r2<- B
7390    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7391    FETCH(r1, 1)                        @ r1<- field byte offset
7392    cmp     r3, #0                      @ check object for null
7393    mov     r2, rINST, lsr #8           @ r2<- A(+)
7394    beq     common_errNullObject        @ object was null
7395    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7396    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7397    and     r2, r2, #15
7398    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7399    SET_VREG(r0, r2)                    @ fp[A]<- r0
7400    GOTO_OPCODE(ip)                     @ jump to next instruction
7401
7402
7403/* ------------------------------ */
7404    .balign 64
7405.L_OP_IPUT_QUICK: /* 0xf5 */
7406/* File: armv6t2/OP_IPUT_QUICK.S */
7407    /* For: iput-quick, iput-object-quick */
7408    /* op vA, vB, offset@CCCC */
7409    mov     r2, rINST, lsr #12          @ r2<- B
7410    FETCH(r1, 1)                        @ r1<- field byte offset
7411    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7412    ubfx    r2, rINST, #8, #4           @ r2<- A
7413    cmp     r3, #0                      @ check object for null
7414    beq     common_errNullObject        @ object was null
7415    GET_VREG(r0, r2)                    @ r0<- fp[A]
7416    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7417    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7418    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7419    GOTO_OPCODE(ip)                     @ jump to next instruction
7420
7421/* ------------------------------ */
7422    .balign 64
7423.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */
7424/* File: armv6t2/OP_IPUT_WIDE_QUICK.S */
7425    /* iput-wide-quick vA, vB, offset@CCCC */
7426    mov     r1, rINST, lsr #12          @ r1<- B
7427    ubfx    r0, rINST, #8, #4           @ r0<- A
7428    GET_VREG(r2, r1)                    @ r2<- fp[B], the object pointer
7429    add     r3, rFP, r0, lsl #2         @ r3<- &fp[A]
7430    cmp     r2, #0                      @ check object for null
7431    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[A]
7432    beq     common_errNullObject        @ object was null
7433    FETCH(r3, 1)                        @ r3<- field byte offset
7434    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7435    strd    r0, [r2, r3]                @ obj.field (64 bits, aligned)<- r0/r1
7436    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7437    GOTO_OPCODE(ip)                     @ jump to next instruction
7438
7439/* ------------------------------ */
7440    .balign 64
7441.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
7442/* File: armv5te/OP_IPUT_OBJECT_QUICK.S */
7443    /* For: iput-object-quick */
7444    /* op vA, vB, offset@CCCC */
7445    mov     r2, rINST, lsr #12          @ r2<- B
7446    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7447    FETCH(r1, 1)                        @ r1<- field byte offset
7448    cmp     r3, #0                      @ check object for null
7449    mov     r2, rINST, lsr #8           @ r2<- A(+)
7450    beq     common_errNullObject        @ object was null
7451    and     r2, r2, #15
7452    GET_VREG(r0, r2)                    @ r0<- fp[A]
7453    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
7454    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7455    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7456    cmp     r0, #0
7457    strneb  r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head
7458    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7459    GOTO_OPCODE(ip)                     @ jump to next instruction
7460
7461/* ------------------------------ */
7462    .balign 64
7463.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
7464/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7465    /*
7466     * Handle an optimized virtual method call.
7467     *
7468     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7469     */
7470    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7471    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7472    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7473    FETCH(r1, 1)                        @ r1<- BBBB
7474    .if     (!0)
7475    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7476    .endif
7477    GET_VREG(r9, r3)                    @ r9<- vC ("this" ptr)
7478    cmp     r9, #0                      @ is "this" null?
7479    beq     common_errNullObject        @ null "this", throw exception
7480    ldr     r2, [r9, #offObject_clazz]  @ r2<- thisPtr->clazz
7481    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7482    EXPORT_PC()                         @ invoke must export
7483    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7484    bl      common_invokeMethodNoRange @ (r0=method, r9="this")
7485
7486/* ------------------------------ */
7487    .balign 64
7488.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
7489/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */
7490/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7491    /*
7492     * Handle an optimized virtual method call.
7493     *
7494     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7495     */
7496    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7497    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7498    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7499    FETCH(r1, 1)                        @ r1<- BBBB
7500    .if     (!1)
7501    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7502    .endif
7503    GET_VREG(r9, r3)                    @ r9<- vC ("this" ptr)
7504    cmp     r9, #0                      @ is "this" null?
7505    beq     common_errNullObject        @ null "this", throw exception
7506    ldr     r2, [r9, #offObject_clazz]  @ r2<- thisPtr->clazz
7507    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7508    EXPORT_PC()                         @ invoke must export
7509    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7510    bl      common_invokeMethodRange @ (r0=method, r9="this")
7511
7512
7513/* ------------------------------ */
7514    .balign 64
7515.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */
7516/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7517    /*
7518     * Handle an optimized "super" method call.
7519     *
7520     * for: [opt] invoke-super-quick, invoke-super-quick/range
7521     */
7522    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7523    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7524    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7525    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7526    .if     (!0)
7527    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7528    .endif
7529    FETCH(r1, 1)                        @ r1<- BBBB
7530    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7531    EXPORT_PC()                         @ must export for invoke
7532    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7533    GET_VREG(r9, r10)                   @ r9<- "this"
7534    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7535    cmp     r9, #0                      @ null "this" ref?
7536    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7537    beq     common_errNullObject        @ "this" is null, throw exception
7538    bl      common_invokeMethodNoRange @ (r0=method, r9="this")
7539
7540/* ------------------------------ */
7541    .balign 64
7542.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
7543/* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */
7544/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7545    /*
7546     * Handle an optimized "super" method call.
7547     *
7548     * for: [opt] invoke-super-quick, invoke-super-quick/range
7549     */
7550    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7551    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7552    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7553    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7554    .if     (!1)
7555    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7556    .endif
7557    FETCH(r1, 1)                        @ r1<- BBBB
7558    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7559    EXPORT_PC()                         @ must export for invoke
7560    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7561    GET_VREG(r9, r10)                   @ r9<- "this"
7562    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7563    cmp     r9, #0                      @ null "this" ref?
7564    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7565    beq     common_errNullObject        @ "this" is null, throw exception
7566    bl      common_invokeMethodRange @ (r0=method, r9="this")
7567
7568
7569/* ------------------------------ */
7570    .balign 64
7571.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
7572/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */
7573/* File: armv5te/OP_IPUT_OBJECT.S */
7574    /*
7575     * 32-bit instance field put.
7576     *
7577     * for: iput-object, iput-object-volatile
7578     */
7579    /* op vA, vB, field@CCCC */
7580    mov     r0, rINST, lsr #12          @ r0<- B
7581    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7582    FETCH(r1, 1)                        @ r1<- field ref CCCC
7583    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7584    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7585    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7586    cmp     r0, #0                      @ is resolved entry null?
7587    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ no, already resolved
75888:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7589    EXPORT_PC()                         @ resolve() could throw
7590    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7591    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7592    cmp     r0, #0                      @ success?
7593    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ yes, finish up
7594    b       common_exceptionThrown
7595
7596
7597/* ------------------------------ */
7598    .balign 64
7599.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
7600/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */
7601/* File: armv5te/OP_SGET.S */
7602    /*
7603     * General 32-bit SGET handler.
7604     *
7605     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7606     */
7607    /* op vAA, field@BBBB */
7608    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7609    FETCH(r1, 1)                        @ r1<- field ref BBBB
7610    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
7611    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
7612    cmp     r0, #0                      @ is resolved entry null?
7613    beq     .LOP_SGET_OBJECT_VOLATILE_resolve         @ yes, do resolve
7614.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0
7615    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7616    SMP_DMB                            @ acquiring load
7617    mov     r2, rINST, lsr #8           @ r2<- AA
7618    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7619    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7620    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7621    GOTO_OPCODE(ip)                     @ jump to next instruction
7622
7623
7624/* ------------------------------ */
7625    .balign 64
7626.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
7627/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */
7628/* File: armv5te/OP_SPUT_OBJECT.S */
7629    /*
7630     * 32-bit SPUT handler for objects
7631     *
7632     * for: sput-object, sput-object-volatile
7633     */
7634    /* op vAA, field@BBBB */
7635    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7636    FETCH(r1, 1)                        @ r1<- field ref BBBB
7637    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
7638    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
7639    cmp     r0, #0                      @ is resolved entry null?
7640    beq     .LOP_SPUT_OBJECT_VOLATILE_resolve         @ yes, do resolve
7641.LOP_SPUT_OBJECT_VOLATILE_finish:   @ field ptr in r0
7642    mov     r2, rINST, lsr #8           @ r2<- AA
7643    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7644    GET_VREG(r1, r2)                    @ r1<- fp[AA]
7645    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
7646    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
7647    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7648    SMP_DMB_ST                        @ releasing store
7649    b       .LOP_SPUT_OBJECT_VOLATILE_end
7650
7651
7652/* ------------------------------ */
7653    .balign 64
7654.L_OP_UNUSED_FF: /* 0xff */
7655/* File: armv5te/OP_UNUSED_FF.S */
7656/* File: armv5te/unused.S */
7657    bl      common_abort
7658
7659
7660    .balign 64
7661    .size   dvmAsmInstructionStart, .-dvmAsmInstructionStart
7662    .global dvmAsmInstructionEnd
7663dvmAsmInstructionEnd:
7664
7665/*
7666 * ===========================================================================
7667 *  Sister implementations
7668 * ===========================================================================
7669 */
7670    .global dvmAsmSisterStart
7671    .type   dvmAsmSisterStart, %function
7672    .text
7673    .balign 4
7674dvmAsmSisterStart:
7675
7676/* continuation for OP_CONST_STRING */
7677
7678    /*
7679     * Continuation if the String has not yet been resolved.
7680     *  r1: BBBB (String ref)
7681     *  r9: target register
7682     */
7683.LOP_CONST_STRING_resolve:
7684    EXPORT_PC()
7685    ldr     r0, [rSELF, #offThread_method] @ r0<- self->method
7686    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
7687    bl      dvmResolveString            @ r0<- String reference
7688    cmp     r0, #0                      @ failed?
7689    beq     common_exceptionThrown      @ yup, handle the exception
7690    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7691    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7692    SET_VREG(r0, r9)                    @ vAA<- r0
7693    GOTO_OPCODE(ip)                     @ jump to next instruction
7694
7695/* continuation for OP_CONST_STRING_JUMBO */
7696
7697    /*
7698     * Continuation if the String has not yet been resolved.
7699     *  r1: BBBBBBBB (String ref)
7700     *  r9: target register
7701     */
7702.LOP_CONST_STRING_JUMBO_resolve:
7703    EXPORT_PC()
7704    ldr     r0, [rSELF, #offThread_method] @ r0<- self->method
7705    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
7706    bl      dvmResolveString            @ r0<- String reference
7707    cmp     r0, #0                      @ failed?
7708    beq     common_exceptionThrown      @ yup, handle the exception
7709    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7710    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7711    SET_VREG(r0, r9)                    @ vAA<- r0
7712    GOTO_OPCODE(ip)                     @ jump to next instruction
7713
7714/* continuation for OP_CONST_CLASS */
7715
7716    /*
7717     * Continuation if the Class has not yet been resolved.
7718     *  r1: BBBB (Class ref)
7719     *  r9: target register
7720     */
7721.LOP_CONST_CLASS_resolve:
7722    EXPORT_PC()
7723    ldr     r0, [rSELF, #offThread_method] @ r0<- self->method
7724    mov     r2, #1                      @ r2<- true
7725    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
7726    bl      dvmResolveClass             @ r0<- Class reference
7727    cmp     r0, #0                      @ failed?
7728    beq     common_exceptionThrown      @ yup, handle the exception
7729    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7730    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7731    SET_VREG(r0, r9)                    @ vAA<- r0
7732    GOTO_OPCODE(ip)                     @ jump to next instruction
7733
7734/* continuation for OP_CHECK_CAST */
7735
7736    /*
7737     * Trivial test failed, need to perform full check.  This is common.
7738     *  r0 holds obj->clazz
7739     *  r1 holds desired class resolved from BBBB
7740     *  r9 holds object
7741     */
7742.LOP_CHECK_CAST_fullcheck:
7743    mov     r10, r1                     @ avoid ClassObject getting clobbered
7744    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
7745    cmp     r0, #0                      @ failed?
7746    bne     .LOP_CHECK_CAST_okay            @ no, success
7747
7748    @ A cast has failed.  We need to throw a ClassCastException.
7749    EXPORT_PC()                         @ about to throw
7750    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
7751    mov     r1, r10                     @ r1<- desired class
7752    bl      dvmThrowClassCastException
7753    b       common_exceptionThrown
7754
7755    /*
7756     * Resolution required.  This is the least-likely path.
7757     *
7758     *  r2 holds BBBB
7759     *  r9 holds object
7760     */
7761.LOP_CHECK_CAST_resolve:
7762    EXPORT_PC()                         @ resolve() could throw
7763    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
7764    mov     r1, r2                      @ r1<- BBBB
7765    mov     r2, #0                      @ r2<- false
7766    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
7767    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
7768    cmp     r0, #0                      @ got null?
7769    beq     common_exceptionThrown      @ yes, handle exception
7770    mov     r1, r0                      @ r1<- class resolved from BBB
7771    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
7772    b       .LOP_CHECK_CAST_resolved        @ pick up where we left off
7773
7774/* continuation for OP_INSTANCE_OF */
7775
7776    /*
7777     * Trivial test failed, need to perform full check.  This is common.
7778     *  r0 holds obj->clazz
7779     *  r1 holds class resolved from BBBB
7780     *  r9 holds A
7781     */
7782.LOP_INSTANCE_OF_fullcheck:
7783    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
7784    @ fall through to OP_INSTANCE_OF_store
7785
7786    /*
7787     * r0 holds boolean result
7788     * r9 holds A
7789     */
7790.LOP_INSTANCE_OF_store:
7791    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7792    SET_VREG(r0, r9)                    @ vA<- r0
7793    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7794    GOTO_OPCODE(ip)                     @ jump to next instruction
7795
7796    /*
7797     * Trivial test succeeded, save and bail.
7798     *  r9 holds A
7799     */
7800.LOP_INSTANCE_OF_trivial:
7801    mov     r0, #1                      @ indicate success
7802    @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper
7803    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7804    SET_VREG(r0, r9)                    @ vA<- r0
7805    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7806    GOTO_OPCODE(ip)                     @ jump to next instruction
7807
7808    /*
7809     * Resolution required.  This is the least-likely path.
7810     *
7811     *  r3 holds BBBB
7812     *  r9 holds A
7813     */
7814.LOP_INSTANCE_OF_resolve:
7815    EXPORT_PC()                         @ resolve() could throw
7816    ldr     r0, [rSELF, #offThread_method]    @ r0<- self->method
7817    mov     r1, r3                      @ r1<- BBBB
7818    mov     r2, #1                      @ r2<- true
7819    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
7820    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
7821    cmp     r0, #0                      @ got null?
7822    beq     common_exceptionThrown      @ yes, handle exception
7823    mov     r1, r0                      @ r1<- class resolved from BBB
7824    mov     r3, rINST, lsr #12          @ r3<- B
7825    GET_VREG(r0, r3)                    @ r0<- vB (object)
7826    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
7827    b       .LOP_INSTANCE_OF_resolved        @ pick up where we left off
7828
7829/* continuation for OP_NEW_INSTANCE */
7830
7831    .balign 32                          @ minimize cache lines
7832.LOP_NEW_INSTANCE_finish: @ r0=new object
7833    mov     r3, rINST, lsr #8           @ r3<- AA
7834    cmp     r0, #0                      @ failed?
7835#if defined(WITH_JIT)
7836    /*
7837     * The JIT needs the class to be fully resolved before it can
7838     * include this instruction in a trace.
7839     */
7840    ldrh    r1, [rSELF, #offThread_subMode]
7841    beq     common_exceptionThrown      @ yes, handle the exception
7842    ands    r1, #kSubModeJitTraceBuild  @ under construction?
7843    bne     .LOP_NEW_INSTANCE_jitCheck
7844#else
7845    beq     common_exceptionThrown      @ yes, handle the exception
7846#endif
7847.LOP_NEW_INSTANCE_end:
7848    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7849    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7850    SET_VREG(r0, r3)                    @ vAA<- r0
7851    GOTO_OPCODE(ip)                     @ jump to next instruction
7852
7853#if defined(WITH_JIT)
7854    /*
7855     * Check to see if we need to stop the trace building early.
7856     * r0: new object
7857     * r3: vAA
7858     */
7859.LOP_NEW_INSTANCE_jitCheck:
7860    ldr     r1, [r10]                   @ reload resolved class
7861    cmp     r1, #0                      @ okay?
7862    bne     .LOP_NEW_INSTANCE_end             @ yes, finish
7863    mov     r9, r0                      @ preserve new object
7864    mov     r10, r3                     @ preserve vAA
7865    mov     r0, rSELF
7866    mov     r1, rPC
7867    bl      dvmJitEndTraceSelect        @ (self, pc)
7868    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7869    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7870    SET_VREG(r9, r10)                   @ vAA<- new object
7871    GOTO_OPCODE(ip)                     @ jump to next instruction
7872#endif
7873
7874    /*
7875     * Class initialization required.
7876     *
7877     *  r0 holds class object
7878     */
7879.LOP_NEW_INSTANCE_needinit:
7880    mov     r9, r0                      @ save r0
7881    bl      dvmInitClass                @ initialize class
7882    cmp     r0, #0                      @ check boolean result
7883    mov     r0, r9                      @ restore r0
7884    bne     .LOP_NEW_INSTANCE_initialized     @ success, continue
7885    b       common_exceptionThrown      @ failed, deal with init exception
7886
7887    /*
7888     * Resolution required.  This is the least-likely path.
7889     *
7890     *  r1 holds BBBB
7891     */
7892.LOP_NEW_INSTANCE_resolve:
7893    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
7894    mov     r2, #0                      @ r2<- false
7895    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
7896    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
7897    cmp     r0, #0                      @ got null?
7898    bne     .LOP_NEW_INSTANCE_resolved        @ no, continue
7899    b       common_exceptionThrown      @ yes, handle exception
7900
7901/* continuation for OP_NEW_ARRAY */
7902
7903
7904    /*
7905     * Resolve class.  (This is an uncommon case.)
7906     *
7907     *  r1 holds array length
7908     *  r2 holds class ref CCCC
7909     */
7910.LOP_NEW_ARRAY_resolve:
7911    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
7912    mov     r9, r1                      @ r9<- length (save)
7913    mov     r1, r2                      @ r1<- CCCC
7914    mov     r2, #0                      @ r2<- false
7915    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
7916    bl      dvmResolveClass             @ r0<- call(clazz, ref)
7917    cmp     r0, #0                      @ got null?
7918    mov     r1, r9                      @ r1<- length (restore)
7919    beq     common_exceptionThrown      @ yes, handle exception
7920    @ fall through to OP_NEW_ARRAY_finish
7921
7922    /*
7923     * Finish allocation.
7924     *
7925     *  r0 holds class
7926     *  r1 holds array length
7927     */
7928.LOP_NEW_ARRAY_finish:
7929    mov     r2, #ALLOC_DONT_TRACK       @ don't track in local refs table
7930    bl      dvmAllocArrayByClass        @ r0<- call(clazz, length, flags)
7931    cmp     r0, #0                      @ failed?
7932    mov     r2, rINST, lsr #8           @ r2<- A+
7933    beq     common_exceptionThrown      @ yes, handle the exception
7934    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7935    and     r2, r2, #15                 @ r2<- A
7936    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7937    SET_VREG(r0, r2)                    @ vA<- r0
7938    GOTO_OPCODE(ip)                     @ jump to next instruction
7939
7940/* continuation for OP_FILLED_NEW_ARRAY */
7941
7942    /*
7943     * On entry:
7944     *  r0 holds array class
7945     *  r10 holds AA or BA
7946     */
7947.LOP_FILLED_NEW_ARRAY_continue:
7948    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
7949    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
7950    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
7951    .if     0
7952    mov     r1, r10                     @ r1<- AA (length)
7953    .else
7954    mov     r1, r10, lsr #4             @ r1<- B (length)
7955    .endif
7956    cmp     rINST, #'I'                 @ array of ints?
7957    cmpne   rINST, #'L'                 @ array of objects?
7958    cmpne   rINST, #'['                 @ array of arrays?
7959    mov     r9, r1                      @ save length in r9
7960    bne     .LOP_FILLED_NEW_ARRAY_notimpl         @ no, not handled yet
7961    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
7962    cmp     r0, #0                      @ null return?
7963    beq     common_exceptionThrown      @ alloc failed, handle exception
7964
7965    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
7966    str     r0, [rSELF, #offThread_retval]      @ retval.l <- new array
7967    str     rINST, [rSELF, #offThread_retval+4] @ retval.h <- type
7968    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
7969    subs    r9, r9, #1                  @ length--, check for neg
7970    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
7971    bmi     2f                          @ was zero, bail
7972
7973    @ copy values from registers into the array
7974    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
7975    .if     0
7976    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
79771:  ldr     r3, [r2], #4                @ r3<- *r2++
7978    subs    r9, r9, #1                  @ count--
7979    str     r3, [r0], #4                @ *contents++ = vX
7980    bpl     1b
7981    @ continue at 2
7982    .else
7983    cmp     r9, #4                      @ length was initially 5?
7984    and     r2, r10, #15                @ r2<- A
7985    bne     1f                          @ <= 4 args, branch
7986    GET_VREG(r3, r2)                    @ r3<- vA
7987    sub     r9, r9, #1                  @ count--
7988    str     r3, [r0, #16]               @ contents[4] = vA
79891:  and     r2, r1, #15                 @ r2<- F/E/D/C
7990    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
7991    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
7992    subs    r9, r9, #1                  @ count--
7993    str     r3, [r0], #4                @ *contents++ = vX
7994    bpl     1b
7995    @ continue at 2
7996    .endif
7997
79982:
7999    ldr     r0, [rSELF, #offThread_retval]     @ r0<- object
8000    ldr     r1, [rSELF, #offThread_retval+4]   @ r1<- type
8001    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
8002    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
8003    cmp     r1, #'I'                         @ Is int array?
8004    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
8005    GOTO_OPCODE(ip)                          @ execute it
8006
8007    /*
8008     * Throw an exception indicating that we have not implemented this
8009     * mode of filled-new-array.
8010     */
8011.LOP_FILLED_NEW_ARRAY_notimpl:
8012    ldr     r0, .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY
80133:  add     r0, pc
8014    bl      dvmThrowInternalError
8015    b       common_exceptionThrown
8016
8017    /*
8018     * Ideally we'd only define this once, but depending on layout we can
8019     * exceed the range of the load above.
8020     */
8021
8022.L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY:
8023    .word   PCREL_REF(.LstrFilledNewArrayNotImpl,3b)
8024
8025/* continuation for OP_FILLED_NEW_ARRAY_RANGE */
8026
8027    /*
8028     * On entry:
8029     *  r0 holds array class
8030     *  r10 holds AA or BA
8031     */
8032.LOP_FILLED_NEW_ARRAY_RANGE_continue:
8033    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
8034    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
8035    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
8036    .if     1
8037    mov     r1, r10                     @ r1<- AA (length)
8038    .else
8039    mov     r1, r10, lsr #4             @ r1<- B (length)
8040    .endif
8041    cmp     rINST, #'I'                 @ array of ints?
8042    cmpne   rINST, #'L'                 @ array of objects?
8043    cmpne   rINST, #'['                 @ array of arrays?
8044    mov     r9, r1                      @ save length in r9
8045    bne     .LOP_FILLED_NEW_ARRAY_RANGE_notimpl         @ no, not handled yet
8046    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
8047    cmp     r0, #0                      @ null return?
8048    beq     common_exceptionThrown      @ alloc failed, handle exception
8049
8050    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
8051    str     r0, [rSELF, #offThread_retval]      @ retval.l <- new array
8052    str     rINST, [rSELF, #offThread_retval+4] @ retval.h <- type
8053    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
8054    subs    r9, r9, #1                  @ length--, check for neg
8055    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
8056    bmi     2f                          @ was zero, bail
8057
8058    @ copy values from registers into the array
8059    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
8060    .if     1
8061    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
80621:  ldr     r3, [r2], #4                @ r3<- *r2++
8063    subs    r9, r9, #1                  @ count--
8064    str     r3, [r0], #4                @ *contents++ = vX
8065    bpl     1b
8066    @ continue at 2
8067    .else
8068    cmp     r9, #4                      @ length was initially 5?
8069    and     r2, r10, #15                @ r2<- A
8070    bne     1f                          @ <= 4 args, branch
8071    GET_VREG(r3, r2)                    @ r3<- vA
8072    sub     r9, r9, #1                  @ count--
8073    str     r3, [r0, #16]               @ contents[4] = vA
80741:  and     r2, r1, #15                 @ r2<- F/E/D/C
8075    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
8076    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
8077    subs    r9, r9, #1                  @ count--
8078    str     r3, [r0], #4                @ *contents++ = vX
8079    bpl     1b
8080    @ continue at 2
8081    .endif
8082
80832:
8084    ldr     r0, [rSELF, #offThread_retval]     @ r0<- object
8085    ldr     r1, [rSELF, #offThread_retval+4]   @ r1<- type
8086    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
8087    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
8088    cmp     r1, #'I'                         @ Is int array?
8089    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
8090    GOTO_OPCODE(ip)                          @ execute it
8091
8092    /*
8093     * Throw an exception indicating that we have not implemented this
8094     * mode of filled-new-array.
8095     */
8096.LOP_FILLED_NEW_ARRAY_RANGE_notimpl:
8097    ldr     r0, .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY_RANGE
80983:  add     r0, pc
8099    bl      dvmThrowInternalError
8100    b       common_exceptionThrown
8101
8102    /*
8103     * Ideally we'd only define this once, but depending on layout we can
8104     * exceed the range of the load above.
8105     */
8106
8107.L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY_RANGE:
8108    .word   PCREL_REF(.LstrFilledNewArrayNotImpl,3b)
8109
8110/* continuation for OP_CMPL_FLOAT */
8111.LOP_CMPL_FLOAT_finish:
8112    SET_VREG(r0, r9)                    @ vAA<- r0
8113    GOTO_OPCODE(ip)                     @ jump to next instruction
8114
8115/* continuation for OP_CMPG_FLOAT */
8116.LOP_CMPG_FLOAT_finish:
8117    SET_VREG(r0, r9)                    @ vAA<- r0
8118    GOTO_OPCODE(ip)                     @ jump to next instruction
8119
8120/* continuation for OP_CMPL_DOUBLE */
8121.LOP_CMPL_DOUBLE_finish:
8122    SET_VREG(r0, r9)                    @ vAA<- r0
8123    GOTO_OPCODE(ip)                     @ jump to next instruction
8124
8125/* continuation for OP_CMPG_DOUBLE */
8126.LOP_CMPG_DOUBLE_finish:
8127    SET_VREG(r0, r9)                    @ vAA<- r0
8128    GOTO_OPCODE(ip)                     @ jump to next instruction
8129
8130/* continuation for OP_CMP_LONG */
8131
8132.LOP_CMP_LONG_less:
8133    mvn     r1, #0                      @ r1<- -1
8134    @ Want to cond code the next mov so we can avoid branch, but don't see it;
8135    @ instead, we just replicate the tail end.
8136    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8137    SET_VREG(r1, r9)                    @ vAA<- r1
8138    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8139    GOTO_OPCODE(ip)                     @ jump to next instruction
8140
8141.LOP_CMP_LONG_greater:
8142    mov     r1, #1                      @ r1<- 1
8143    @ fall through to _finish
8144
8145.LOP_CMP_LONG_finish:
8146    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8147    SET_VREG(r1, r9)                    @ vAA<- r1
8148    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8149    GOTO_OPCODE(ip)                     @ jump to next instruction
8150
8151/* continuation for OP_AGET_WIDE */
8152
8153.LOP_AGET_WIDE_finish:
8154    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8155    ldrd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
8156    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
8157    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8158    stmia   r9, {r2-r3}                 @ vAA/vAA+1<- r2/r3
8159    GOTO_OPCODE(ip)                     @ jump to next instruction
8160
8161/* continuation for OP_APUT_WIDE */
8162
8163.LOP_APUT_WIDE_finish:
8164    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8165    ldmia   r9, {r2-r3}                 @ r2/r3<- vAA/vAA+1
8166    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8167    strd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
8168    GOTO_OPCODE(ip)                     @ jump to next instruction
8169
8170/* continuation for OP_APUT_OBJECT */
8171    /*
8172     * On entry:
8173     *  rINST = vBB (arrayObj)
8174     *  r9 = vAA (obj)
8175     *  r10 = offset into array (vBB + vCC * width)
8176     */
8177.LOP_APUT_OBJECT_finish:
8178    cmp     r9, #0                      @ storing null reference?
8179    beq     .LOP_APUT_OBJECT_skip_check      @ yes, skip type checks
8180    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
8181    ldr     r1, [rINST, #offObject_clazz]  @ r1<- arrayObj->clazz
8182    bl      dvmCanPutArrayElement       @ test object type vs. array type
8183    cmp     r0, #0                      @ okay?
8184    beq     .LOP_APUT_OBJECT_throw           @ no
8185    mov     r1, rINST                   @ r1<- arrayObj
8186    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8187    ldr     r2, [rSELF, #offThread_cardTable]     @ get biased CT base
8188    add     r10, #offArrayObject_contents   @ r0<- pointer to slot
8189    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8190    str     r9, [r10]                   @ vBB[vCC]<- vAA
8191    strb    r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head
8192    GOTO_OPCODE(ip)                     @ jump to next instruction
8193.LOP_APUT_OBJECT_skip_check:
8194    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8195    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8196    str     r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA
8197    GOTO_OPCODE(ip)                     @ jump to next instruction
8198.LOP_APUT_OBJECT_throw:
8199    @ The types don't match.  We need to throw an ArrayStoreException.
8200    ldr     r0, [r9, #offObject_clazz]
8201    ldr     r1, [rINST, #offObject_clazz]
8202    EXPORT_PC()
8203    bl      dvmThrowArrayStoreExceptionIncompatibleElement
8204    b       common_exceptionThrown
8205
8206/* continuation for OP_IGET */
8207
8208    /*
8209     * Currently:
8210     *  r0 holds resolved field
8211     *  r9 holds object
8212     */
8213.LOP_IGET_finish:
8214    @bl      common_squeak0
8215    cmp     r9, #0                      @ check object for null
8216    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8217    beq     common_errNullObject        @ object was null
8218    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8219    ubfx    r2, rINST, #8, #4           @ r2<- A
8220    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8221    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8222    SET_VREG(r0, r2)                    @ fp[A]<- r0
8223    GOTO_OPCODE(ip)                     @ jump to next instruction
8224
8225/* continuation for OP_IGET_WIDE */
8226
8227    /*
8228     * Currently:
8229     *  r0 holds resolved field
8230     *  r9 holds object
8231     */
8232.LOP_IGET_WIDE_finish:
8233    cmp     r9, #0                      @ check object for null
8234    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8235    beq     common_errNullObject        @ object was null
8236    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
8237    ubfx    r2, rINST, #8, #4           @ r2<- A
8238    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8239    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
8240    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8241    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
8242    GOTO_OPCODE(ip)                     @ jump to next instruction
8243
8244/* continuation for OP_IGET_OBJECT */
8245
8246    /*
8247     * Currently:
8248     *  r0 holds resolved field
8249     *  r9 holds object
8250     */
8251.LOP_IGET_OBJECT_finish:
8252    @bl      common_squeak0
8253    cmp     r9, #0                      @ check object for null
8254    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8255    beq     common_errNullObject        @ object was null
8256    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8257    @ no-op                             @ acquiring load
8258    mov     r2, rINST, lsr #8           @ r2<- A+
8259    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8260    and     r2, r2, #15                 @ r2<- A
8261    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8262    SET_VREG(r0, r2)                    @ fp[A]<- r0
8263    GOTO_OPCODE(ip)                     @ jump to next instruction
8264
8265/* continuation for OP_IGET_BOOLEAN */
8266
8267    /*
8268     * Currently:
8269     *  r0 holds resolved field
8270     *  r9 holds object
8271     */
8272.LOP_IGET_BOOLEAN_finish:
8273    @bl      common_squeak1
8274    cmp     r9, #0                      @ check object for null
8275    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8276    beq     common_errNullObject        @ object was null
8277    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8278    @ no-op                             @ acquiring load
8279    mov     r2, rINST, lsr #8           @ r2<- A+
8280    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8281    and     r2, r2, #15                 @ r2<- A
8282    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8283    SET_VREG(r0, r2)                    @ fp[A]<- r0
8284    GOTO_OPCODE(ip)                     @ jump to next instruction
8285
8286/* continuation for OP_IGET_BYTE */
8287
8288    /*
8289     * Currently:
8290     *  r0 holds resolved field
8291     *  r9 holds object
8292     */
8293.LOP_IGET_BYTE_finish:
8294    @bl      common_squeak2
8295    cmp     r9, #0                      @ check object for null
8296    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8297    beq     common_errNullObject        @ object was null
8298    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8299    @ no-op                             @ acquiring load
8300    mov     r2, rINST, lsr #8           @ r2<- A+
8301    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8302    and     r2, r2, #15                 @ r2<- A
8303    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8304    SET_VREG(r0, r2)                    @ fp[A]<- r0
8305    GOTO_OPCODE(ip)                     @ jump to next instruction
8306
8307/* continuation for OP_IGET_CHAR */
8308
8309    /*
8310     * Currently:
8311     *  r0 holds resolved field
8312     *  r9 holds object
8313     */
8314.LOP_IGET_CHAR_finish:
8315    @bl      common_squeak3
8316    cmp     r9, #0                      @ check object for null
8317    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8318    beq     common_errNullObject        @ object was null
8319    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8320    @ no-op                             @ acquiring load
8321    mov     r2, rINST, lsr #8           @ r2<- A+
8322    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8323    and     r2, r2, #15                 @ r2<- A
8324    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8325    SET_VREG(r0, r2)                    @ fp[A]<- r0
8326    GOTO_OPCODE(ip)                     @ jump to next instruction
8327
8328/* continuation for OP_IGET_SHORT */
8329
8330    /*
8331     * Currently:
8332     *  r0 holds resolved field
8333     *  r9 holds object
8334     */
8335.LOP_IGET_SHORT_finish:
8336    @bl      common_squeak4
8337    cmp     r9, #0                      @ check object for null
8338    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8339    beq     common_errNullObject        @ object was null
8340    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8341    @ no-op                             @ acquiring load
8342    mov     r2, rINST, lsr #8           @ r2<- A+
8343    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8344    and     r2, r2, #15                 @ r2<- A
8345    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8346    SET_VREG(r0, r2)                    @ fp[A]<- r0
8347    GOTO_OPCODE(ip)                     @ jump to next instruction
8348
8349/* continuation for OP_IPUT */
8350
8351    /*
8352     * Currently:
8353     *  r0 holds resolved field
8354     *  r9 holds object
8355     */
8356.LOP_IPUT_finish:
8357    @bl      common_squeak0
8358    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8359    ubfx    r1, rINST, #8, #4           @ r1<- A
8360    cmp     r9, #0                      @ check object for null
8361    GET_VREG(r0, r1)                    @ r0<- fp[A]
8362    beq     common_errNullObject        @ object was null
8363    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8364    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8365    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
8366    GOTO_OPCODE(ip)                     @ jump to next instruction
8367
8368/* continuation for OP_IPUT_WIDE */
8369
8370    /*
8371     * Currently:
8372     *  r0 holds resolved field
8373     *  r9 holds object
8374     */
8375.LOP_IPUT_WIDE_finish:
8376    ubfx    r2, rINST, #8, #4           @ r2<- A
8377    cmp     r9, #0                      @ check object for null
8378    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8379    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
8380    beq     common_errNullObject        @ object was null
8381    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8382    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
8383    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8384    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0
8385    GOTO_OPCODE(ip)                     @ jump to next instruction
8386
8387/* continuation for OP_IPUT_OBJECT */
8388
8389    /*
8390     * Currently:
8391     *  r0 holds resolved field
8392     *  r9 holds object
8393     */
8394.LOP_IPUT_OBJECT_finish:
8395    @bl      common_squeak0
8396    mov     r1, rINST, lsr #8           @ r1<- A+
8397    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8398    and     r1, r1, #15                 @ r1<- A
8399    cmp     r9, #0                      @ check object for null
8400    GET_VREG(r0, r1)                    @ r0<- fp[A]
8401    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
8402    beq     common_errNullObject        @ object was null
8403    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8404    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8405    @ no-op                         @ releasing store
8406    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
8407    @ no-op
8408    cmp     r0, #0                      @ stored a null reference?
8409    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
8410    GOTO_OPCODE(ip)                     @ jump to next instruction
8411
8412/* continuation for OP_IPUT_BOOLEAN */
8413
8414    /*
8415     * Currently:
8416     *  r0 holds resolved field
8417     *  r9 holds object
8418     */
8419.LOP_IPUT_BOOLEAN_finish:
8420    @bl      common_squeak1
8421    mov     r1, rINST, lsr #8           @ r1<- A+
8422    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8423    and     r1, r1, #15                 @ r1<- A
8424    cmp     r9, #0                      @ check object for null
8425    GET_VREG(r0, r1)                    @ r0<- fp[A]
8426    beq     common_errNullObject        @ object was null
8427    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8428    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8429    @ no-op                         @ releasing store
8430    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
8431    @ no-op
8432    GOTO_OPCODE(ip)                     @ jump to next instruction
8433
8434/* continuation for OP_IPUT_BYTE */
8435
8436    /*
8437     * Currently:
8438     *  r0 holds resolved field
8439     *  r9 holds object
8440     */
8441.LOP_IPUT_BYTE_finish:
8442    @bl      common_squeak2
8443    mov     r1, rINST, lsr #8           @ r1<- A+
8444    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8445    and     r1, r1, #15                 @ r1<- A
8446    cmp     r9, #0                      @ check object for null
8447    GET_VREG(r0, r1)                    @ r0<- fp[A]
8448    beq     common_errNullObject        @ object was null
8449    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8450    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8451    @ no-op                         @ releasing store
8452    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
8453    @ no-op
8454    GOTO_OPCODE(ip)                     @ jump to next instruction
8455
8456/* continuation for OP_IPUT_CHAR */
8457
8458    /*
8459     * Currently:
8460     *  r0 holds resolved field
8461     *  r9 holds object
8462     */
8463.LOP_IPUT_CHAR_finish:
8464    @bl      common_squeak3
8465    mov     r1, rINST, lsr #8           @ r1<- A+
8466    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8467    and     r1, r1, #15                 @ r1<- A
8468    cmp     r9, #0                      @ check object for null
8469    GET_VREG(r0, r1)                    @ r0<- fp[A]
8470    beq     common_errNullObject        @ object was null
8471    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8472    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8473    @ no-op                         @ releasing store
8474    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
8475    @ no-op
8476    GOTO_OPCODE(ip)                     @ jump to next instruction
8477
8478/* continuation for OP_IPUT_SHORT */
8479
8480    /*
8481     * Currently:
8482     *  r0 holds resolved field
8483     *  r9 holds object
8484     */
8485.LOP_IPUT_SHORT_finish:
8486    @bl      common_squeak4
8487    mov     r1, rINST, lsr #8           @ r1<- A+
8488    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8489    and     r1, r1, #15                 @ r1<- A
8490    cmp     r9, #0                      @ check object for null
8491    GET_VREG(r0, r1)                    @ r0<- fp[A]
8492    beq     common_errNullObject        @ object was null
8493    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8494    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8495    @ no-op                         @ releasing store
8496    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
8497    @ no-op
8498    GOTO_OPCODE(ip)                     @ jump to next instruction
8499
8500/* continuation for OP_SGET */
8501
8502    /*
8503     * Continuation if the field has not yet been resolved.
8504     *  r1:  BBBB field ref
8505     *  r10: dvmDex->pResFields
8506     */
8507.LOP_SGET_resolve:
8508    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8509#if defined(WITH_JIT)
8510    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8511#endif
8512    EXPORT_PC()                         @ resolve() could throw, so export now
8513    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8514    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8515    cmp     r0, #0                      @ success?
8516    beq     common_exceptionThrown      @ no, handle exception
8517#if defined(WITH_JIT)
8518    /*
8519     * If the JIT is actively building a trace we need to make sure
8520     * that the field is fully resolved before including this instruction.
8521     */
8522    bl      common_verifyField
8523#endif
8524    b       .LOP_SGET_finish
8525
8526/* continuation for OP_SGET_WIDE */
8527
8528    /*
8529     * Continuation if the field has not yet been resolved.
8530     *  r1:  BBBB field ref
8531     *  r10: dvmDex->pResFields
8532     *
8533     * Returns StaticField pointer in r0.
8534     */
8535.LOP_SGET_WIDE_resolve:
8536    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8537#if defined(WITH_JIT)
8538    add     r10, r10, r1, lsl #2        @ r1<- &dvmDex->pResFields[field]
8539#endif
8540    EXPORT_PC()                         @ resolve() could throw, so export now
8541    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8542    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8543    cmp     r0, #0                      @ success?
8544    beq     common_exceptionThrown      @ no, handle exception
8545#if defined(WITH_JIT)
8546    /*
8547     * If the JIT is actively building a trace we need to make sure
8548     * that the field is fully resolved before including this instruction.
8549     */
8550    bl      common_verifyField
8551#endif
8552    b       .LOP_SGET_WIDE_finish          @ resume
8553
8554/* continuation for OP_SGET_OBJECT */
8555
8556    /*
8557     * Continuation if the field has not yet been resolved.
8558     *  r1:  BBBB field ref
8559     *  r10: dvmDex->pResFields
8560     */
8561.LOP_SGET_OBJECT_resolve:
8562    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8563#if defined(WITH_JIT)
8564    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8565#endif
8566    EXPORT_PC()                         @ resolve() could throw, so export now
8567    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8568    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8569    cmp     r0, #0                      @ success?
8570    beq     common_exceptionThrown      @ no, handle exception
8571#if defined(WITH_JIT)
8572    /*
8573     * If the JIT is actively building a trace we need to make sure
8574     * that the field is fully resolved before including this instruction.
8575     */
8576    bl      common_verifyField
8577#endif
8578    b       .LOP_SGET_OBJECT_finish
8579
8580/* continuation for OP_SGET_BOOLEAN */
8581
8582    /*
8583     * Continuation if the field has not yet been resolved.
8584     *  r1:  BBBB field ref
8585     *  r10: dvmDex->pResFields
8586     */
8587.LOP_SGET_BOOLEAN_resolve:
8588    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8589#if defined(WITH_JIT)
8590    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8591#endif
8592    EXPORT_PC()                         @ resolve() could throw, so export now
8593    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8594    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8595    cmp     r0, #0                      @ success?
8596    beq     common_exceptionThrown      @ no, handle exception
8597#if defined(WITH_JIT)
8598    /*
8599     * If the JIT is actively building a trace we need to make sure
8600     * that the field is fully resolved before including this instruction.
8601     */
8602    bl      common_verifyField
8603#endif
8604    b       .LOP_SGET_BOOLEAN_finish
8605
8606/* continuation for OP_SGET_BYTE */
8607
8608    /*
8609     * Continuation if the field has not yet been resolved.
8610     *  r1:  BBBB field ref
8611     *  r10: dvmDex->pResFields
8612     */
8613.LOP_SGET_BYTE_resolve:
8614    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8615#if defined(WITH_JIT)
8616    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8617#endif
8618    EXPORT_PC()                         @ resolve() could throw, so export now
8619    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8620    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8621    cmp     r0, #0                      @ success?
8622    beq     common_exceptionThrown      @ no, handle exception
8623#if defined(WITH_JIT)
8624    /*
8625     * If the JIT is actively building a trace we need to make sure
8626     * that the field is fully resolved before including this instruction.
8627     */
8628    bl      common_verifyField
8629#endif
8630    b       .LOP_SGET_BYTE_finish
8631
8632/* continuation for OP_SGET_CHAR */
8633
8634    /*
8635     * Continuation if the field has not yet been resolved.
8636     *  r1:  BBBB field ref
8637     *  r10: dvmDex->pResFields
8638     */
8639.LOP_SGET_CHAR_resolve:
8640    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8641#if defined(WITH_JIT)
8642    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8643#endif
8644    EXPORT_PC()                         @ resolve() could throw, so export now
8645    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8646    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8647    cmp     r0, #0                      @ success?
8648    beq     common_exceptionThrown      @ no, handle exception
8649#if defined(WITH_JIT)
8650    /*
8651     * If the JIT is actively building a trace we need to make sure
8652     * that the field is fully resolved before including this instruction.
8653     */
8654    bl      common_verifyField
8655#endif
8656    b       .LOP_SGET_CHAR_finish
8657
8658/* continuation for OP_SGET_SHORT */
8659
8660    /*
8661     * Continuation if the field has not yet been resolved.
8662     *  r1:  BBBB field ref
8663     *  r10: dvmDex->pResFields
8664     */
8665.LOP_SGET_SHORT_resolve:
8666    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8667#if defined(WITH_JIT)
8668    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8669#endif
8670    EXPORT_PC()                         @ resolve() could throw, so export now
8671    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8672    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8673    cmp     r0, #0                      @ success?
8674    beq     common_exceptionThrown      @ no, handle exception
8675#if defined(WITH_JIT)
8676    /*
8677     * If the JIT is actively building a trace we need to make sure
8678     * that the field is fully resolved before including this instruction.
8679     */
8680    bl      common_verifyField
8681#endif
8682    b       .LOP_SGET_SHORT_finish
8683
8684/* continuation for OP_SPUT */
8685
8686    /*
8687     * Continuation if the field has not yet been resolved.
8688     *  r1:  BBBB field ref
8689     *  r10: dvmDex->pResFields
8690     */
8691.LOP_SPUT_resolve:
8692    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8693#if defined(WITH_JIT)
8694    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8695#endif
8696    EXPORT_PC()                         @ resolve() could throw, so export now
8697    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8698    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8699    cmp     r0, #0                      @ success?
8700    beq     common_exceptionThrown      @ no, handle exception
8701#if defined(WITH_JIT)
8702    /*
8703     * If the JIT is actively building a trace we need to make sure
8704     * that the field is fully resolved before including this instruction.
8705     */
8706    bl      common_verifyField
8707#endif
8708    b       .LOP_SPUT_finish          @ resume
8709
8710/* continuation for OP_SPUT_WIDE */
8711
8712    /*
8713     * Continuation if the field has not yet been resolved.
8714     *  r1:  BBBB field ref
8715     *  r9:  &fp[AA]
8716     *  r10: dvmDex->pResFields
8717     *
8718     * Returns StaticField pointer in r2.
8719     */
8720.LOP_SPUT_WIDE_resolve:
8721    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8722#if defined(WITH_JIT)
8723    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8724#endif
8725    EXPORT_PC()                         @ resolve() could throw, so export now
8726    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8727    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8728    cmp     r0, #0                      @ success?
8729    mov     r2, r0                      @ copy to r2
8730    beq     common_exceptionThrown      @ no, handle exception
8731#if defined(WITH_JIT)
8732    /*
8733     * If the JIT is actively building a trace we need to make sure
8734     * that the field is fully resolved before including this instruction.
8735     */
8736    bl      common_verifyField
8737#endif
8738    b       .LOP_SPUT_WIDE_finish          @ resume
8739
8740/* continuation for OP_SPUT_OBJECT */
8741
8742
8743.LOP_SPUT_OBJECT_end:
8744    str     r1, [r0, #offStaticField_value]  @ field<- vAA
8745    @ no-op
8746    cmp     r1, #0                      @ stored a null object?
8747    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
8748    GOTO_OPCODE(ip)                     @ jump to next instruction
8749
8750    /* Continuation if the field has not yet been resolved.
8751     * r1:  BBBB field ref
8752     * r10: dvmDex->pResFields
8753     */
8754.LOP_SPUT_OBJECT_resolve:
8755    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8756#if defined(WITH_JIT)
8757    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8758#endif
8759    EXPORT_PC()                         @ resolve() could throw, so export now
8760    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8761    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8762    cmp     r0, #0                      @ success?
8763    beq     common_exceptionThrown      @ no, handle exception
8764#if defined(WITH_JIT)
8765    /*
8766     * If the JIT is actively building a trace we need to make sure
8767     * that the field is fully resolved before including this instruction.
8768     */
8769    bl      common_verifyField
8770#endif
8771    b       .LOP_SPUT_OBJECT_finish          @ resume
8772
8773
8774/* continuation for OP_SPUT_BOOLEAN */
8775
8776    /*
8777     * Continuation if the field has not yet been resolved.
8778     *  r1:  BBBB field ref
8779     *  r10: dvmDex->pResFields
8780     */
8781.LOP_SPUT_BOOLEAN_resolve:
8782    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8783#if defined(WITH_JIT)
8784    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8785#endif
8786    EXPORT_PC()                         @ resolve() could throw, so export now
8787    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8788    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8789    cmp     r0, #0                      @ success?
8790    beq     common_exceptionThrown      @ no, handle exception
8791#if defined(WITH_JIT)
8792    /*
8793     * If the JIT is actively building a trace we need to make sure
8794     * that the field is fully resolved before including this instruction.
8795     */
8796    bl      common_verifyField
8797#endif
8798    b       .LOP_SPUT_BOOLEAN_finish          @ resume
8799
8800/* continuation for OP_SPUT_BYTE */
8801
8802    /*
8803     * Continuation if the field has not yet been resolved.
8804     *  r1:  BBBB field ref
8805     *  r10: dvmDex->pResFields
8806     */
8807.LOP_SPUT_BYTE_resolve:
8808    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8809#if defined(WITH_JIT)
8810    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8811#endif
8812    EXPORT_PC()                         @ resolve() could throw, so export now
8813    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8814    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8815    cmp     r0, #0                      @ success?
8816    beq     common_exceptionThrown      @ no, handle exception
8817#if defined(WITH_JIT)
8818    /*
8819     * If the JIT is actively building a trace we need to make sure
8820     * that the field is fully resolved before including this instruction.
8821     */
8822    bl      common_verifyField
8823#endif
8824    b       .LOP_SPUT_BYTE_finish          @ resume
8825
8826/* continuation for OP_SPUT_CHAR */
8827
8828    /*
8829     * Continuation if the field has not yet been resolved.
8830     *  r1:  BBBB field ref
8831     *  r10: dvmDex->pResFields
8832     */
8833.LOP_SPUT_CHAR_resolve:
8834    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8835#if defined(WITH_JIT)
8836    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8837#endif
8838    EXPORT_PC()                         @ resolve() could throw, so export now
8839    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8840    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8841    cmp     r0, #0                      @ success?
8842    beq     common_exceptionThrown      @ no, handle exception
8843#if defined(WITH_JIT)
8844    /*
8845     * If the JIT is actively building a trace we need to make sure
8846     * that the field is fully resolved before including this instruction.
8847     */
8848    bl      common_verifyField
8849#endif
8850    b       .LOP_SPUT_CHAR_finish          @ resume
8851
8852/* continuation for OP_SPUT_SHORT */
8853
8854    /*
8855     * Continuation if the field has not yet been resolved.
8856     *  r1:  BBBB field ref
8857     *  r10: dvmDex->pResFields
8858     */
8859.LOP_SPUT_SHORT_resolve:
8860    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8861#if defined(WITH_JIT)
8862    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8863#endif
8864    EXPORT_PC()                         @ resolve() could throw, so export now
8865    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8866    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8867    cmp     r0, #0                      @ success?
8868    beq     common_exceptionThrown      @ no, handle exception
8869#if defined(WITH_JIT)
8870    /*
8871     * If the JIT is actively building a trace we need to make sure
8872     * that the field is fully resolved before including this instruction.
8873     */
8874    bl      common_verifyField
8875#endif
8876    b       .LOP_SPUT_SHORT_finish          @ resume
8877
8878/* continuation for OP_INVOKE_VIRTUAL */
8879
8880    /*
8881     * At this point:
8882     *  r0 = resolved base method
8883     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
8884     */
8885.LOP_INVOKE_VIRTUAL_continue:
8886    GET_VREG(r9, r10)                   @ r9<- "this" ptr
8887    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
8888    cmp     r9, #0                      @ is "this" null?
8889    beq     common_errNullObject        @ null "this", throw exception
8890    ldr     r3, [r9, #offObject_clazz]  @ r3<- thisPtr->clazz
8891    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
8892    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
8893    bl      common_invokeMethodNoRange @ (r0=method, r9="this")
8894
8895/* continuation for OP_INVOKE_SUPER */
8896
8897    /*
8898     * At this point:
8899     *  r0 = resolved base method
8900     *  r10 = method->clazz
8901     */
8902.LOP_INVOKE_SUPER_continue:
8903    ldr     r1, [r10, #offClassObject_super]    @ r1<- method->clazz->super
8904    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
8905    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
8906    EXPORT_PC()                         @ must export for invoke
8907    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
8908    bcs     .LOP_INVOKE_SUPER_nsm             @ method not present in superclass
8909    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
8910    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
8911    bl      common_invokeMethodNoRange @ continue on
8912
8913.LOP_INVOKE_SUPER_resolve:
8914    mov     r0, r10                     @ r0<- method->clazz
8915    mov     r2, #METHOD_VIRTUAL         @ resolver method type
8916    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8917    cmp     r0, #0                      @ got null?
8918    bne     .LOP_INVOKE_SUPER_continue        @ no, continue
8919    b       common_exceptionThrown      @ yes, handle exception
8920
8921    /*
8922     * Throw a NoSuchMethodError with the method name as the message.
8923     *  r0 = resolved base method
8924     */
8925.LOP_INVOKE_SUPER_nsm:
8926    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
8927    b       common_errNoSuchMethod
8928
8929/* continuation for OP_INVOKE_DIRECT */
8930
8931    /*
8932     * On entry:
8933     *  r1 = reference (BBBB or CCCC)
8934     *  r10 = "this" register
8935     */
8936.LOP_INVOKE_DIRECT_resolve:
8937    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
8938    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8939    mov     r2, #METHOD_DIRECT          @ resolver method type
8940    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8941    cmp     r0, #0                      @ got null?
8942    bne     .LOP_INVOKE_DIRECT_finish          @ no, continue
8943    b       common_exceptionThrown      @ yes, handle exception
8944
8945/* continuation for OP_INVOKE_STATIC */
8946
8947
8948.LOP_INVOKE_STATIC_resolve:
8949    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
8950    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8951    mov     r2, #METHOD_STATIC          @ resolver method type
8952    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8953    cmp     r0, #0                      @ got null?
8954#if defined(WITH_JIT)
8955    /*
8956     * Check to see if we're actively building a trace.  If so,
8957     * we need to keep this instruction out of it.
8958     * r10: &resolved_methodToCall
8959     */
8960    ldrh    r2, [rSELF, #offThread_subMode]
8961    beq     common_exceptionThrown            @ null, handle exception
8962    ands    r2, #kSubModeJitTraceBuild        @ trace under construction?
8963    beq     common_invokeMethodNoRange     @ no (r0=method, r9="this")
8964    ldr     r1, [r10]                         @ reload resolved method
8965    cmp     r1, #0                            @ finished resolving?
8966    bne     common_invokeMethodNoRange     @ yes (r0=method, r9="this")
8967    mov     r10, r0                           @ preserve method
8968    mov     r0, rSELF
8969    mov     r1, rPC
8970    bl      dvmJitEndTraceSelect              @ (self, pc)
8971    mov     r0, r10
8972    b       common_invokeMethodNoRange     @ whew, finally!
8973#else
8974    bne     common_invokeMethodNoRange     @ (r0=method, r9="this")
8975    b       common_exceptionThrown            @ yes, handle exception
8976#endif
8977
8978/* continuation for OP_INVOKE_VIRTUAL_RANGE */
8979
8980    /*
8981     * At this point:
8982     *  r0 = resolved base method
8983     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
8984     */
8985.LOP_INVOKE_VIRTUAL_RANGE_continue:
8986    GET_VREG(r9, r10)                   @ r9<- "this" ptr
8987    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
8988    cmp     r9, #0                      @ is "this" null?
8989    beq     common_errNullObject        @ null "this", throw exception
8990    ldr     r3, [r9, #offObject_clazz]  @ r3<- thisPtr->clazz
8991    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
8992    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
8993    bl      common_invokeMethodRange @ (r0=method, r9="this")
8994
8995/* continuation for OP_INVOKE_SUPER_RANGE */
8996
8997    /*
8998     * At this point:
8999     *  r0 = resolved base method
9000     *  r10 = method->clazz
9001     */
9002.LOP_INVOKE_SUPER_RANGE_continue:
9003    ldr     r1, [r10, #offClassObject_super]    @ r1<- method->clazz->super
9004    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
9005    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
9006    EXPORT_PC()                         @ must export for invoke
9007    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
9008    bcs     .LOP_INVOKE_SUPER_RANGE_nsm             @ method not present in superclass
9009    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
9010    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
9011    bl      common_invokeMethodRange @ continue on
9012
9013.LOP_INVOKE_SUPER_RANGE_resolve:
9014    mov     r0, r10                     @ r0<- method->clazz
9015    mov     r2, #METHOD_VIRTUAL         @ resolver method type
9016    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
9017    cmp     r0, #0                      @ got null?
9018    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ no, continue
9019    b       common_exceptionThrown      @ yes, handle exception
9020
9021    /*
9022     * Throw a NoSuchMethodError with the method name as the message.
9023     *  r0 = resolved base method
9024     */
9025.LOP_INVOKE_SUPER_RANGE_nsm:
9026    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
9027    b       common_errNoSuchMethod
9028
9029/* continuation for OP_INVOKE_DIRECT_RANGE */
9030
9031    /*
9032     * On entry:
9033     *  r1 = reference (BBBB or CCCC)
9034     *  r10 = "this" register
9035     */
9036.LOP_INVOKE_DIRECT_RANGE_resolve:
9037    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
9038    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
9039    mov     r2, #METHOD_DIRECT          @ resolver method type
9040    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
9041    cmp     r0, #0                      @ got null?
9042    bne     .LOP_INVOKE_DIRECT_RANGE_finish          @ no, continue
9043    b       common_exceptionThrown      @ yes, handle exception
9044
9045/* continuation for OP_INVOKE_STATIC_RANGE */
9046
9047
9048.LOP_INVOKE_STATIC_RANGE_resolve:
9049    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
9050    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
9051    mov     r2, #METHOD_STATIC          @ resolver method type
9052    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
9053    cmp     r0, #0                      @ got null?
9054#if defined(WITH_JIT)
9055    /*
9056     * Check to see if we're actively building a trace.  If so,
9057     * we need to keep this instruction out of it.
9058     * r10: &resolved_methodToCall
9059     */
9060    ldrh    r2, [rSELF, #offThread_subMode]
9061    beq     common_exceptionThrown            @ null, handle exception
9062    ands    r2, #kSubModeJitTraceBuild        @ trace under construction?
9063    beq     common_invokeMethodRange     @ no (r0=method, r9="this")
9064    ldr     r1, [r10]                         @ reload resolved method
9065    cmp     r1, #0                            @ finished resolving?
9066    bne     common_invokeMethodRange     @ yes (r0=method, r9="this")
9067    mov     r10, r0                           @ preserve method
9068    mov     r0, rSELF
9069    mov     r1, rPC
9070    bl      dvmJitEndTraceSelect              @ (self, pc)
9071    mov     r0, r10
9072    b       common_invokeMethodRange     @ whew, finally!
9073#else
9074    bne     common_invokeMethodRange     @ (r0=method, r9="this")
9075    b       common_exceptionThrown            @ yes, handle exception
9076#endif
9077
9078/* continuation for OP_FLOAT_TO_LONG */
9079/*
9080 * Convert the float in r0 to a long in r0/r1.
9081 *
9082 * We have to clip values to long min/max per the specification.  The
9083 * expected common case is a "reasonable" value that converts directly
9084 * to modest integer.  The EABI convert function isn't doing this for us.
9085 */
9086f2l_doconv:
9087    stmfd   sp!, {r4, lr}
9088    mov     r1, #0x5f000000             @ (float)maxlong
9089    mov     r4, r0
9090    bl      __aeabi_fcmpge              @ is arg >= maxlong?
9091    cmp     r0, #0                      @ nonzero == yes
9092    mvnne   r0, #0                      @ return maxlong (7fffffff)
9093    mvnne   r1, #0x80000000
9094    ldmnefd sp!, {r4, pc}
9095
9096    mov     r0, r4                      @ recover arg
9097    mov     r1, #0xdf000000             @ (float)minlong
9098    bl      __aeabi_fcmple              @ is arg <= minlong?
9099    cmp     r0, #0                      @ nonzero == yes
9100    movne   r0, #0                      @ return minlong (80000000)
9101    movne   r1, #0x80000000
9102    ldmnefd sp!, {r4, pc}
9103
9104    mov     r0, r4                      @ recover arg
9105    mov     r1, r4
9106    bl      __aeabi_fcmpeq              @ is arg == self?
9107    cmp     r0, #0                      @ zero == no
9108    moveq   r1, #0                      @ return zero for NaN
9109    ldmeqfd sp!, {r4, pc}
9110
9111    mov     r0, r4                      @ recover arg
9112    bl      __aeabi_f2lz                @ convert float to long
9113    ldmfd   sp!, {r4, pc}
9114
9115/* continuation for OP_DOUBLE_TO_LONG */
9116/*
9117 * Convert the double in r0/r1 to a long in r0/r1.
9118 *
9119 * We have to clip values to long min/max per the specification.  The
9120 * expected common case is a "reasonable" value that converts directly
9121 * to modest integer.  The EABI convert function isn't doing this for us.
9122 */
9123d2l_doconv:
9124    stmfd   sp!, {r4, r5, lr}           @ save regs
9125    mov     r3, #0x43000000             @ maxlong, as a double (high word)
9126    add     r3, #0x00e00000             @  0x43e00000
9127    mov     r2, #0                      @ maxlong, as a double (low word)
9128    sub     sp, sp, #4                  @ align for EABI
9129    mov     r4, r0                      @ save a copy of r0
9130    mov     r5, r1                      @  and r1
9131    bl      __aeabi_dcmpge              @ is arg >= maxlong?
9132    cmp     r0, #0                      @ nonzero == yes
9133    mvnne   r0, #0                      @ return maxlong (7fffffffffffffff)
9134    mvnne   r1, #0x80000000
9135    bne     1f
9136
9137    mov     r0, r4                      @ recover arg
9138    mov     r1, r5
9139    mov     r3, #0xc3000000             @ minlong, as a double (high word)
9140    add     r3, #0x00e00000             @  0xc3e00000
9141    mov     r2, #0                      @ minlong, as a double (low word)
9142    bl      __aeabi_dcmple              @ is arg <= minlong?
9143    cmp     r0, #0                      @ nonzero == yes
9144    movne   r0, #0                      @ return minlong (8000000000000000)
9145    movne   r1, #0x80000000
9146    bne     1f
9147
9148    mov     r0, r4                      @ recover arg
9149    mov     r1, r5
9150    mov     r2, r4                      @ compare against self
9151    mov     r3, r5
9152    bl      __aeabi_dcmpeq              @ is arg == self?
9153    cmp     r0, #0                      @ zero == no
9154    moveq   r1, #0                      @ return zero for NaN
9155    beq     1f
9156
9157    mov     r0, r4                      @ recover arg
9158    mov     r1, r5
9159    bl      __aeabi_d2lz                @ convert double to long
9160
91611:
9162    add     sp, sp, #4
9163    ldmfd   sp!, {r4, r5, pc}
9164
9165/* continuation for OP_MUL_LONG */
9166
9167.LOP_MUL_LONG_finish:
9168    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9169    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
9170    GOTO_OPCODE(ip)                     @ jump to next instruction
9171
9172/* continuation for OP_SHL_LONG */
9173
9174.LOP_SHL_LONG_finish:
9175    mov     r0, r0, asl r2              @  r0<- r0 << r2
9176    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9177    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9178    GOTO_OPCODE(ip)                     @ jump to next instruction
9179
9180/* continuation for OP_SHR_LONG */
9181
9182.LOP_SHR_LONG_finish:
9183    mov     r1, r1, asr r2              @  r1<- r1 >> r2
9184    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9185    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9186    GOTO_OPCODE(ip)                     @ jump to next instruction
9187
9188/* continuation for OP_USHR_LONG */
9189
9190.LOP_USHR_LONG_finish:
9191    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
9192    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9193    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9194    GOTO_OPCODE(ip)                     @ jump to next instruction
9195
9196/* continuation for OP_SHL_LONG_2ADDR */
9197
9198.LOP_SHL_LONG_2ADDR_finish:
9199    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9200    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9201    GOTO_OPCODE(ip)                     @ jump to next instruction
9202
9203/* continuation for OP_SHR_LONG_2ADDR */
9204
9205.LOP_SHR_LONG_2ADDR_finish:
9206    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9207    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9208    GOTO_OPCODE(ip)                     @ jump to next instruction
9209
9210/* continuation for OP_USHR_LONG_2ADDR */
9211
9212.LOP_USHR_LONG_2ADDR_finish:
9213    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9214    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9215    GOTO_OPCODE(ip)                     @ jump to next instruction
9216
9217/* continuation for OP_IGET_VOLATILE */
9218
9219    /*
9220     * Currently:
9221     *  r0 holds resolved field
9222     *  r9 holds object
9223     */
9224.LOP_IGET_VOLATILE_finish:
9225    @bl      common_squeak0
9226    cmp     r9, #0                      @ check object for null
9227    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9228    beq     common_errNullObject        @ object was null
9229    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
9230    SMP_DMB                            @ acquiring load
9231    mov     r2, rINST, lsr #8           @ r2<- A+
9232    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9233    and     r2, r2, #15                 @ r2<- A
9234    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9235    SET_VREG(r0, r2)                    @ fp[A]<- r0
9236    GOTO_OPCODE(ip)                     @ jump to next instruction
9237
9238/* continuation for OP_IPUT_VOLATILE */
9239
9240    /*
9241     * Currently:
9242     *  r0 holds resolved field
9243     *  r9 holds object
9244     */
9245.LOP_IPUT_VOLATILE_finish:
9246    @bl      common_squeak0
9247    mov     r1, rINST, lsr #8           @ r1<- A+
9248    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9249    and     r1, r1, #15                 @ r1<- A
9250    cmp     r9, #0                      @ check object for null
9251    GET_VREG(r0, r1)                    @ r0<- fp[A]
9252    beq     common_errNullObject        @ object was null
9253    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9254    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9255    SMP_DMB_ST                        @ releasing store
9256    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
9257    SMP_DMB
9258    GOTO_OPCODE(ip)                     @ jump to next instruction
9259
9260/* continuation for OP_SGET_VOLATILE */
9261
9262    /*
9263     * Continuation if the field has not yet been resolved.
9264     *  r1:  BBBB field ref
9265     *  r10: dvmDex->pResFields
9266     */
9267.LOP_SGET_VOLATILE_resolve:
9268    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9269#if defined(WITH_JIT)
9270    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9271#endif
9272    EXPORT_PC()                         @ resolve() could throw, so export now
9273    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9274    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9275    cmp     r0, #0                      @ success?
9276    beq     common_exceptionThrown      @ no, handle exception
9277#if defined(WITH_JIT)
9278    /*
9279     * If the JIT is actively building a trace we need to make sure
9280     * that the field is fully resolved before including this instruction.
9281     */
9282    bl      common_verifyField
9283#endif
9284    b       .LOP_SGET_VOLATILE_finish
9285
9286/* continuation for OP_SPUT_VOLATILE */
9287
9288    /*
9289     * Continuation if the field has not yet been resolved.
9290     *  r1:  BBBB field ref
9291     *  r10: dvmDex->pResFields
9292     */
9293.LOP_SPUT_VOLATILE_resolve:
9294    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9295#if defined(WITH_JIT)
9296    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9297#endif
9298    EXPORT_PC()                         @ resolve() could throw, so export now
9299    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9300    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9301    cmp     r0, #0                      @ success?
9302    beq     common_exceptionThrown      @ no, handle exception
9303#if defined(WITH_JIT)
9304    /*
9305     * If the JIT is actively building a trace we need to make sure
9306     * that the field is fully resolved before including this instruction.
9307     */
9308    bl      common_verifyField
9309#endif
9310    b       .LOP_SPUT_VOLATILE_finish          @ resume
9311
9312/* continuation for OP_IGET_OBJECT_VOLATILE */
9313
9314    /*
9315     * Currently:
9316     *  r0 holds resolved field
9317     *  r9 holds object
9318     */
9319.LOP_IGET_OBJECT_VOLATILE_finish:
9320    @bl      common_squeak0
9321    cmp     r9, #0                      @ check object for null
9322    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9323    beq     common_errNullObject        @ object was null
9324    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
9325    SMP_DMB                            @ acquiring load
9326    mov     r2, rINST, lsr #8           @ r2<- A+
9327    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9328    and     r2, r2, #15                 @ r2<- A
9329    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9330    SET_VREG(r0, r2)                    @ fp[A]<- r0
9331    GOTO_OPCODE(ip)                     @ jump to next instruction
9332
9333/* continuation for OP_IGET_WIDE_VOLATILE */
9334
9335    /*
9336     * Currently:
9337     *  r0 holds resolved field
9338     *  r9 holds object
9339     */
9340.LOP_IGET_WIDE_VOLATILE_finish:
9341    cmp     r9, #0                      @ check object for null
9342    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9343    beq     common_errNullObject        @ object was null
9344    .if     1
9345    add     r0, r9, r3                  @ r0<- address of field
9346    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
9347    .else
9348    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
9349    .endif
9350    mov     r2, rINST, lsr #8           @ r2<- A+
9351    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9352    and     r2, r2, #15                 @ r2<- A
9353    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
9354    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9355    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
9356    GOTO_OPCODE(ip)                     @ jump to next instruction
9357
9358/* continuation for OP_IPUT_WIDE_VOLATILE */
9359
9360    /*
9361     * Currently:
9362     *  r0 holds resolved field
9363     *  r9 holds object
9364     */
9365.LOP_IPUT_WIDE_VOLATILE_finish:
9366    mov     r2, rINST, lsr #8           @ r2<- A+
9367    cmp     r9, #0                      @ check object for null
9368    and     r2, r2, #15                 @ r2<- A
9369    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9370    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
9371    beq     common_errNullObject        @ object was null
9372    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9373    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
9374    GET_INST_OPCODE(r10)                @ extract opcode from rINST
9375    .if     1
9376    add     r2, r9, r3                  @ r2<- target address
9377    bl      dvmQuasiAtomicSwap64Sync    @ stores r0/r1 into addr r2
9378    .else
9379    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
9380    .endif
9381    GOTO_OPCODE(r10)                    @ jump to next instruction
9382
9383/* continuation for OP_SGET_WIDE_VOLATILE */
9384
9385    /*
9386     * Continuation if the field has not yet been resolved.
9387     *  r1:  BBBB field ref
9388     *  r10: dvmDex->pResFields
9389     *
9390     * Returns StaticField pointer in r0.
9391     */
9392.LOP_SGET_WIDE_VOLATILE_resolve:
9393    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9394#if defined(WITH_JIT)
9395    add     r10, r10, r1, lsl #2        @ r1<- &dvmDex->pResFields[field]
9396#endif
9397    EXPORT_PC()                         @ resolve() could throw, so export now
9398    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9399    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9400    cmp     r0, #0                      @ success?
9401    beq     common_exceptionThrown      @ no, handle exception
9402#if defined(WITH_JIT)
9403    /*
9404     * If the JIT is actively building a trace we need to make sure
9405     * that the field is fully resolved before including this instruction.
9406     */
9407    bl      common_verifyField
9408#endif
9409    b       .LOP_SGET_WIDE_VOLATILE_finish          @ resume
9410
9411/* continuation for OP_SPUT_WIDE_VOLATILE */
9412
9413    /*
9414     * Continuation if the field has not yet been resolved.
9415     *  r1:  BBBB field ref
9416     *  r9:  &fp[AA]
9417     *  r10: dvmDex->pResFields
9418     *
9419     * Returns StaticField pointer in r2.
9420     */
9421.LOP_SPUT_WIDE_VOLATILE_resolve:
9422    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9423#if defined(WITH_JIT)
9424    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9425#endif
9426    EXPORT_PC()                         @ resolve() could throw, so export now
9427    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9428    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9429    cmp     r0, #0                      @ success?
9430    mov     r2, r0                      @ copy to r2
9431    beq     common_exceptionThrown      @ no, handle exception
9432#if defined(WITH_JIT)
9433    /*
9434     * If the JIT is actively building a trace we need to make sure
9435     * that the field is fully resolved before including this instruction.
9436     */
9437    bl      common_verifyField
9438#endif
9439    b       .LOP_SPUT_WIDE_VOLATILE_finish          @ resume
9440
9441/* continuation for OP_EXECUTE_INLINE */
9442
9443    /*
9444     * Extract args, call function.
9445     *  r0 = #of args (0-4)
9446     *  r10 = call index
9447     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
9448     *
9449     * Other ideas:
9450     * - Use a jump table from the main piece to jump directly into the
9451     *   AND/LDR pairs.  Costs a data load, saves a branch.
9452     * - Have five separate pieces that do the loading, so we can work the
9453     *   interleave a little better.  Increases code size.
9454     */
9455.LOP_EXECUTE_INLINE_continue:
9456    rsb     r0, r0, #4                  @ r0<- 4-r0
9457    FETCH(rINST, 2)                     @ rINST<- FEDC
9458    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
9459    bl      common_abort                @ (skipped due to ARM prefetch)
94604:  and     ip, rINST, #0xf000          @ isolate F
9461    ldr     r3, [rFP, ip, lsr #10]      @ r3<- vF (shift right 12, left 2)
94623:  and     ip, rINST, #0x0f00          @ isolate E
9463    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vE
94642:  and     ip, rINST, #0x00f0          @ isolate D
9465    ldr     r1, [rFP, ip, lsr #2]       @ r1<- vD
94661:  and     ip, rINST, #0x000f          @ isolate C
9467    ldr     r0, [rFP, ip, lsl #2]       @ r0<- vC
94680:
9469    ldr     rINST, .LOP_EXECUTE_INLINE_table    @ table of InlineOperation
94705:  add     rINST, pc
9471    ldr     pc, [rINST, r10, lsl #4]    @ sizeof=16, "func" is first entry
9472    @ (not reached)
9473
9474    /*
9475     * We're debugging or profiling.
9476     * r10: opIndex
9477     */
9478.LOP_EXECUTE_INLINE_debugmode:
9479    mov     r0, r10
9480    bl      dvmResolveInlineNative
9481    cmp     r0, #0                      @ did it resolve?
9482    beq     .LOP_EXECUTE_INLINE_resume          @ no, just move on
9483    mov     r9, r0                      @ remember method
9484    mov     r1, rSELF
9485    bl      dvmFastMethodTraceEnter     @ (method, self)
9486    add     r1, rSELF, #offThread_retval@ r1<- &self->retval
9487    sub     sp, sp, #8                  @ make room for arg, +64 bit align
9488    mov     r0, rINST, lsr #12          @ r0<- B
9489    str     r1, [sp]                    @ push &self->retval
9490    bl      .LOP_EXECUTE_INLINE_continue        @ make call; will return after
9491    mov     rINST, r0                   @ save result of inline
9492    add     sp, sp, #8                  @ pop stack
9493    mov     r0, r9                      @ r0<- method
9494    mov     r1, rSELF
9495    bl      dvmFastNativeMethodTraceExit @ (method, self)
9496    cmp     rINST, #0                   @ test boolean result of inline
9497    beq     common_exceptionThrown      @ returned false, handle exception
9498    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
9499    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9500    GOTO_OPCODE(ip)                     @ jump to next instruction
9501
9502
9503
9504
9505.LOP_EXECUTE_INLINE_table:
9506    .word   PCREL_REF(gDvmInlineOpsTable,5b)
9507
9508/* continuation for OP_EXECUTE_INLINE_RANGE */
9509
9510    /*
9511     * Extract args, call function.
9512     *  r0 = #of args (0-4)
9513     *  r10 = call index
9514     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
9515     */
9516.LOP_EXECUTE_INLINE_RANGE_continue:
9517    rsb     r0, r0, #4                  @ r0<- 4-r0
9518    FETCH(r9, 2)                        @ r9<- CCCC
9519    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
9520    bl      common_abort                @ (skipped due to ARM prefetch)
95214:  add     ip, r9, #3                  @ base+3
9522    GET_VREG(r3, ip)                    @ r3<- vBase[3]
95233:  add     ip, r9, #2                  @ base+2
9524    GET_VREG(r2, ip)                    @ r2<- vBase[2]
95252:  add     ip, r9, #1                  @ base+1
9526    GET_VREG(r1, ip)                    @ r1<- vBase[1]
95271:  add     ip, r9, #0                  @ (nop)
9528    GET_VREG(r0, ip)                    @ r0<- vBase[0]
95290:
9530    ldr     r9, .LOP_EXECUTE_INLINE_RANGE_table       @ table of InlineOperation
95315:  add     r9, pc
9532    ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
9533    @ (not reached)
9534
9535
9536    /*
9537     * We're debugging or profiling.
9538     * r10: opIndex
9539     */
9540.LOP_EXECUTE_INLINE_RANGE_debugmode:
9541    mov     r0, r10
9542    bl      dvmResolveInlineNative
9543    cmp     r0, #0                      @ did it resolve?
9544    beq     .LOP_EXECUTE_INLINE_RANGE_resume          @ no, just move on
9545    mov     r9, r0                      @ remember method
9546    mov     r1, rSELF
9547    bl      dvmFastMethodTraceEnter     @ (method, self)
9548    add     r1, rSELF, #offThread_retval@ r1<- &self->retval
9549    sub     sp, sp, #8                  @ make room for arg, +64 bit align
9550    mov     r0, rINST, lsr #8           @ r0<- B
9551    mov     rINST, r9                   @ rINST<- method
9552    str     r1, [sp]                    @ push &self->retval
9553    bl      .LOP_EXECUTE_INLINE_RANGE_continue        @ make call; will return after
9554    mov     r9, r0                      @ save result of inline
9555    add     sp, sp, #8                  @ pop stack
9556    mov     r0, rINST                   @ r0<- method
9557    mov     r1, rSELF
9558    bl      dvmFastNativeMethodTraceExit  @ (method, self)
9559    cmp     r9, #0                      @ test boolean result of inline
9560    beq     common_exceptionThrown      @ returned false, handle exception
9561    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
9562    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9563    GOTO_OPCODE(ip)                     @ jump to next instruction
9564
9565
9566
9567
9568.LOP_EXECUTE_INLINE_RANGE_table:
9569    .word   PCREL_REF(gDvmInlineOpsTable,5b)
9570
9571
9572/* continuation for OP_INVOKE_OBJECT_INIT_RANGE */
9573
9574.LOP_INVOKE_OBJECT_INIT_RANGE_setFinal:
9575    EXPORT_PC()                         @ can throw
9576    bl      dvmSetFinalizable           @ call dvmSetFinalizable(obj)
9577    ldr     r0, [rSELF, #offThread_exception] @ r0<- self->exception
9578    cmp     r0, #0                      @ exception pending?
9579    bne     common_exceptionThrown      @ yes, handle it
9580    b       .LOP_INVOKE_OBJECT_INIT_RANGE_finish
9581
9582    /*
9583     * A debugger is attached, so we need to go ahead and do
9584     * this.  For simplicity, we'll just jump directly to the
9585     * corresponding handler.  Note that we can't use
9586     * rIBASE here because it may be in single-step mode.
9587     * Load the primary table base directly.
9588     */
9589.LOP_INVOKE_OBJECT_INIT_RANGE_debugger:
9590    ldr     r1, [rSELF, #offThread_mainHandlerTable]
9591    mov     ip, #OP_INVOKE_DIRECT_RANGE
9592    GOTO_OPCODE_BASE(r1,ip)             @ execute it
9593
9594/* continuation for OP_IPUT_OBJECT_VOLATILE */
9595
9596    /*
9597     * Currently:
9598     *  r0 holds resolved field
9599     *  r9 holds object
9600     */
9601.LOP_IPUT_OBJECT_VOLATILE_finish:
9602    @bl      common_squeak0
9603    mov     r1, rINST, lsr #8           @ r1<- A+
9604    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9605    and     r1, r1, #15                 @ r1<- A
9606    cmp     r9, #0                      @ check object for null
9607    GET_VREG(r0, r1)                    @ r0<- fp[A]
9608    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
9609    beq     common_errNullObject        @ object was null
9610    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9611    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9612    SMP_DMB_ST                        @ releasing store
9613    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
9614    SMP_DMB
9615    cmp     r0, #0                      @ stored a null reference?
9616    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
9617    GOTO_OPCODE(ip)                     @ jump to next instruction
9618
9619/* continuation for OP_SGET_OBJECT_VOLATILE */
9620
9621    /*
9622     * Continuation if the field has not yet been resolved.
9623     *  r1:  BBBB field ref
9624     *  r10: dvmDex->pResFields
9625     */
9626.LOP_SGET_OBJECT_VOLATILE_resolve:
9627    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9628#if defined(WITH_JIT)
9629    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9630#endif
9631    EXPORT_PC()                         @ resolve() could throw, so export now
9632    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9633    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9634    cmp     r0, #0                      @ success?
9635    beq     common_exceptionThrown      @ no, handle exception
9636#if defined(WITH_JIT)
9637    /*
9638     * If the JIT is actively building a trace we need to make sure
9639     * that the field is fully resolved before including this instruction.
9640     */
9641    bl      common_verifyField
9642#endif
9643    b       .LOP_SGET_OBJECT_VOLATILE_finish
9644
9645/* continuation for OP_SPUT_OBJECT_VOLATILE */
9646
9647
9648.LOP_SPUT_OBJECT_VOLATILE_end:
9649    str     r1, [r0, #offStaticField_value]  @ field<- vAA
9650    SMP_DMB
9651    cmp     r1, #0                      @ stored a null object?
9652    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
9653    GOTO_OPCODE(ip)                     @ jump to next instruction
9654
9655    /* Continuation if the field has not yet been resolved.
9656     * r1:  BBBB field ref
9657     * r10: dvmDex->pResFields
9658     */
9659.LOP_SPUT_OBJECT_VOLATILE_resolve:
9660    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9661#if defined(WITH_JIT)
9662    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9663#endif
9664    EXPORT_PC()                         @ resolve() could throw, so export now
9665    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9666    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9667    cmp     r0, #0                      @ success?
9668    beq     common_exceptionThrown      @ no, handle exception
9669#if defined(WITH_JIT)
9670    /*
9671     * If the JIT is actively building a trace we need to make sure
9672     * that the field is fully resolved before including this instruction.
9673     */
9674    bl      common_verifyField
9675#endif
9676    b       .LOP_SPUT_OBJECT_VOLATILE_finish          @ resume
9677
9678
9679    .size   dvmAsmSisterStart, .-dvmAsmSisterStart
9680    .global dvmAsmSisterEnd
9681dvmAsmSisterEnd:
9682
9683
9684    .global dvmAsmAltInstructionStart
9685    .type   dvmAsmAltInstructionStart, %function
9686    .text
9687
9688dvmAsmAltInstructionStart = .L_ALT_OP_NOP
9689/* ------------------------------ */
9690    .balign 64
9691.L_ALT_OP_NOP: /* 0x00 */
9692/* File: armv5te/alt_stub.S */
9693/*
9694 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9695 * any interesting requests and then jump to the real instruction
9696 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9697 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9698 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9699 * bail to the real handler if breakFlags==0.
9700 */
9701    ldrb   r3, [rSELF, #offThread_breakFlags]
9702    adrl   lr, dvmAsmInstructionStart + (0 * 64)
9703    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9704    cmp    r3, #0
9705    bxeq   lr                   @ nothing to do - jump to real handler
9706    EXPORT_PC()
9707    mov    r0, rPC              @ arg0
9708    mov    r1, rFP              @ arg1
9709    mov    r2, rSELF            @ arg2
9710    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9711
9712/* ------------------------------ */
9713    .balign 64
9714.L_ALT_OP_MOVE: /* 0x01 */
9715/* File: armv5te/alt_stub.S */
9716/*
9717 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9718 * any interesting requests and then jump to the real instruction
9719 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9720 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9721 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9722 * bail to the real handler if breakFlags==0.
9723 */
9724    ldrb   r3, [rSELF, #offThread_breakFlags]
9725    adrl   lr, dvmAsmInstructionStart + (1 * 64)
9726    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9727    cmp    r3, #0
9728    bxeq   lr                   @ nothing to do - jump to real handler
9729    EXPORT_PC()
9730    mov    r0, rPC              @ arg0
9731    mov    r1, rFP              @ arg1
9732    mov    r2, rSELF            @ arg2
9733    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9734
9735/* ------------------------------ */
9736    .balign 64
9737.L_ALT_OP_MOVE_FROM16: /* 0x02 */
9738/* File: armv5te/alt_stub.S */
9739/*
9740 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9741 * any interesting requests and then jump to the real instruction
9742 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9743 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9744 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9745 * bail to the real handler if breakFlags==0.
9746 */
9747    ldrb   r3, [rSELF, #offThread_breakFlags]
9748    adrl   lr, dvmAsmInstructionStart + (2 * 64)
9749    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9750    cmp    r3, #0
9751    bxeq   lr                   @ nothing to do - jump to real handler
9752    EXPORT_PC()
9753    mov    r0, rPC              @ arg0
9754    mov    r1, rFP              @ arg1
9755    mov    r2, rSELF            @ arg2
9756    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9757
9758/* ------------------------------ */
9759    .balign 64
9760.L_ALT_OP_MOVE_16: /* 0x03 */
9761/* File: armv5te/alt_stub.S */
9762/*
9763 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9764 * any interesting requests and then jump to the real instruction
9765 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9766 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9767 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9768 * bail to the real handler if breakFlags==0.
9769 */
9770    ldrb   r3, [rSELF, #offThread_breakFlags]
9771    adrl   lr, dvmAsmInstructionStart + (3 * 64)
9772    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9773    cmp    r3, #0
9774    bxeq   lr                   @ nothing to do - jump to real handler
9775    EXPORT_PC()
9776    mov    r0, rPC              @ arg0
9777    mov    r1, rFP              @ arg1
9778    mov    r2, rSELF            @ arg2
9779    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9780
9781/* ------------------------------ */
9782    .balign 64
9783.L_ALT_OP_MOVE_WIDE: /* 0x04 */
9784/* File: armv5te/alt_stub.S */
9785/*
9786 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9787 * any interesting requests and then jump to the real instruction
9788 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9789 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9790 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9791 * bail to the real handler if breakFlags==0.
9792 */
9793    ldrb   r3, [rSELF, #offThread_breakFlags]
9794    adrl   lr, dvmAsmInstructionStart + (4 * 64)
9795    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9796    cmp    r3, #0
9797    bxeq   lr                   @ nothing to do - jump to real handler
9798    EXPORT_PC()
9799    mov    r0, rPC              @ arg0
9800    mov    r1, rFP              @ arg1
9801    mov    r2, rSELF            @ arg2
9802    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9803
9804/* ------------------------------ */
9805    .balign 64
9806.L_ALT_OP_MOVE_WIDE_FROM16: /* 0x05 */
9807/* File: armv5te/alt_stub.S */
9808/*
9809 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9810 * any interesting requests and then jump to the real instruction
9811 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9812 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9813 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9814 * bail to the real handler if breakFlags==0.
9815 */
9816    ldrb   r3, [rSELF, #offThread_breakFlags]
9817    adrl   lr, dvmAsmInstructionStart + (5 * 64)
9818    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9819    cmp    r3, #0
9820    bxeq   lr                   @ nothing to do - jump to real handler
9821    EXPORT_PC()
9822    mov    r0, rPC              @ arg0
9823    mov    r1, rFP              @ arg1
9824    mov    r2, rSELF            @ arg2
9825    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9826
9827/* ------------------------------ */
9828    .balign 64
9829.L_ALT_OP_MOVE_WIDE_16: /* 0x06 */
9830/* File: armv5te/alt_stub.S */
9831/*
9832 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9833 * any interesting requests and then jump to the real instruction
9834 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9835 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9836 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9837 * bail to the real handler if breakFlags==0.
9838 */
9839    ldrb   r3, [rSELF, #offThread_breakFlags]
9840    adrl   lr, dvmAsmInstructionStart + (6 * 64)
9841    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9842    cmp    r3, #0
9843    bxeq   lr                   @ nothing to do - jump to real handler
9844    EXPORT_PC()
9845    mov    r0, rPC              @ arg0
9846    mov    r1, rFP              @ arg1
9847    mov    r2, rSELF            @ arg2
9848    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9849
9850/* ------------------------------ */
9851    .balign 64
9852.L_ALT_OP_MOVE_OBJECT: /* 0x07 */
9853/* File: armv5te/alt_stub.S */
9854/*
9855 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9856 * any interesting requests and then jump to the real instruction
9857 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9858 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9859 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9860 * bail to the real handler if breakFlags==0.
9861 */
9862    ldrb   r3, [rSELF, #offThread_breakFlags]
9863    adrl   lr, dvmAsmInstructionStart + (7 * 64)
9864    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9865    cmp    r3, #0
9866    bxeq   lr                   @ nothing to do - jump to real handler
9867    EXPORT_PC()
9868    mov    r0, rPC              @ arg0
9869    mov    r1, rFP              @ arg1
9870    mov    r2, rSELF            @ arg2
9871    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9872
9873/* ------------------------------ */
9874    .balign 64
9875.L_ALT_OP_MOVE_OBJECT_FROM16: /* 0x08 */
9876/* File: armv5te/alt_stub.S */
9877/*
9878 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9879 * any interesting requests and then jump to the real instruction
9880 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9881 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9882 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9883 * bail to the real handler if breakFlags==0.
9884 */
9885    ldrb   r3, [rSELF, #offThread_breakFlags]
9886    adrl   lr, dvmAsmInstructionStart + (8 * 64)
9887    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9888    cmp    r3, #0
9889    bxeq   lr                   @ nothing to do - jump to real handler
9890    EXPORT_PC()
9891    mov    r0, rPC              @ arg0
9892    mov    r1, rFP              @ arg1
9893    mov    r2, rSELF            @ arg2
9894    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9895
9896/* ------------------------------ */
9897    .balign 64
9898.L_ALT_OP_MOVE_OBJECT_16: /* 0x09 */
9899/* File: armv5te/alt_stub.S */
9900/*
9901 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9902 * any interesting requests and then jump to the real instruction
9903 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9904 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9905 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9906 * bail to the real handler if breakFlags==0.
9907 */
9908    ldrb   r3, [rSELF, #offThread_breakFlags]
9909    adrl   lr, dvmAsmInstructionStart + (9 * 64)
9910    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9911    cmp    r3, #0
9912    bxeq   lr                   @ nothing to do - jump to real handler
9913    EXPORT_PC()
9914    mov    r0, rPC              @ arg0
9915    mov    r1, rFP              @ arg1
9916    mov    r2, rSELF            @ arg2
9917    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9918
9919/* ------------------------------ */
9920    .balign 64
9921.L_ALT_OP_MOVE_RESULT: /* 0x0a */
9922/* File: armv5te/alt_stub.S */
9923/*
9924 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9925 * any interesting requests and then jump to the real instruction
9926 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9927 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9928 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9929 * bail to the real handler if breakFlags==0.
9930 */
9931    ldrb   r3, [rSELF, #offThread_breakFlags]
9932    adrl   lr, dvmAsmInstructionStart + (10 * 64)
9933    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9934    cmp    r3, #0
9935    bxeq   lr                   @ nothing to do - jump to real handler
9936    EXPORT_PC()
9937    mov    r0, rPC              @ arg0
9938    mov    r1, rFP              @ arg1
9939    mov    r2, rSELF            @ arg2
9940    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9941
9942/* ------------------------------ */
9943    .balign 64
9944.L_ALT_OP_MOVE_RESULT_WIDE: /* 0x0b */
9945/* File: armv5te/alt_stub.S */
9946/*
9947 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9948 * any interesting requests and then jump to the real instruction
9949 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9950 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9951 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9952 * bail to the real handler if breakFlags==0.
9953 */
9954    ldrb   r3, [rSELF, #offThread_breakFlags]
9955    adrl   lr, dvmAsmInstructionStart + (11 * 64)
9956    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9957    cmp    r3, #0
9958    bxeq   lr                   @ nothing to do - jump to real handler
9959    EXPORT_PC()
9960    mov    r0, rPC              @ arg0
9961    mov    r1, rFP              @ arg1
9962    mov    r2, rSELF            @ arg2
9963    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9964
9965/* ------------------------------ */
9966    .balign 64
9967.L_ALT_OP_MOVE_RESULT_OBJECT: /* 0x0c */
9968/* File: armv5te/alt_stub.S */
9969/*
9970 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9971 * any interesting requests and then jump to the real instruction
9972 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9973 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9974 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9975 * bail to the real handler if breakFlags==0.
9976 */
9977    ldrb   r3, [rSELF, #offThread_breakFlags]
9978    adrl   lr, dvmAsmInstructionStart + (12 * 64)
9979    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9980    cmp    r3, #0
9981    bxeq   lr                   @ nothing to do - jump to real handler
9982    EXPORT_PC()
9983    mov    r0, rPC              @ arg0
9984    mov    r1, rFP              @ arg1
9985    mov    r2, rSELF            @ arg2
9986    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9987
9988/* ------------------------------ */
9989    .balign 64
9990.L_ALT_OP_MOVE_EXCEPTION: /* 0x0d */
9991/* File: armv5te/alt_stub.S */
9992/*
9993 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9994 * any interesting requests and then jump to the real instruction
9995 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9996 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9997 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9998 * bail to the real handler if breakFlags==0.
9999 */
10000    ldrb   r3, [rSELF, #offThread_breakFlags]
10001    adrl   lr, dvmAsmInstructionStart + (13 * 64)
10002    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10003    cmp    r3, #0
10004    bxeq   lr                   @ nothing to do - jump to real handler
10005    EXPORT_PC()
10006    mov    r0, rPC              @ arg0
10007    mov    r1, rFP              @ arg1
10008    mov    r2, rSELF            @ arg2
10009    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10010
10011/* ------------------------------ */
10012    .balign 64
10013.L_ALT_OP_RETURN_VOID: /* 0x0e */
10014/* File: armv5te/alt_stub.S */
10015/*
10016 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10017 * any interesting requests and then jump to the real instruction
10018 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10019 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10020 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10021 * bail to the real handler if breakFlags==0.
10022 */
10023    ldrb   r3, [rSELF, #offThread_breakFlags]
10024    adrl   lr, dvmAsmInstructionStart + (14 * 64)
10025    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10026    cmp    r3, #0
10027    bxeq   lr                   @ nothing to do - jump to real handler
10028    EXPORT_PC()
10029    mov    r0, rPC              @ arg0
10030    mov    r1, rFP              @ arg1
10031    mov    r2, rSELF            @ arg2
10032    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10033
10034/* ------------------------------ */
10035    .balign 64
10036.L_ALT_OP_RETURN: /* 0x0f */
10037/* File: armv5te/alt_stub.S */
10038/*
10039 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10040 * any interesting requests and then jump to the real instruction
10041 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10042 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10043 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10044 * bail to the real handler if breakFlags==0.
10045 */
10046    ldrb   r3, [rSELF, #offThread_breakFlags]
10047    adrl   lr, dvmAsmInstructionStart + (15 * 64)
10048    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10049    cmp    r3, #0
10050    bxeq   lr                   @ nothing to do - jump to real handler
10051    EXPORT_PC()
10052    mov    r0, rPC              @ arg0
10053    mov    r1, rFP              @ arg1
10054    mov    r2, rSELF            @ arg2
10055    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10056
10057/* ------------------------------ */
10058    .balign 64
10059.L_ALT_OP_RETURN_WIDE: /* 0x10 */
10060/* File: armv5te/alt_stub.S */
10061/*
10062 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10063 * any interesting requests and then jump to the real instruction
10064 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10065 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10066 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10067 * bail to the real handler if breakFlags==0.
10068 */
10069    ldrb   r3, [rSELF, #offThread_breakFlags]
10070    adrl   lr, dvmAsmInstructionStart + (16 * 64)
10071    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10072    cmp    r3, #0
10073    bxeq   lr                   @ nothing to do - jump to real handler
10074    EXPORT_PC()
10075    mov    r0, rPC              @ arg0
10076    mov    r1, rFP              @ arg1
10077    mov    r2, rSELF            @ arg2
10078    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10079
10080/* ------------------------------ */
10081    .balign 64
10082.L_ALT_OP_RETURN_OBJECT: /* 0x11 */
10083/* File: armv5te/alt_stub.S */
10084/*
10085 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10086 * any interesting requests and then jump to the real instruction
10087 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10088 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10089 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10090 * bail to the real handler if breakFlags==0.
10091 */
10092    ldrb   r3, [rSELF, #offThread_breakFlags]
10093    adrl   lr, dvmAsmInstructionStart + (17 * 64)
10094    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10095    cmp    r3, #0
10096    bxeq   lr                   @ nothing to do - jump to real handler
10097    EXPORT_PC()
10098    mov    r0, rPC              @ arg0
10099    mov    r1, rFP              @ arg1
10100    mov    r2, rSELF            @ arg2
10101    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10102
10103/* ------------------------------ */
10104    .balign 64
10105.L_ALT_OP_CONST_4: /* 0x12 */
10106/* File: armv5te/alt_stub.S */
10107/*
10108 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10109 * any interesting requests and then jump to the real instruction
10110 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10111 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10112 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10113 * bail to the real handler if breakFlags==0.
10114 */
10115    ldrb   r3, [rSELF, #offThread_breakFlags]
10116    adrl   lr, dvmAsmInstructionStart + (18 * 64)
10117    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10118    cmp    r3, #0
10119    bxeq   lr                   @ nothing to do - jump to real handler
10120    EXPORT_PC()
10121    mov    r0, rPC              @ arg0
10122    mov    r1, rFP              @ arg1
10123    mov    r2, rSELF            @ arg2
10124    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10125
10126/* ------------------------------ */
10127    .balign 64
10128.L_ALT_OP_CONST_16: /* 0x13 */
10129/* File: armv5te/alt_stub.S */
10130/*
10131 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10132 * any interesting requests and then jump to the real instruction
10133 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10134 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10135 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10136 * bail to the real handler if breakFlags==0.
10137 */
10138    ldrb   r3, [rSELF, #offThread_breakFlags]
10139    adrl   lr, dvmAsmInstructionStart + (19 * 64)
10140    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10141    cmp    r3, #0
10142    bxeq   lr                   @ nothing to do - jump to real handler
10143    EXPORT_PC()
10144    mov    r0, rPC              @ arg0
10145    mov    r1, rFP              @ arg1
10146    mov    r2, rSELF            @ arg2
10147    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10148
10149/* ------------------------------ */
10150    .balign 64
10151.L_ALT_OP_CONST: /* 0x14 */
10152/* File: armv5te/alt_stub.S */
10153/*
10154 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10155 * any interesting requests and then jump to the real instruction
10156 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10157 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10158 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10159 * bail to the real handler if breakFlags==0.
10160 */
10161    ldrb   r3, [rSELF, #offThread_breakFlags]
10162    adrl   lr, dvmAsmInstructionStart + (20 * 64)
10163    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10164    cmp    r3, #0
10165    bxeq   lr                   @ nothing to do - jump to real handler
10166    EXPORT_PC()
10167    mov    r0, rPC              @ arg0
10168    mov    r1, rFP              @ arg1
10169    mov    r2, rSELF            @ arg2
10170    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10171
10172/* ------------------------------ */
10173    .balign 64
10174.L_ALT_OP_CONST_HIGH16: /* 0x15 */
10175/* File: armv5te/alt_stub.S */
10176/*
10177 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10178 * any interesting requests and then jump to the real instruction
10179 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10180 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10181 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10182 * bail to the real handler if breakFlags==0.
10183 */
10184    ldrb   r3, [rSELF, #offThread_breakFlags]
10185    adrl   lr, dvmAsmInstructionStart + (21 * 64)
10186    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10187    cmp    r3, #0
10188    bxeq   lr                   @ nothing to do - jump to real handler
10189    EXPORT_PC()
10190    mov    r0, rPC              @ arg0
10191    mov    r1, rFP              @ arg1
10192    mov    r2, rSELF            @ arg2
10193    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10194
10195/* ------------------------------ */
10196    .balign 64
10197.L_ALT_OP_CONST_WIDE_16: /* 0x16 */
10198/* File: armv5te/alt_stub.S */
10199/*
10200 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10201 * any interesting requests and then jump to the real instruction
10202 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10203 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10204 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10205 * bail to the real handler if breakFlags==0.
10206 */
10207    ldrb   r3, [rSELF, #offThread_breakFlags]
10208    adrl   lr, dvmAsmInstructionStart + (22 * 64)
10209    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10210    cmp    r3, #0
10211    bxeq   lr                   @ nothing to do - jump to real handler
10212    EXPORT_PC()
10213    mov    r0, rPC              @ arg0
10214    mov    r1, rFP              @ arg1
10215    mov    r2, rSELF            @ arg2
10216    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10217
10218/* ------------------------------ */
10219    .balign 64
10220.L_ALT_OP_CONST_WIDE_32: /* 0x17 */
10221/* File: armv5te/alt_stub.S */
10222/*
10223 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10224 * any interesting requests and then jump to the real instruction
10225 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10226 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10227 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10228 * bail to the real handler if breakFlags==0.
10229 */
10230    ldrb   r3, [rSELF, #offThread_breakFlags]
10231    adrl   lr, dvmAsmInstructionStart + (23 * 64)
10232    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10233    cmp    r3, #0
10234    bxeq   lr                   @ nothing to do - jump to real handler
10235    EXPORT_PC()
10236    mov    r0, rPC              @ arg0
10237    mov    r1, rFP              @ arg1
10238    mov    r2, rSELF            @ arg2
10239    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10240
10241/* ------------------------------ */
10242    .balign 64
10243.L_ALT_OP_CONST_WIDE: /* 0x18 */
10244/* File: armv5te/alt_stub.S */
10245/*
10246 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10247 * any interesting requests and then jump to the real instruction
10248 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10249 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10250 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10251 * bail to the real handler if breakFlags==0.
10252 */
10253    ldrb   r3, [rSELF, #offThread_breakFlags]
10254    adrl   lr, dvmAsmInstructionStart + (24 * 64)
10255    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10256    cmp    r3, #0
10257    bxeq   lr                   @ nothing to do - jump to real handler
10258    EXPORT_PC()
10259    mov    r0, rPC              @ arg0
10260    mov    r1, rFP              @ arg1
10261    mov    r2, rSELF            @ arg2
10262    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10263
10264/* ------------------------------ */
10265    .balign 64
10266.L_ALT_OP_CONST_WIDE_HIGH16: /* 0x19 */
10267/* File: armv5te/alt_stub.S */
10268/*
10269 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10270 * any interesting requests and then jump to the real instruction
10271 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10272 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10273 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10274 * bail to the real handler if breakFlags==0.
10275 */
10276    ldrb   r3, [rSELF, #offThread_breakFlags]
10277    adrl   lr, dvmAsmInstructionStart + (25 * 64)
10278    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10279    cmp    r3, #0
10280    bxeq   lr                   @ nothing to do - jump to real handler
10281    EXPORT_PC()
10282    mov    r0, rPC              @ arg0
10283    mov    r1, rFP              @ arg1
10284    mov    r2, rSELF            @ arg2
10285    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10286
10287/* ------------------------------ */
10288    .balign 64
10289.L_ALT_OP_CONST_STRING: /* 0x1a */
10290/* File: armv5te/alt_stub.S */
10291/*
10292 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10293 * any interesting requests and then jump to the real instruction
10294 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10295 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10296 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10297 * bail to the real handler if breakFlags==0.
10298 */
10299    ldrb   r3, [rSELF, #offThread_breakFlags]
10300    adrl   lr, dvmAsmInstructionStart + (26 * 64)
10301    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10302    cmp    r3, #0
10303    bxeq   lr                   @ nothing to do - jump to real handler
10304    EXPORT_PC()
10305    mov    r0, rPC              @ arg0
10306    mov    r1, rFP              @ arg1
10307    mov    r2, rSELF            @ arg2
10308    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10309
10310/* ------------------------------ */
10311    .balign 64
10312.L_ALT_OP_CONST_STRING_JUMBO: /* 0x1b */
10313/* File: armv5te/alt_stub.S */
10314/*
10315 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10316 * any interesting requests and then jump to the real instruction
10317 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10318 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10319 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10320 * bail to the real handler if breakFlags==0.
10321 */
10322    ldrb   r3, [rSELF, #offThread_breakFlags]
10323    adrl   lr, dvmAsmInstructionStart + (27 * 64)
10324    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10325    cmp    r3, #0
10326    bxeq   lr                   @ nothing to do - jump to real handler
10327    EXPORT_PC()
10328    mov    r0, rPC              @ arg0
10329    mov    r1, rFP              @ arg1
10330    mov    r2, rSELF            @ arg2
10331    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10332
10333/* ------------------------------ */
10334    .balign 64
10335.L_ALT_OP_CONST_CLASS: /* 0x1c */
10336/* File: armv5te/alt_stub.S */
10337/*
10338 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10339 * any interesting requests and then jump to the real instruction
10340 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10341 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10342 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10343 * bail to the real handler if breakFlags==0.
10344 */
10345    ldrb   r3, [rSELF, #offThread_breakFlags]
10346    adrl   lr, dvmAsmInstructionStart + (28 * 64)
10347    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10348    cmp    r3, #0
10349    bxeq   lr                   @ nothing to do - jump to real handler
10350    EXPORT_PC()
10351    mov    r0, rPC              @ arg0
10352    mov    r1, rFP              @ arg1
10353    mov    r2, rSELF            @ arg2
10354    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10355
10356/* ------------------------------ */
10357    .balign 64
10358.L_ALT_OP_MONITOR_ENTER: /* 0x1d */
10359/* File: armv5te/alt_stub.S */
10360/*
10361 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10362 * any interesting requests and then jump to the real instruction
10363 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10364 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10365 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10366 * bail to the real handler if breakFlags==0.
10367 */
10368    ldrb   r3, [rSELF, #offThread_breakFlags]
10369    adrl   lr, dvmAsmInstructionStart + (29 * 64)
10370    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10371    cmp    r3, #0
10372    bxeq   lr                   @ nothing to do - jump to real handler
10373    EXPORT_PC()
10374    mov    r0, rPC              @ arg0
10375    mov    r1, rFP              @ arg1
10376    mov    r2, rSELF            @ arg2
10377    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10378
10379/* ------------------------------ */
10380    .balign 64
10381.L_ALT_OP_MONITOR_EXIT: /* 0x1e */
10382/* File: armv5te/alt_stub.S */
10383/*
10384 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10385 * any interesting requests and then jump to the real instruction
10386 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10387 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10388 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10389 * bail to the real handler if breakFlags==0.
10390 */
10391    ldrb   r3, [rSELF, #offThread_breakFlags]
10392    adrl   lr, dvmAsmInstructionStart + (30 * 64)
10393    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10394    cmp    r3, #0
10395    bxeq   lr                   @ nothing to do - jump to real handler
10396    EXPORT_PC()
10397    mov    r0, rPC              @ arg0
10398    mov    r1, rFP              @ arg1
10399    mov    r2, rSELF            @ arg2
10400    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10401
10402/* ------------------------------ */
10403    .balign 64
10404.L_ALT_OP_CHECK_CAST: /* 0x1f */
10405/* File: armv5te/alt_stub.S */
10406/*
10407 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10408 * any interesting requests and then jump to the real instruction
10409 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10410 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10411 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10412 * bail to the real handler if breakFlags==0.
10413 */
10414    ldrb   r3, [rSELF, #offThread_breakFlags]
10415    adrl   lr, dvmAsmInstructionStart + (31 * 64)
10416    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10417    cmp    r3, #0
10418    bxeq   lr                   @ nothing to do - jump to real handler
10419    EXPORT_PC()
10420    mov    r0, rPC              @ arg0
10421    mov    r1, rFP              @ arg1
10422    mov    r2, rSELF            @ arg2
10423    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10424
10425/* ------------------------------ */
10426    .balign 64
10427.L_ALT_OP_INSTANCE_OF: /* 0x20 */
10428/* File: armv5te/alt_stub.S */
10429/*
10430 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10431 * any interesting requests and then jump to the real instruction
10432 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10433 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10434 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10435 * bail to the real handler if breakFlags==0.
10436 */
10437    ldrb   r3, [rSELF, #offThread_breakFlags]
10438    adrl   lr, dvmAsmInstructionStart + (32 * 64)
10439    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10440    cmp    r3, #0
10441    bxeq   lr                   @ nothing to do - jump to real handler
10442    EXPORT_PC()
10443    mov    r0, rPC              @ arg0
10444    mov    r1, rFP              @ arg1
10445    mov    r2, rSELF            @ arg2
10446    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10447
10448/* ------------------------------ */
10449    .balign 64
10450.L_ALT_OP_ARRAY_LENGTH: /* 0x21 */
10451/* File: armv5te/alt_stub.S */
10452/*
10453 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10454 * any interesting requests and then jump to the real instruction
10455 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10456 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10457 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10458 * bail to the real handler if breakFlags==0.
10459 */
10460    ldrb   r3, [rSELF, #offThread_breakFlags]
10461    adrl   lr, dvmAsmInstructionStart + (33 * 64)
10462    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10463    cmp    r3, #0
10464    bxeq   lr                   @ nothing to do - jump to real handler
10465    EXPORT_PC()
10466    mov    r0, rPC              @ arg0
10467    mov    r1, rFP              @ arg1
10468    mov    r2, rSELF            @ arg2
10469    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10470
10471/* ------------------------------ */
10472    .balign 64
10473.L_ALT_OP_NEW_INSTANCE: /* 0x22 */
10474/* File: armv5te/alt_stub.S */
10475/*
10476 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10477 * any interesting requests and then jump to the real instruction
10478 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10479 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10480 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10481 * bail to the real handler if breakFlags==0.
10482 */
10483    ldrb   r3, [rSELF, #offThread_breakFlags]
10484    adrl   lr, dvmAsmInstructionStart + (34 * 64)
10485    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10486    cmp    r3, #0
10487    bxeq   lr                   @ nothing to do - jump to real handler
10488    EXPORT_PC()
10489    mov    r0, rPC              @ arg0
10490    mov    r1, rFP              @ arg1
10491    mov    r2, rSELF            @ arg2
10492    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10493
10494/* ------------------------------ */
10495    .balign 64
10496.L_ALT_OP_NEW_ARRAY: /* 0x23 */
10497/* File: armv5te/alt_stub.S */
10498/*
10499 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10500 * any interesting requests and then jump to the real instruction
10501 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10502 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10503 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10504 * bail to the real handler if breakFlags==0.
10505 */
10506    ldrb   r3, [rSELF, #offThread_breakFlags]
10507    adrl   lr, dvmAsmInstructionStart + (35 * 64)
10508    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10509    cmp    r3, #0
10510    bxeq   lr                   @ nothing to do - jump to real handler
10511    EXPORT_PC()
10512    mov    r0, rPC              @ arg0
10513    mov    r1, rFP              @ arg1
10514    mov    r2, rSELF            @ arg2
10515    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10516
10517/* ------------------------------ */
10518    .balign 64
10519.L_ALT_OP_FILLED_NEW_ARRAY: /* 0x24 */
10520/* File: armv5te/alt_stub.S */
10521/*
10522 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10523 * any interesting requests and then jump to the real instruction
10524 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10525 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10526 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10527 * bail to the real handler if breakFlags==0.
10528 */
10529    ldrb   r3, [rSELF, #offThread_breakFlags]
10530    adrl   lr, dvmAsmInstructionStart + (36 * 64)
10531    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10532    cmp    r3, #0
10533    bxeq   lr                   @ nothing to do - jump to real handler
10534    EXPORT_PC()
10535    mov    r0, rPC              @ arg0
10536    mov    r1, rFP              @ arg1
10537    mov    r2, rSELF            @ arg2
10538    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10539
10540/* ------------------------------ */
10541    .balign 64
10542.L_ALT_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
10543/* File: armv5te/alt_stub.S */
10544/*
10545 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10546 * any interesting requests and then jump to the real instruction
10547 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10548 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10549 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10550 * bail to the real handler if breakFlags==0.
10551 */
10552    ldrb   r3, [rSELF, #offThread_breakFlags]
10553    adrl   lr, dvmAsmInstructionStart + (37 * 64)
10554    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10555    cmp    r3, #0
10556    bxeq   lr                   @ nothing to do - jump to real handler
10557    EXPORT_PC()
10558    mov    r0, rPC              @ arg0
10559    mov    r1, rFP              @ arg1
10560    mov    r2, rSELF            @ arg2
10561    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10562
10563/* ------------------------------ */
10564    .balign 64
10565.L_ALT_OP_FILL_ARRAY_DATA: /* 0x26 */
10566/* File: armv5te/alt_stub.S */
10567/*
10568 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10569 * any interesting requests and then jump to the real instruction
10570 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10571 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10572 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10573 * bail to the real handler if breakFlags==0.
10574 */
10575    ldrb   r3, [rSELF, #offThread_breakFlags]
10576    adrl   lr, dvmAsmInstructionStart + (38 * 64)
10577    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10578    cmp    r3, #0
10579    bxeq   lr                   @ nothing to do - jump to real handler
10580    EXPORT_PC()
10581    mov    r0, rPC              @ arg0
10582    mov    r1, rFP              @ arg1
10583    mov    r2, rSELF            @ arg2
10584    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10585
10586/* ------------------------------ */
10587    .balign 64
10588.L_ALT_OP_THROW: /* 0x27 */
10589/* File: armv5te/alt_stub.S */
10590/*
10591 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10592 * any interesting requests and then jump to the real instruction
10593 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10594 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10595 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10596 * bail to the real handler if breakFlags==0.
10597 */
10598    ldrb   r3, [rSELF, #offThread_breakFlags]
10599    adrl   lr, dvmAsmInstructionStart + (39 * 64)
10600    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10601    cmp    r3, #0
10602    bxeq   lr                   @ nothing to do - jump to real handler
10603    EXPORT_PC()
10604    mov    r0, rPC              @ arg0
10605    mov    r1, rFP              @ arg1
10606    mov    r2, rSELF            @ arg2
10607    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10608
10609/* ------------------------------ */
10610    .balign 64
10611.L_ALT_OP_GOTO: /* 0x28 */
10612/* File: armv5te/alt_stub.S */
10613/*
10614 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10615 * any interesting requests and then jump to the real instruction
10616 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10617 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10618 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10619 * bail to the real handler if breakFlags==0.
10620 */
10621    ldrb   r3, [rSELF, #offThread_breakFlags]
10622    adrl   lr, dvmAsmInstructionStart + (40 * 64)
10623    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10624    cmp    r3, #0
10625    bxeq   lr                   @ nothing to do - jump to real handler
10626    EXPORT_PC()
10627    mov    r0, rPC              @ arg0
10628    mov    r1, rFP              @ arg1
10629    mov    r2, rSELF            @ arg2
10630    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10631
10632/* ------------------------------ */
10633    .balign 64
10634.L_ALT_OP_GOTO_16: /* 0x29 */
10635/* File: armv5te/alt_stub.S */
10636/*
10637 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10638 * any interesting requests and then jump to the real instruction
10639 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10640 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10641 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10642 * bail to the real handler if breakFlags==0.
10643 */
10644    ldrb   r3, [rSELF, #offThread_breakFlags]
10645    adrl   lr, dvmAsmInstructionStart + (41 * 64)
10646    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10647    cmp    r3, #0
10648    bxeq   lr                   @ nothing to do - jump to real handler
10649    EXPORT_PC()
10650    mov    r0, rPC              @ arg0
10651    mov    r1, rFP              @ arg1
10652    mov    r2, rSELF            @ arg2
10653    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10654
10655/* ------------------------------ */
10656    .balign 64
10657.L_ALT_OP_GOTO_32: /* 0x2a */
10658/* File: armv5te/alt_stub.S */
10659/*
10660 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10661 * any interesting requests and then jump to the real instruction
10662 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10663 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10664 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10665 * bail to the real handler if breakFlags==0.
10666 */
10667    ldrb   r3, [rSELF, #offThread_breakFlags]
10668    adrl   lr, dvmAsmInstructionStart + (42 * 64)
10669    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10670    cmp    r3, #0
10671    bxeq   lr                   @ nothing to do - jump to real handler
10672    EXPORT_PC()
10673    mov    r0, rPC              @ arg0
10674    mov    r1, rFP              @ arg1
10675    mov    r2, rSELF            @ arg2
10676    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10677
10678/* ------------------------------ */
10679    .balign 64
10680.L_ALT_OP_PACKED_SWITCH: /* 0x2b */
10681/* File: armv5te/alt_stub.S */
10682/*
10683 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10684 * any interesting requests and then jump to the real instruction
10685 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10686 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10687 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10688 * bail to the real handler if breakFlags==0.
10689 */
10690    ldrb   r3, [rSELF, #offThread_breakFlags]
10691    adrl   lr, dvmAsmInstructionStart + (43 * 64)
10692    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10693    cmp    r3, #0
10694    bxeq   lr                   @ nothing to do - jump to real handler
10695    EXPORT_PC()
10696    mov    r0, rPC              @ arg0
10697    mov    r1, rFP              @ arg1
10698    mov    r2, rSELF            @ arg2
10699    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10700
10701/* ------------------------------ */
10702    .balign 64
10703.L_ALT_OP_SPARSE_SWITCH: /* 0x2c */
10704/* File: armv5te/alt_stub.S */
10705/*
10706 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10707 * any interesting requests and then jump to the real instruction
10708 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10709 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10710 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10711 * bail to the real handler if breakFlags==0.
10712 */
10713    ldrb   r3, [rSELF, #offThread_breakFlags]
10714    adrl   lr, dvmAsmInstructionStart + (44 * 64)
10715    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10716    cmp    r3, #0
10717    bxeq   lr                   @ nothing to do - jump to real handler
10718    EXPORT_PC()
10719    mov    r0, rPC              @ arg0
10720    mov    r1, rFP              @ arg1
10721    mov    r2, rSELF            @ arg2
10722    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10723
10724/* ------------------------------ */
10725    .balign 64
10726.L_ALT_OP_CMPL_FLOAT: /* 0x2d */
10727/* File: armv5te/alt_stub.S */
10728/*
10729 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10730 * any interesting requests and then jump to the real instruction
10731 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10732 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10733 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10734 * bail to the real handler if breakFlags==0.
10735 */
10736    ldrb   r3, [rSELF, #offThread_breakFlags]
10737    adrl   lr, dvmAsmInstructionStart + (45 * 64)
10738    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10739    cmp    r3, #0
10740    bxeq   lr                   @ nothing to do - jump to real handler
10741    EXPORT_PC()
10742    mov    r0, rPC              @ arg0
10743    mov    r1, rFP              @ arg1
10744    mov    r2, rSELF            @ arg2
10745    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10746
10747/* ------------------------------ */
10748    .balign 64
10749.L_ALT_OP_CMPG_FLOAT: /* 0x2e */
10750/* File: armv5te/alt_stub.S */
10751/*
10752 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10753 * any interesting requests and then jump to the real instruction
10754 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10755 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10756 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10757 * bail to the real handler if breakFlags==0.
10758 */
10759    ldrb   r3, [rSELF, #offThread_breakFlags]
10760    adrl   lr, dvmAsmInstructionStart + (46 * 64)
10761    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10762    cmp    r3, #0
10763    bxeq   lr                   @ nothing to do - jump to real handler
10764    EXPORT_PC()
10765    mov    r0, rPC              @ arg0
10766    mov    r1, rFP              @ arg1
10767    mov    r2, rSELF            @ arg2
10768    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10769
10770/* ------------------------------ */
10771    .balign 64
10772.L_ALT_OP_CMPL_DOUBLE: /* 0x2f */
10773/* File: armv5te/alt_stub.S */
10774/*
10775 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10776 * any interesting requests and then jump to the real instruction
10777 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10778 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10779 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10780 * bail to the real handler if breakFlags==0.
10781 */
10782    ldrb   r3, [rSELF, #offThread_breakFlags]
10783    adrl   lr, dvmAsmInstructionStart + (47 * 64)
10784    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10785    cmp    r3, #0
10786    bxeq   lr                   @ nothing to do - jump to real handler
10787    EXPORT_PC()
10788    mov    r0, rPC              @ arg0
10789    mov    r1, rFP              @ arg1
10790    mov    r2, rSELF            @ arg2
10791    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10792
10793/* ------------------------------ */
10794    .balign 64
10795.L_ALT_OP_CMPG_DOUBLE: /* 0x30 */
10796/* File: armv5te/alt_stub.S */
10797/*
10798 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10799 * any interesting requests and then jump to the real instruction
10800 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10801 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10802 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10803 * bail to the real handler if breakFlags==0.
10804 */
10805    ldrb   r3, [rSELF, #offThread_breakFlags]
10806    adrl   lr, dvmAsmInstructionStart + (48 * 64)
10807    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10808    cmp    r3, #0
10809    bxeq   lr                   @ nothing to do - jump to real handler
10810    EXPORT_PC()
10811    mov    r0, rPC              @ arg0
10812    mov    r1, rFP              @ arg1
10813    mov    r2, rSELF            @ arg2
10814    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10815
10816/* ------------------------------ */
10817    .balign 64
10818.L_ALT_OP_CMP_LONG: /* 0x31 */
10819/* File: armv5te/alt_stub.S */
10820/*
10821 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10822 * any interesting requests and then jump to the real instruction
10823 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10824 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10825 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10826 * bail to the real handler if breakFlags==0.
10827 */
10828    ldrb   r3, [rSELF, #offThread_breakFlags]
10829    adrl   lr, dvmAsmInstructionStart + (49 * 64)
10830    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10831    cmp    r3, #0
10832    bxeq   lr                   @ nothing to do - jump to real handler
10833    EXPORT_PC()
10834    mov    r0, rPC              @ arg0
10835    mov    r1, rFP              @ arg1
10836    mov    r2, rSELF            @ arg2
10837    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10838
10839/* ------------------------------ */
10840    .balign 64
10841.L_ALT_OP_IF_EQ: /* 0x32 */
10842/* File: armv5te/alt_stub.S */
10843/*
10844 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10845 * any interesting requests and then jump to the real instruction
10846 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10847 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10848 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10849 * bail to the real handler if breakFlags==0.
10850 */
10851    ldrb   r3, [rSELF, #offThread_breakFlags]
10852    adrl   lr, dvmAsmInstructionStart + (50 * 64)
10853    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10854    cmp    r3, #0
10855    bxeq   lr                   @ nothing to do - jump to real handler
10856    EXPORT_PC()
10857    mov    r0, rPC              @ arg0
10858    mov    r1, rFP              @ arg1
10859    mov    r2, rSELF            @ arg2
10860    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10861
10862/* ------------------------------ */
10863    .balign 64
10864.L_ALT_OP_IF_NE: /* 0x33 */
10865/* File: armv5te/alt_stub.S */
10866/*
10867 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10868 * any interesting requests and then jump to the real instruction
10869 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10870 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10871 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10872 * bail to the real handler if breakFlags==0.
10873 */
10874    ldrb   r3, [rSELF, #offThread_breakFlags]
10875    adrl   lr, dvmAsmInstructionStart + (51 * 64)
10876    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10877    cmp    r3, #0
10878    bxeq   lr                   @ nothing to do - jump to real handler
10879    EXPORT_PC()
10880    mov    r0, rPC              @ arg0
10881    mov    r1, rFP              @ arg1
10882    mov    r2, rSELF            @ arg2
10883    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10884
10885/* ------------------------------ */
10886    .balign 64
10887.L_ALT_OP_IF_LT: /* 0x34 */
10888/* File: armv5te/alt_stub.S */
10889/*
10890 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10891 * any interesting requests and then jump to the real instruction
10892 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10893 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10894 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10895 * bail to the real handler if breakFlags==0.
10896 */
10897    ldrb   r3, [rSELF, #offThread_breakFlags]
10898    adrl   lr, dvmAsmInstructionStart + (52 * 64)
10899    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10900    cmp    r3, #0
10901    bxeq   lr                   @ nothing to do - jump to real handler
10902    EXPORT_PC()
10903    mov    r0, rPC              @ arg0
10904    mov    r1, rFP              @ arg1
10905    mov    r2, rSELF            @ arg2
10906    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10907
10908/* ------------------------------ */
10909    .balign 64
10910.L_ALT_OP_IF_GE: /* 0x35 */
10911/* File: armv5te/alt_stub.S */
10912/*
10913 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10914 * any interesting requests and then jump to the real instruction
10915 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10916 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10917 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10918 * bail to the real handler if breakFlags==0.
10919 */
10920    ldrb   r3, [rSELF, #offThread_breakFlags]
10921    adrl   lr, dvmAsmInstructionStart + (53 * 64)
10922    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10923    cmp    r3, #0
10924    bxeq   lr                   @ nothing to do - jump to real handler
10925    EXPORT_PC()
10926    mov    r0, rPC              @ arg0
10927    mov    r1, rFP              @ arg1
10928    mov    r2, rSELF            @ arg2
10929    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10930
10931/* ------------------------------ */
10932    .balign 64
10933.L_ALT_OP_IF_GT: /* 0x36 */
10934/* File: armv5te/alt_stub.S */
10935/*
10936 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10937 * any interesting requests and then jump to the real instruction
10938 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10939 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10940 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10941 * bail to the real handler if breakFlags==0.
10942 */
10943    ldrb   r3, [rSELF, #offThread_breakFlags]
10944    adrl   lr, dvmAsmInstructionStart + (54 * 64)
10945    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10946    cmp    r3, #0
10947    bxeq   lr                   @ nothing to do - jump to real handler
10948    EXPORT_PC()
10949    mov    r0, rPC              @ arg0
10950    mov    r1, rFP              @ arg1
10951    mov    r2, rSELF            @ arg2
10952    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10953
10954/* ------------------------------ */
10955    .balign 64
10956.L_ALT_OP_IF_LE: /* 0x37 */
10957/* File: armv5te/alt_stub.S */
10958/*
10959 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10960 * any interesting requests and then jump to the real instruction
10961 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10962 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10963 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10964 * bail to the real handler if breakFlags==0.
10965 */
10966    ldrb   r3, [rSELF, #offThread_breakFlags]
10967    adrl   lr, dvmAsmInstructionStart + (55 * 64)
10968    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10969    cmp    r3, #0
10970    bxeq   lr                   @ nothing to do - jump to real handler
10971    EXPORT_PC()
10972    mov    r0, rPC              @ arg0
10973    mov    r1, rFP              @ arg1
10974    mov    r2, rSELF            @ arg2
10975    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10976
10977/* ------------------------------ */
10978    .balign 64
10979.L_ALT_OP_IF_EQZ: /* 0x38 */
10980/* File: armv5te/alt_stub.S */
10981/*
10982 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10983 * any interesting requests and then jump to the real instruction
10984 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10985 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10986 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10987 * bail to the real handler if breakFlags==0.
10988 */
10989    ldrb   r3, [rSELF, #offThread_breakFlags]
10990    adrl   lr, dvmAsmInstructionStart + (56 * 64)
10991    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10992    cmp    r3, #0
10993    bxeq   lr                   @ nothing to do - jump to real handler
10994    EXPORT_PC()
10995    mov    r0, rPC              @ arg0
10996    mov    r1, rFP              @ arg1
10997    mov    r2, rSELF            @ arg2
10998    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10999
11000/* ------------------------------ */
11001    .balign 64
11002.L_ALT_OP_IF_NEZ: /* 0x39 */
11003/* File: armv5te/alt_stub.S */
11004/*
11005 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11006 * any interesting requests and then jump to the real instruction
11007 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11008 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11009 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11010 * bail to the real handler if breakFlags==0.
11011 */
11012    ldrb   r3, [rSELF, #offThread_breakFlags]
11013    adrl   lr, dvmAsmInstructionStart + (57 * 64)
11014    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11015    cmp    r3, #0
11016    bxeq   lr                   @ nothing to do - jump to real handler
11017    EXPORT_PC()
11018    mov    r0, rPC              @ arg0
11019    mov    r1, rFP              @ arg1
11020    mov    r2, rSELF            @ arg2
11021    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11022
11023/* ------------------------------ */
11024    .balign 64
11025.L_ALT_OP_IF_LTZ: /* 0x3a */
11026/* File: armv5te/alt_stub.S */
11027/*
11028 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11029 * any interesting requests and then jump to the real instruction
11030 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11031 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11032 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11033 * bail to the real handler if breakFlags==0.
11034 */
11035    ldrb   r3, [rSELF, #offThread_breakFlags]
11036    adrl   lr, dvmAsmInstructionStart + (58 * 64)
11037    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11038    cmp    r3, #0
11039    bxeq   lr                   @ nothing to do - jump to real handler
11040    EXPORT_PC()
11041    mov    r0, rPC              @ arg0
11042    mov    r1, rFP              @ arg1
11043    mov    r2, rSELF            @ arg2
11044    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11045
11046/* ------------------------------ */
11047    .balign 64
11048.L_ALT_OP_IF_GEZ: /* 0x3b */
11049/* File: armv5te/alt_stub.S */
11050/*
11051 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11052 * any interesting requests and then jump to the real instruction
11053 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11054 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11055 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11056 * bail to the real handler if breakFlags==0.
11057 */
11058    ldrb   r3, [rSELF, #offThread_breakFlags]
11059    adrl   lr, dvmAsmInstructionStart + (59 * 64)
11060    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11061    cmp    r3, #0
11062    bxeq   lr                   @ nothing to do - jump to real handler
11063    EXPORT_PC()
11064    mov    r0, rPC              @ arg0
11065    mov    r1, rFP              @ arg1
11066    mov    r2, rSELF            @ arg2
11067    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11068
11069/* ------------------------------ */
11070    .balign 64
11071.L_ALT_OP_IF_GTZ: /* 0x3c */
11072/* File: armv5te/alt_stub.S */
11073/*
11074 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11075 * any interesting requests and then jump to the real instruction
11076 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11077 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11078 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11079 * bail to the real handler if breakFlags==0.
11080 */
11081    ldrb   r3, [rSELF, #offThread_breakFlags]
11082    adrl   lr, dvmAsmInstructionStart + (60 * 64)
11083    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11084    cmp    r3, #0
11085    bxeq   lr                   @ nothing to do - jump to real handler
11086    EXPORT_PC()
11087    mov    r0, rPC              @ arg0
11088    mov    r1, rFP              @ arg1
11089    mov    r2, rSELF            @ arg2
11090    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11091
11092/* ------------------------------ */
11093    .balign 64
11094.L_ALT_OP_IF_LEZ: /* 0x3d */
11095/* File: armv5te/alt_stub.S */
11096/*
11097 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11098 * any interesting requests and then jump to the real instruction
11099 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11100 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11101 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11102 * bail to the real handler if breakFlags==0.
11103 */
11104    ldrb   r3, [rSELF, #offThread_breakFlags]
11105    adrl   lr, dvmAsmInstructionStart + (61 * 64)
11106    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11107    cmp    r3, #0
11108    bxeq   lr                   @ nothing to do - jump to real handler
11109    EXPORT_PC()
11110    mov    r0, rPC              @ arg0
11111    mov    r1, rFP              @ arg1
11112    mov    r2, rSELF            @ arg2
11113    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11114
11115/* ------------------------------ */
11116    .balign 64
11117.L_ALT_OP_UNUSED_3E: /* 0x3e */
11118/* File: armv5te/alt_stub.S */
11119/*
11120 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11121 * any interesting requests and then jump to the real instruction
11122 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11123 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11124 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11125 * bail to the real handler if breakFlags==0.
11126 */
11127    ldrb   r3, [rSELF, #offThread_breakFlags]
11128    adrl   lr, dvmAsmInstructionStart + (62 * 64)
11129    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11130    cmp    r3, #0
11131    bxeq   lr                   @ nothing to do - jump to real handler
11132    EXPORT_PC()
11133    mov    r0, rPC              @ arg0
11134    mov    r1, rFP              @ arg1
11135    mov    r2, rSELF            @ arg2
11136    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11137
11138/* ------------------------------ */
11139    .balign 64
11140.L_ALT_OP_UNUSED_3F: /* 0x3f */
11141/* File: armv5te/alt_stub.S */
11142/*
11143 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11144 * any interesting requests and then jump to the real instruction
11145 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11146 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11147 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11148 * bail to the real handler if breakFlags==0.
11149 */
11150    ldrb   r3, [rSELF, #offThread_breakFlags]
11151    adrl   lr, dvmAsmInstructionStart + (63 * 64)
11152    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11153    cmp    r3, #0
11154    bxeq   lr                   @ nothing to do - jump to real handler
11155    EXPORT_PC()
11156    mov    r0, rPC              @ arg0
11157    mov    r1, rFP              @ arg1
11158    mov    r2, rSELF            @ arg2
11159    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11160
11161/* ------------------------------ */
11162    .balign 64
11163.L_ALT_OP_UNUSED_40: /* 0x40 */
11164/* File: armv5te/alt_stub.S */
11165/*
11166 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11167 * any interesting requests and then jump to the real instruction
11168 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11169 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11170 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11171 * bail to the real handler if breakFlags==0.
11172 */
11173    ldrb   r3, [rSELF, #offThread_breakFlags]
11174    adrl   lr, dvmAsmInstructionStart + (64 * 64)
11175    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11176    cmp    r3, #0
11177    bxeq   lr                   @ nothing to do - jump to real handler
11178    EXPORT_PC()
11179    mov    r0, rPC              @ arg0
11180    mov    r1, rFP              @ arg1
11181    mov    r2, rSELF            @ arg2
11182    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11183
11184/* ------------------------------ */
11185    .balign 64
11186.L_ALT_OP_UNUSED_41: /* 0x41 */
11187/* File: armv5te/alt_stub.S */
11188/*
11189 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11190 * any interesting requests and then jump to the real instruction
11191 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11192 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11193 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11194 * bail to the real handler if breakFlags==0.
11195 */
11196    ldrb   r3, [rSELF, #offThread_breakFlags]
11197    adrl   lr, dvmAsmInstructionStart + (65 * 64)
11198    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11199    cmp    r3, #0
11200    bxeq   lr                   @ nothing to do - jump to real handler
11201    EXPORT_PC()
11202    mov    r0, rPC              @ arg0
11203    mov    r1, rFP              @ arg1
11204    mov    r2, rSELF            @ arg2
11205    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11206
11207/* ------------------------------ */
11208    .balign 64
11209.L_ALT_OP_UNUSED_42: /* 0x42 */
11210/* File: armv5te/alt_stub.S */
11211/*
11212 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11213 * any interesting requests and then jump to the real instruction
11214 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11215 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11216 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11217 * bail to the real handler if breakFlags==0.
11218 */
11219    ldrb   r3, [rSELF, #offThread_breakFlags]
11220    adrl   lr, dvmAsmInstructionStart + (66 * 64)
11221    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11222    cmp    r3, #0
11223    bxeq   lr                   @ nothing to do - jump to real handler
11224    EXPORT_PC()
11225    mov    r0, rPC              @ arg0
11226    mov    r1, rFP              @ arg1
11227    mov    r2, rSELF            @ arg2
11228    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11229
11230/* ------------------------------ */
11231    .balign 64
11232.L_ALT_OP_UNUSED_43: /* 0x43 */
11233/* File: armv5te/alt_stub.S */
11234/*
11235 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11236 * any interesting requests and then jump to the real instruction
11237 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11238 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11239 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11240 * bail to the real handler if breakFlags==0.
11241 */
11242    ldrb   r3, [rSELF, #offThread_breakFlags]
11243    adrl   lr, dvmAsmInstructionStart + (67 * 64)
11244    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11245    cmp    r3, #0
11246    bxeq   lr                   @ nothing to do - jump to real handler
11247    EXPORT_PC()
11248    mov    r0, rPC              @ arg0
11249    mov    r1, rFP              @ arg1
11250    mov    r2, rSELF            @ arg2
11251    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11252
11253/* ------------------------------ */
11254    .balign 64
11255.L_ALT_OP_AGET: /* 0x44 */
11256/* File: armv5te/alt_stub.S */
11257/*
11258 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11259 * any interesting requests and then jump to the real instruction
11260 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11261 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11262 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11263 * bail to the real handler if breakFlags==0.
11264 */
11265    ldrb   r3, [rSELF, #offThread_breakFlags]
11266    adrl   lr, dvmAsmInstructionStart + (68 * 64)
11267    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11268    cmp    r3, #0
11269    bxeq   lr                   @ nothing to do - jump to real handler
11270    EXPORT_PC()
11271    mov    r0, rPC              @ arg0
11272    mov    r1, rFP              @ arg1
11273    mov    r2, rSELF            @ arg2
11274    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11275
11276/* ------------------------------ */
11277    .balign 64
11278.L_ALT_OP_AGET_WIDE: /* 0x45 */
11279/* File: armv5te/alt_stub.S */
11280/*
11281 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11282 * any interesting requests and then jump to the real instruction
11283 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11284 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11285 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11286 * bail to the real handler if breakFlags==0.
11287 */
11288    ldrb   r3, [rSELF, #offThread_breakFlags]
11289    adrl   lr, dvmAsmInstructionStart + (69 * 64)
11290    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11291    cmp    r3, #0
11292    bxeq   lr                   @ nothing to do - jump to real handler
11293    EXPORT_PC()
11294    mov    r0, rPC              @ arg0
11295    mov    r1, rFP              @ arg1
11296    mov    r2, rSELF            @ arg2
11297    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11298
11299/* ------------------------------ */
11300    .balign 64
11301.L_ALT_OP_AGET_OBJECT: /* 0x46 */
11302/* File: armv5te/alt_stub.S */
11303/*
11304 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11305 * any interesting requests and then jump to the real instruction
11306 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11307 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11308 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11309 * bail to the real handler if breakFlags==0.
11310 */
11311    ldrb   r3, [rSELF, #offThread_breakFlags]
11312    adrl   lr, dvmAsmInstructionStart + (70 * 64)
11313    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11314    cmp    r3, #0
11315    bxeq   lr                   @ nothing to do - jump to real handler
11316    EXPORT_PC()
11317    mov    r0, rPC              @ arg0
11318    mov    r1, rFP              @ arg1
11319    mov    r2, rSELF            @ arg2
11320    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11321
11322/* ------------------------------ */
11323    .balign 64
11324.L_ALT_OP_AGET_BOOLEAN: /* 0x47 */
11325/* File: armv5te/alt_stub.S */
11326/*
11327 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11328 * any interesting requests and then jump to the real instruction
11329 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11330 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11331 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11332 * bail to the real handler if breakFlags==0.
11333 */
11334    ldrb   r3, [rSELF, #offThread_breakFlags]
11335    adrl   lr, dvmAsmInstructionStart + (71 * 64)
11336    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11337    cmp    r3, #0
11338    bxeq   lr                   @ nothing to do - jump to real handler
11339    EXPORT_PC()
11340    mov    r0, rPC              @ arg0
11341    mov    r1, rFP              @ arg1
11342    mov    r2, rSELF            @ arg2
11343    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11344
11345/* ------------------------------ */
11346    .balign 64
11347.L_ALT_OP_AGET_BYTE: /* 0x48 */
11348/* File: armv5te/alt_stub.S */
11349/*
11350 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11351 * any interesting requests and then jump to the real instruction
11352 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11353 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11354 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11355 * bail to the real handler if breakFlags==0.
11356 */
11357    ldrb   r3, [rSELF, #offThread_breakFlags]
11358    adrl   lr, dvmAsmInstructionStart + (72 * 64)
11359    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11360    cmp    r3, #0
11361    bxeq   lr                   @ nothing to do - jump to real handler
11362    EXPORT_PC()
11363    mov    r0, rPC              @ arg0
11364    mov    r1, rFP              @ arg1
11365    mov    r2, rSELF            @ arg2
11366    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11367
11368/* ------------------------------ */
11369    .balign 64
11370.L_ALT_OP_AGET_CHAR: /* 0x49 */
11371/* File: armv5te/alt_stub.S */
11372/*
11373 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11374 * any interesting requests and then jump to the real instruction
11375 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11376 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11377 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11378 * bail to the real handler if breakFlags==0.
11379 */
11380    ldrb   r3, [rSELF, #offThread_breakFlags]
11381    adrl   lr, dvmAsmInstructionStart + (73 * 64)
11382    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11383    cmp    r3, #0
11384    bxeq   lr                   @ nothing to do - jump to real handler
11385    EXPORT_PC()
11386    mov    r0, rPC              @ arg0
11387    mov    r1, rFP              @ arg1
11388    mov    r2, rSELF            @ arg2
11389    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11390
11391/* ------------------------------ */
11392    .balign 64
11393.L_ALT_OP_AGET_SHORT: /* 0x4a */
11394/* File: armv5te/alt_stub.S */
11395/*
11396 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11397 * any interesting requests and then jump to the real instruction
11398 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11399 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11400 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11401 * bail to the real handler if breakFlags==0.
11402 */
11403    ldrb   r3, [rSELF, #offThread_breakFlags]
11404    adrl   lr, dvmAsmInstructionStart + (74 * 64)
11405    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11406    cmp    r3, #0
11407    bxeq   lr                   @ nothing to do - jump to real handler
11408    EXPORT_PC()
11409    mov    r0, rPC              @ arg0
11410    mov    r1, rFP              @ arg1
11411    mov    r2, rSELF            @ arg2
11412    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11413
11414/* ------------------------------ */
11415    .balign 64
11416.L_ALT_OP_APUT: /* 0x4b */
11417/* File: armv5te/alt_stub.S */
11418/*
11419 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11420 * any interesting requests and then jump to the real instruction
11421 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11422 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11423 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11424 * bail to the real handler if breakFlags==0.
11425 */
11426    ldrb   r3, [rSELF, #offThread_breakFlags]
11427    adrl   lr, dvmAsmInstructionStart + (75 * 64)
11428    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11429    cmp    r3, #0
11430    bxeq   lr                   @ nothing to do - jump to real handler
11431    EXPORT_PC()
11432    mov    r0, rPC              @ arg0
11433    mov    r1, rFP              @ arg1
11434    mov    r2, rSELF            @ arg2
11435    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11436
11437/* ------------------------------ */
11438    .balign 64
11439.L_ALT_OP_APUT_WIDE: /* 0x4c */
11440/* File: armv5te/alt_stub.S */
11441/*
11442 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11443 * any interesting requests and then jump to the real instruction
11444 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11445 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11446 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11447 * bail to the real handler if breakFlags==0.
11448 */
11449    ldrb   r3, [rSELF, #offThread_breakFlags]
11450    adrl   lr, dvmAsmInstructionStart + (76 * 64)
11451    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11452    cmp    r3, #0
11453    bxeq   lr                   @ nothing to do - jump to real handler
11454    EXPORT_PC()
11455    mov    r0, rPC              @ arg0
11456    mov    r1, rFP              @ arg1
11457    mov    r2, rSELF            @ arg2
11458    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11459
11460/* ------------------------------ */
11461    .balign 64
11462.L_ALT_OP_APUT_OBJECT: /* 0x4d */
11463/* File: armv5te/alt_stub.S */
11464/*
11465 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11466 * any interesting requests and then jump to the real instruction
11467 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11468 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11469 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11470 * bail to the real handler if breakFlags==0.
11471 */
11472    ldrb   r3, [rSELF, #offThread_breakFlags]
11473    adrl   lr, dvmAsmInstructionStart + (77 * 64)
11474    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11475    cmp    r3, #0
11476    bxeq   lr                   @ nothing to do - jump to real handler
11477    EXPORT_PC()
11478    mov    r0, rPC              @ arg0
11479    mov    r1, rFP              @ arg1
11480    mov    r2, rSELF            @ arg2
11481    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11482
11483/* ------------------------------ */
11484    .balign 64
11485.L_ALT_OP_APUT_BOOLEAN: /* 0x4e */
11486/* File: armv5te/alt_stub.S */
11487/*
11488 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11489 * any interesting requests and then jump to the real instruction
11490 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11491 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11492 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11493 * bail to the real handler if breakFlags==0.
11494 */
11495    ldrb   r3, [rSELF, #offThread_breakFlags]
11496    adrl   lr, dvmAsmInstructionStart + (78 * 64)
11497    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11498    cmp    r3, #0
11499    bxeq   lr                   @ nothing to do - jump to real handler
11500    EXPORT_PC()
11501    mov    r0, rPC              @ arg0
11502    mov    r1, rFP              @ arg1
11503    mov    r2, rSELF            @ arg2
11504    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11505
11506/* ------------------------------ */
11507    .balign 64
11508.L_ALT_OP_APUT_BYTE: /* 0x4f */
11509/* File: armv5te/alt_stub.S */
11510/*
11511 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11512 * any interesting requests and then jump to the real instruction
11513 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11514 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11515 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11516 * bail to the real handler if breakFlags==0.
11517 */
11518    ldrb   r3, [rSELF, #offThread_breakFlags]
11519    adrl   lr, dvmAsmInstructionStart + (79 * 64)
11520    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11521    cmp    r3, #0
11522    bxeq   lr                   @ nothing to do - jump to real handler
11523    EXPORT_PC()
11524    mov    r0, rPC              @ arg0
11525    mov    r1, rFP              @ arg1
11526    mov    r2, rSELF            @ arg2
11527    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11528
11529/* ------------------------------ */
11530    .balign 64
11531.L_ALT_OP_APUT_CHAR: /* 0x50 */
11532/* File: armv5te/alt_stub.S */
11533/*
11534 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11535 * any interesting requests and then jump to the real instruction
11536 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11537 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11538 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11539 * bail to the real handler if breakFlags==0.
11540 */
11541    ldrb   r3, [rSELF, #offThread_breakFlags]
11542    adrl   lr, dvmAsmInstructionStart + (80 * 64)
11543    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11544    cmp    r3, #0
11545    bxeq   lr                   @ nothing to do - jump to real handler
11546    EXPORT_PC()
11547    mov    r0, rPC              @ arg0
11548    mov    r1, rFP              @ arg1
11549    mov    r2, rSELF            @ arg2
11550    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11551
11552/* ------------------------------ */
11553    .balign 64
11554.L_ALT_OP_APUT_SHORT: /* 0x51 */
11555/* File: armv5te/alt_stub.S */
11556/*
11557 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11558 * any interesting requests and then jump to the real instruction
11559 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11560 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11561 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11562 * bail to the real handler if breakFlags==0.
11563 */
11564    ldrb   r3, [rSELF, #offThread_breakFlags]
11565    adrl   lr, dvmAsmInstructionStart + (81 * 64)
11566    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11567    cmp    r3, #0
11568    bxeq   lr                   @ nothing to do - jump to real handler
11569    EXPORT_PC()
11570    mov    r0, rPC              @ arg0
11571    mov    r1, rFP              @ arg1
11572    mov    r2, rSELF            @ arg2
11573    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11574
11575/* ------------------------------ */
11576    .balign 64
11577.L_ALT_OP_IGET: /* 0x52 */
11578/* File: armv5te/alt_stub.S */
11579/*
11580 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11581 * any interesting requests and then jump to the real instruction
11582 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11583 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11584 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11585 * bail to the real handler if breakFlags==0.
11586 */
11587    ldrb   r3, [rSELF, #offThread_breakFlags]
11588    adrl   lr, dvmAsmInstructionStart + (82 * 64)
11589    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11590    cmp    r3, #0
11591    bxeq   lr                   @ nothing to do - jump to real handler
11592    EXPORT_PC()
11593    mov    r0, rPC              @ arg0
11594    mov    r1, rFP              @ arg1
11595    mov    r2, rSELF            @ arg2
11596    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11597
11598/* ------------------------------ */
11599    .balign 64
11600.L_ALT_OP_IGET_WIDE: /* 0x53 */
11601/* File: armv5te/alt_stub.S */
11602/*
11603 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11604 * any interesting requests and then jump to the real instruction
11605 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11606 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11607 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11608 * bail to the real handler if breakFlags==0.
11609 */
11610    ldrb   r3, [rSELF, #offThread_breakFlags]
11611    adrl   lr, dvmAsmInstructionStart + (83 * 64)
11612    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11613    cmp    r3, #0
11614    bxeq   lr                   @ nothing to do - jump to real handler
11615    EXPORT_PC()
11616    mov    r0, rPC              @ arg0
11617    mov    r1, rFP              @ arg1
11618    mov    r2, rSELF            @ arg2
11619    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11620
11621/* ------------------------------ */
11622    .balign 64
11623.L_ALT_OP_IGET_OBJECT: /* 0x54 */
11624/* File: armv5te/alt_stub.S */
11625/*
11626 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11627 * any interesting requests and then jump to the real instruction
11628 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11629 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11630 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11631 * bail to the real handler if breakFlags==0.
11632 */
11633    ldrb   r3, [rSELF, #offThread_breakFlags]
11634    adrl   lr, dvmAsmInstructionStart + (84 * 64)
11635    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11636    cmp    r3, #0
11637    bxeq   lr                   @ nothing to do - jump to real handler
11638    EXPORT_PC()
11639    mov    r0, rPC              @ arg0
11640    mov    r1, rFP              @ arg1
11641    mov    r2, rSELF            @ arg2
11642    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11643
11644/* ------------------------------ */
11645    .balign 64
11646.L_ALT_OP_IGET_BOOLEAN: /* 0x55 */
11647/* File: armv5te/alt_stub.S */
11648/*
11649 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11650 * any interesting requests and then jump to the real instruction
11651 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11652 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11653 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11654 * bail to the real handler if breakFlags==0.
11655 */
11656    ldrb   r3, [rSELF, #offThread_breakFlags]
11657    adrl   lr, dvmAsmInstructionStart + (85 * 64)
11658    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11659    cmp    r3, #0
11660    bxeq   lr                   @ nothing to do - jump to real handler
11661    EXPORT_PC()
11662    mov    r0, rPC              @ arg0
11663    mov    r1, rFP              @ arg1
11664    mov    r2, rSELF            @ arg2
11665    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11666
11667/* ------------------------------ */
11668    .balign 64
11669.L_ALT_OP_IGET_BYTE: /* 0x56 */
11670/* File: armv5te/alt_stub.S */
11671/*
11672 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11673 * any interesting requests and then jump to the real instruction
11674 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11675 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11676 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11677 * bail to the real handler if breakFlags==0.
11678 */
11679    ldrb   r3, [rSELF, #offThread_breakFlags]
11680    adrl   lr, dvmAsmInstructionStart + (86 * 64)
11681    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11682    cmp    r3, #0
11683    bxeq   lr                   @ nothing to do - jump to real handler
11684    EXPORT_PC()
11685    mov    r0, rPC              @ arg0
11686    mov    r1, rFP              @ arg1
11687    mov    r2, rSELF            @ arg2
11688    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11689
11690/* ------------------------------ */
11691    .balign 64
11692.L_ALT_OP_IGET_CHAR: /* 0x57 */
11693/* File: armv5te/alt_stub.S */
11694/*
11695 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11696 * any interesting requests and then jump to the real instruction
11697 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11698 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11699 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11700 * bail to the real handler if breakFlags==0.
11701 */
11702    ldrb   r3, [rSELF, #offThread_breakFlags]
11703    adrl   lr, dvmAsmInstructionStart + (87 * 64)
11704    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11705    cmp    r3, #0
11706    bxeq   lr                   @ nothing to do - jump to real handler
11707    EXPORT_PC()
11708    mov    r0, rPC              @ arg0
11709    mov    r1, rFP              @ arg1
11710    mov    r2, rSELF            @ arg2
11711    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11712
11713/* ------------------------------ */
11714    .balign 64
11715.L_ALT_OP_IGET_SHORT: /* 0x58 */
11716/* File: armv5te/alt_stub.S */
11717/*
11718 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11719 * any interesting requests and then jump to the real instruction
11720 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11721 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11722 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11723 * bail to the real handler if breakFlags==0.
11724 */
11725    ldrb   r3, [rSELF, #offThread_breakFlags]
11726    adrl   lr, dvmAsmInstructionStart + (88 * 64)
11727    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11728    cmp    r3, #0
11729    bxeq   lr                   @ nothing to do - jump to real handler
11730    EXPORT_PC()
11731    mov    r0, rPC              @ arg0
11732    mov    r1, rFP              @ arg1
11733    mov    r2, rSELF            @ arg2
11734    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11735
11736/* ------------------------------ */
11737    .balign 64
11738.L_ALT_OP_IPUT: /* 0x59 */
11739/* File: armv5te/alt_stub.S */
11740/*
11741 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11742 * any interesting requests and then jump to the real instruction
11743 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11744 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11745 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11746 * bail to the real handler if breakFlags==0.
11747 */
11748    ldrb   r3, [rSELF, #offThread_breakFlags]
11749    adrl   lr, dvmAsmInstructionStart + (89 * 64)
11750    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11751    cmp    r3, #0
11752    bxeq   lr                   @ nothing to do - jump to real handler
11753    EXPORT_PC()
11754    mov    r0, rPC              @ arg0
11755    mov    r1, rFP              @ arg1
11756    mov    r2, rSELF            @ arg2
11757    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11758
11759/* ------------------------------ */
11760    .balign 64
11761.L_ALT_OP_IPUT_WIDE: /* 0x5a */
11762/* File: armv5te/alt_stub.S */
11763/*
11764 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11765 * any interesting requests and then jump to the real instruction
11766 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11767 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11768 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11769 * bail to the real handler if breakFlags==0.
11770 */
11771    ldrb   r3, [rSELF, #offThread_breakFlags]
11772    adrl   lr, dvmAsmInstructionStart + (90 * 64)
11773    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11774    cmp    r3, #0
11775    bxeq   lr                   @ nothing to do - jump to real handler
11776    EXPORT_PC()
11777    mov    r0, rPC              @ arg0
11778    mov    r1, rFP              @ arg1
11779    mov    r2, rSELF            @ arg2
11780    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11781
11782/* ------------------------------ */
11783    .balign 64
11784.L_ALT_OP_IPUT_OBJECT: /* 0x5b */
11785/* File: armv5te/alt_stub.S */
11786/*
11787 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11788 * any interesting requests and then jump to the real instruction
11789 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11790 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11791 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11792 * bail to the real handler if breakFlags==0.
11793 */
11794    ldrb   r3, [rSELF, #offThread_breakFlags]
11795    adrl   lr, dvmAsmInstructionStart + (91 * 64)
11796    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11797    cmp    r3, #0
11798    bxeq   lr                   @ nothing to do - jump to real handler
11799    EXPORT_PC()
11800    mov    r0, rPC              @ arg0
11801    mov    r1, rFP              @ arg1
11802    mov    r2, rSELF            @ arg2
11803    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11804
11805/* ------------------------------ */
11806    .balign 64
11807.L_ALT_OP_IPUT_BOOLEAN: /* 0x5c */
11808/* File: armv5te/alt_stub.S */
11809/*
11810 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11811 * any interesting requests and then jump to the real instruction
11812 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11813 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11814 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11815 * bail to the real handler if breakFlags==0.
11816 */
11817    ldrb   r3, [rSELF, #offThread_breakFlags]
11818    adrl   lr, dvmAsmInstructionStart + (92 * 64)
11819    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11820    cmp    r3, #0
11821    bxeq   lr                   @ nothing to do - jump to real handler
11822    EXPORT_PC()
11823    mov    r0, rPC              @ arg0
11824    mov    r1, rFP              @ arg1
11825    mov    r2, rSELF            @ arg2
11826    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11827
11828/* ------------------------------ */
11829    .balign 64
11830.L_ALT_OP_IPUT_BYTE: /* 0x5d */
11831/* File: armv5te/alt_stub.S */
11832/*
11833 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11834 * any interesting requests and then jump to the real instruction
11835 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11836 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11837 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11838 * bail to the real handler if breakFlags==0.
11839 */
11840    ldrb   r3, [rSELF, #offThread_breakFlags]
11841    adrl   lr, dvmAsmInstructionStart + (93 * 64)
11842    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11843    cmp    r3, #0
11844    bxeq   lr                   @ nothing to do - jump to real handler
11845    EXPORT_PC()
11846    mov    r0, rPC              @ arg0
11847    mov    r1, rFP              @ arg1
11848    mov    r2, rSELF            @ arg2
11849    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11850
11851/* ------------------------------ */
11852    .balign 64
11853.L_ALT_OP_IPUT_CHAR: /* 0x5e */
11854/* File: armv5te/alt_stub.S */
11855/*
11856 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11857 * any interesting requests and then jump to the real instruction
11858 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11859 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11860 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11861 * bail to the real handler if breakFlags==0.
11862 */
11863    ldrb   r3, [rSELF, #offThread_breakFlags]
11864    adrl   lr, dvmAsmInstructionStart + (94 * 64)
11865    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11866    cmp    r3, #0
11867    bxeq   lr                   @ nothing to do - jump to real handler
11868    EXPORT_PC()
11869    mov    r0, rPC              @ arg0
11870    mov    r1, rFP              @ arg1
11871    mov    r2, rSELF            @ arg2
11872    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11873
11874/* ------------------------------ */
11875    .balign 64
11876.L_ALT_OP_IPUT_SHORT: /* 0x5f */
11877/* File: armv5te/alt_stub.S */
11878/*
11879 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11880 * any interesting requests and then jump to the real instruction
11881 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11882 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11883 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11884 * bail to the real handler if breakFlags==0.
11885 */
11886    ldrb   r3, [rSELF, #offThread_breakFlags]
11887    adrl   lr, dvmAsmInstructionStart + (95 * 64)
11888    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11889    cmp    r3, #0
11890    bxeq   lr                   @ nothing to do - jump to real handler
11891    EXPORT_PC()
11892    mov    r0, rPC              @ arg0
11893    mov    r1, rFP              @ arg1
11894    mov    r2, rSELF            @ arg2
11895    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11896
11897/* ------------------------------ */
11898    .balign 64
11899.L_ALT_OP_SGET: /* 0x60 */
11900/* File: armv5te/alt_stub.S */
11901/*
11902 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11903 * any interesting requests and then jump to the real instruction
11904 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11905 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11906 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11907 * bail to the real handler if breakFlags==0.
11908 */
11909    ldrb   r3, [rSELF, #offThread_breakFlags]
11910    adrl   lr, dvmAsmInstructionStart + (96 * 64)
11911    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11912    cmp    r3, #0
11913    bxeq   lr                   @ nothing to do - jump to real handler
11914    EXPORT_PC()
11915    mov    r0, rPC              @ arg0
11916    mov    r1, rFP              @ arg1
11917    mov    r2, rSELF            @ arg2
11918    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11919
11920/* ------------------------------ */
11921    .balign 64
11922.L_ALT_OP_SGET_WIDE: /* 0x61 */
11923/* File: armv5te/alt_stub.S */
11924/*
11925 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11926 * any interesting requests and then jump to the real instruction
11927 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11928 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11929 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11930 * bail to the real handler if breakFlags==0.
11931 */
11932    ldrb   r3, [rSELF, #offThread_breakFlags]
11933    adrl   lr, dvmAsmInstructionStart + (97 * 64)
11934    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11935    cmp    r3, #0
11936    bxeq   lr                   @ nothing to do - jump to real handler
11937    EXPORT_PC()
11938    mov    r0, rPC              @ arg0
11939    mov    r1, rFP              @ arg1
11940    mov    r2, rSELF            @ arg2
11941    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11942
11943/* ------------------------------ */
11944    .balign 64
11945.L_ALT_OP_SGET_OBJECT: /* 0x62 */
11946/* File: armv5te/alt_stub.S */
11947/*
11948 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11949 * any interesting requests and then jump to the real instruction
11950 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11951 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11952 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11953 * bail to the real handler if breakFlags==0.
11954 */
11955    ldrb   r3, [rSELF, #offThread_breakFlags]
11956    adrl   lr, dvmAsmInstructionStart + (98 * 64)
11957    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11958    cmp    r3, #0
11959    bxeq   lr                   @ nothing to do - jump to real handler
11960    EXPORT_PC()
11961    mov    r0, rPC              @ arg0
11962    mov    r1, rFP              @ arg1
11963    mov    r2, rSELF            @ arg2
11964    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11965
11966/* ------------------------------ */
11967    .balign 64
11968.L_ALT_OP_SGET_BOOLEAN: /* 0x63 */
11969/* File: armv5te/alt_stub.S */
11970/*
11971 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11972 * any interesting requests and then jump to the real instruction
11973 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11974 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11975 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11976 * bail to the real handler if breakFlags==0.
11977 */
11978    ldrb   r3, [rSELF, #offThread_breakFlags]
11979    adrl   lr, dvmAsmInstructionStart + (99 * 64)
11980    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11981    cmp    r3, #0
11982    bxeq   lr                   @ nothing to do - jump to real handler
11983    EXPORT_PC()
11984    mov    r0, rPC              @ arg0
11985    mov    r1, rFP              @ arg1
11986    mov    r2, rSELF            @ arg2
11987    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11988
11989/* ------------------------------ */
11990    .balign 64
11991.L_ALT_OP_SGET_BYTE: /* 0x64 */
11992/* File: armv5te/alt_stub.S */
11993/*
11994 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11995 * any interesting requests and then jump to the real instruction
11996 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11997 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11998 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11999 * bail to the real handler if breakFlags==0.
12000 */
12001    ldrb   r3, [rSELF, #offThread_breakFlags]
12002    adrl   lr, dvmAsmInstructionStart + (100 * 64)
12003    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12004    cmp    r3, #0
12005    bxeq   lr                   @ nothing to do - jump to real handler
12006    EXPORT_PC()
12007    mov    r0, rPC              @ arg0
12008    mov    r1, rFP              @ arg1
12009    mov    r2, rSELF            @ arg2
12010    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12011
12012/* ------------------------------ */
12013    .balign 64
12014.L_ALT_OP_SGET_CHAR: /* 0x65 */
12015/* File: armv5te/alt_stub.S */
12016/*
12017 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12018 * any interesting requests and then jump to the real instruction
12019 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12020 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12021 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12022 * bail to the real handler if breakFlags==0.
12023 */
12024    ldrb   r3, [rSELF, #offThread_breakFlags]
12025    adrl   lr, dvmAsmInstructionStart + (101 * 64)
12026    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12027    cmp    r3, #0
12028    bxeq   lr                   @ nothing to do - jump to real handler
12029    EXPORT_PC()
12030    mov    r0, rPC              @ arg0
12031    mov    r1, rFP              @ arg1
12032    mov    r2, rSELF            @ arg2
12033    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12034
12035/* ------------------------------ */
12036    .balign 64
12037.L_ALT_OP_SGET_SHORT: /* 0x66 */
12038/* File: armv5te/alt_stub.S */
12039/*
12040 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12041 * any interesting requests and then jump to the real instruction
12042 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12043 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12044 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12045 * bail to the real handler if breakFlags==0.
12046 */
12047    ldrb   r3, [rSELF, #offThread_breakFlags]
12048    adrl   lr, dvmAsmInstructionStart + (102 * 64)
12049    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12050    cmp    r3, #0
12051    bxeq   lr                   @ nothing to do - jump to real handler
12052    EXPORT_PC()
12053    mov    r0, rPC              @ arg0
12054    mov    r1, rFP              @ arg1
12055    mov    r2, rSELF            @ arg2
12056    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12057
12058/* ------------------------------ */
12059    .balign 64
12060.L_ALT_OP_SPUT: /* 0x67 */
12061/* File: armv5te/alt_stub.S */
12062/*
12063 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12064 * any interesting requests and then jump to the real instruction
12065 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12066 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12067 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12068 * bail to the real handler if breakFlags==0.
12069 */
12070    ldrb   r3, [rSELF, #offThread_breakFlags]
12071    adrl   lr, dvmAsmInstructionStart + (103 * 64)
12072    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12073    cmp    r3, #0
12074    bxeq   lr                   @ nothing to do - jump to real handler
12075    EXPORT_PC()
12076    mov    r0, rPC              @ arg0
12077    mov    r1, rFP              @ arg1
12078    mov    r2, rSELF            @ arg2
12079    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12080
12081/* ------------------------------ */
12082    .balign 64
12083.L_ALT_OP_SPUT_WIDE: /* 0x68 */
12084/* File: armv5te/alt_stub.S */
12085/*
12086 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12087 * any interesting requests and then jump to the real instruction
12088 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12089 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12090 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12091 * bail to the real handler if breakFlags==0.
12092 */
12093    ldrb   r3, [rSELF, #offThread_breakFlags]
12094    adrl   lr, dvmAsmInstructionStart + (104 * 64)
12095    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12096    cmp    r3, #0
12097    bxeq   lr                   @ nothing to do - jump to real handler
12098    EXPORT_PC()
12099    mov    r0, rPC              @ arg0
12100    mov    r1, rFP              @ arg1
12101    mov    r2, rSELF            @ arg2
12102    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12103
12104/* ------------------------------ */
12105    .balign 64
12106.L_ALT_OP_SPUT_OBJECT: /* 0x69 */
12107/* File: armv5te/alt_stub.S */
12108/*
12109 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12110 * any interesting requests and then jump to the real instruction
12111 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12112 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12113 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12114 * bail to the real handler if breakFlags==0.
12115 */
12116    ldrb   r3, [rSELF, #offThread_breakFlags]
12117    adrl   lr, dvmAsmInstructionStart + (105 * 64)
12118    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12119    cmp    r3, #0
12120    bxeq   lr                   @ nothing to do - jump to real handler
12121    EXPORT_PC()
12122    mov    r0, rPC              @ arg0
12123    mov    r1, rFP              @ arg1
12124    mov    r2, rSELF            @ arg2
12125    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12126
12127/* ------------------------------ */
12128    .balign 64
12129.L_ALT_OP_SPUT_BOOLEAN: /* 0x6a */
12130/* File: armv5te/alt_stub.S */
12131/*
12132 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12133 * any interesting requests and then jump to the real instruction
12134 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12135 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12136 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12137 * bail to the real handler if breakFlags==0.
12138 */
12139    ldrb   r3, [rSELF, #offThread_breakFlags]
12140    adrl   lr, dvmAsmInstructionStart + (106 * 64)
12141    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12142    cmp    r3, #0
12143    bxeq   lr                   @ nothing to do - jump to real handler
12144    EXPORT_PC()
12145    mov    r0, rPC              @ arg0
12146    mov    r1, rFP              @ arg1
12147    mov    r2, rSELF            @ arg2
12148    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12149
12150/* ------------------------------ */
12151    .balign 64
12152.L_ALT_OP_SPUT_BYTE: /* 0x6b */
12153/* File: armv5te/alt_stub.S */
12154/*
12155 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12156 * any interesting requests and then jump to the real instruction
12157 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12158 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12159 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12160 * bail to the real handler if breakFlags==0.
12161 */
12162    ldrb   r3, [rSELF, #offThread_breakFlags]
12163    adrl   lr, dvmAsmInstructionStart + (107 * 64)
12164    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12165    cmp    r3, #0
12166    bxeq   lr                   @ nothing to do - jump to real handler
12167    EXPORT_PC()
12168    mov    r0, rPC              @ arg0
12169    mov    r1, rFP              @ arg1
12170    mov    r2, rSELF            @ arg2
12171    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12172
12173/* ------------------------------ */
12174    .balign 64
12175.L_ALT_OP_SPUT_CHAR: /* 0x6c */
12176/* File: armv5te/alt_stub.S */
12177/*
12178 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12179 * any interesting requests and then jump to the real instruction
12180 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12181 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12182 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12183 * bail to the real handler if breakFlags==0.
12184 */
12185    ldrb   r3, [rSELF, #offThread_breakFlags]
12186    adrl   lr, dvmAsmInstructionStart + (108 * 64)
12187    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12188    cmp    r3, #0
12189    bxeq   lr                   @ nothing to do - jump to real handler
12190    EXPORT_PC()
12191    mov    r0, rPC              @ arg0
12192    mov    r1, rFP              @ arg1
12193    mov    r2, rSELF            @ arg2
12194    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12195
12196/* ------------------------------ */
12197    .balign 64
12198.L_ALT_OP_SPUT_SHORT: /* 0x6d */
12199/* File: armv5te/alt_stub.S */
12200/*
12201 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12202 * any interesting requests and then jump to the real instruction
12203 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12204 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12205 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12206 * bail to the real handler if breakFlags==0.
12207 */
12208    ldrb   r3, [rSELF, #offThread_breakFlags]
12209    adrl   lr, dvmAsmInstructionStart + (109 * 64)
12210    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12211    cmp    r3, #0
12212    bxeq   lr                   @ nothing to do - jump to real handler
12213    EXPORT_PC()
12214    mov    r0, rPC              @ arg0
12215    mov    r1, rFP              @ arg1
12216    mov    r2, rSELF            @ arg2
12217    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12218
12219/* ------------------------------ */
12220    .balign 64
12221.L_ALT_OP_INVOKE_VIRTUAL: /* 0x6e */
12222/* File: armv5te/alt_stub.S */
12223/*
12224 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12225 * any interesting requests and then jump to the real instruction
12226 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12227 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12228 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12229 * bail to the real handler if breakFlags==0.
12230 */
12231    ldrb   r3, [rSELF, #offThread_breakFlags]
12232    adrl   lr, dvmAsmInstructionStart + (110 * 64)
12233    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12234    cmp    r3, #0
12235    bxeq   lr                   @ nothing to do - jump to real handler
12236    EXPORT_PC()
12237    mov    r0, rPC              @ arg0
12238    mov    r1, rFP              @ arg1
12239    mov    r2, rSELF            @ arg2
12240    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12241
12242/* ------------------------------ */
12243    .balign 64
12244.L_ALT_OP_INVOKE_SUPER: /* 0x6f */
12245/* File: armv5te/alt_stub.S */
12246/*
12247 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12248 * any interesting requests and then jump to the real instruction
12249 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12250 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12251 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12252 * bail to the real handler if breakFlags==0.
12253 */
12254    ldrb   r3, [rSELF, #offThread_breakFlags]
12255    adrl   lr, dvmAsmInstructionStart + (111 * 64)
12256    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12257    cmp    r3, #0
12258    bxeq   lr                   @ nothing to do - jump to real handler
12259    EXPORT_PC()
12260    mov    r0, rPC              @ arg0
12261    mov    r1, rFP              @ arg1
12262    mov    r2, rSELF            @ arg2
12263    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12264
12265/* ------------------------------ */
12266    .balign 64
12267.L_ALT_OP_INVOKE_DIRECT: /* 0x70 */
12268/* File: armv5te/alt_stub.S */
12269/*
12270 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12271 * any interesting requests and then jump to the real instruction
12272 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12273 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12274 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12275 * bail to the real handler if breakFlags==0.
12276 */
12277    ldrb   r3, [rSELF, #offThread_breakFlags]
12278    adrl   lr, dvmAsmInstructionStart + (112 * 64)
12279    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12280    cmp    r3, #0
12281    bxeq   lr                   @ nothing to do - jump to real handler
12282    EXPORT_PC()
12283    mov    r0, rPC              @ arg0
12284    mov    r1, rFP              @ arg1
12285    mov    r2, rSELF            @ arg2
12286    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12287
12288/* ------------------------------ */
12289    .balign 64
12290.L_ALT_OP_INVOKE_STATIC: /* 0x71 */
12291/* File: armv5te/alt_stub.S */
12292/*
12293 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12294 * any interesting requests and then jump to the real instruction
12295 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12296 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12297 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12298 * bail to the real handler if breakFlags==0.
12299 */
12300    ldrb   r3, [rSELF, #offThread_breakFlags]
12301    adrl   lr, dvmAsmInstructionStart + (113 * 64)
12302    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12303    cmp    r3, #0
12304    bxeq   lr                   @ nothing to do - jump to real handler
12305    EXPORT_PC()
12306    mov    r0, rPC              @ arg0
12307    mov    r1, rFP              @ arg1
12308    mov    r2, rSELF            @ arg2
12309    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12310
12311/* ------------------------------ */
12312    .balign 64
12313.L_ALT_OP_INVOKE_INTERFACE: /* 0x72 */
12314/* File: armv5te/alt_stub.S */
12315/*
12316 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12317 * any interesting requests and then jump to the real instruction
12318 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12319 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12320 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12321 * bail to the real handler if breakFlags==0.
12322 */
12323    ldrb   r3, [rSELF, #offThread_breakFlags]
12324    adrl   lr, dvmAsmInstructionStart + (114 * 64)
12325    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12326    cmp    r3, #0
12327    bxeq   lr                   @ nothing to do - jump to real handler
12328    EXPORT_PC()
12329    mov    r0, rPC              @ arg0
12330    mov    r1, rFP              @ arg1
12331    mov    r2, rSELF            @ arg2
12332    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12333
12334/* ------------------------------ */
12335    .balign 64
12336.L_ALT_OP_UNUSED_73: /* 0x73 */
12337/* File: armv5te/alt_stub.S */
12338/*
12339 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12340 * any interesting requests and then jump to the real instruction
12341 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12342 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12343 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12344 * bail to the real handler if breakFlags==0.
12345 */
12346    ldrb   r3, [rSELF, #offThread_breakFlags]
12347    adrl   lr, dvmAsmInstructionStart + (115 * 64)
12348    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12349    cmp    r3, #0
12350    bxeq   lr                   @ nothing to do - jump to real handler
12351    EXPORT_PC()
12352    mov    r0, rPC              @ arg0
12353    mov    r1, rFP              @ arg1
12354    mov    r2, rSELF            @ arg2
12355    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12356
12357/* ------------------------------ */
12358    .balign 64
12359.L_ALT_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
12360/* File: armv5te/alt_stub.S */
12361/*
12362 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12363 * any interesting requests and then jump to the real instruction
12364 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12365 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12366 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12367 * bail to the real handler if breakFlags==0.
12368 */
12369    ldrb   r3, [rSELF, #offThread_breakFlags]
12370    adrl   lr, dvmAsmInstructionStart + (116 * 64)
12371    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12372    cmp    r3, #0
12373    bxeq   lr                   @ nothing to do - jump to real handler
12374    EXPORT_PC()
12375    mov    r0, rPC              @ arg0
12376    mov    r1, rFP              @ arg1
12377    mov    r2, rSELF            @ arg2
12378    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12379
12380/* ------------------------------ */
12381    .balign 64
12382.L_ALT_OP_INVOKE_SUPER_RANGE: /* 0x75 */
12383/* File: armv5te/alt_stub.S */
12384/*
12385 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12386 * any interesting requests and then jump to the real instruction
12387 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12388 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12389 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12390 * bail to the real handler if breakFlags==0.
12391 */
12392    ldrb   r3, [rSELF, #offThread_breakFlags]
12393    adrl   lr, dvmAsmInstructionStart + (117 * 64)
12394    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12395    cmp    r3, #0
12396    bxeq   lr                   @ nothing to do - jump to real handler
12397    EXPORT_PC()
12398    mov    r0, rPC              @ arg0
12399    mov    r1, rFP              @ arg1
12400    mov    r2, rSELF            @ arg2
12401    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12402
12403/* ------------------------------ */
12404    .balign 64
12405.L_ALT_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
12406/* File: armv5te/alt_stub.S */
12407/*
12408 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12409 * any interesting requests and then jump to the real instruction
12410 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12411 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12412 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12413 * bail to the real handler if breakFlags==0.
12414 */
12415    ldrb   r3, [rSELF, #offThread_breakFlags]
12416    adrl   lr, dvmAsmInstructionStart + (118 * 64)
12417    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12418    cmp    r3, #0
12419    bxeq   lr                   @ nothing to do - jump to real handler
12420    EXPORT_PC()
12421    mov    r0, rPC              @ arg0
12422    mov    r1, rFP              @ arg1
12423    mov    r2, rSELF            @ arg2
12424    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12425
12426/* ------------------------------ */
12427    .balign 64
12428.L_ALT_OP_INVOKE_STATIC_RANGE: /* 0x77 */
12429/* File: armv5te/alt_stub.S */
12430/*
12431 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12432 * any interesting requests and then jump to the real instruction
12433 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12434 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12435 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12436 * bail to the real handler if breakFlags==0.
12437 */
12438    ldrb   r3, [rSELF, #offThread_breakFlags]
12439    adrl   lr, dvmAsmInstructionStart + (119 * 64)
12440    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12441    cmp    r3, #0
12442    bxeq   lr                   @ nothing to do - jump to real handler
12443    EXPORT_PC()
12444    mov    r0, rPC              @ arg0
12445    mov    r1, rFP              @ arg1
12446    mov    r2, rSELF            @ arg2
12447    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12448
12449/* ------------------------------ */
12450    .balign 64
12451.L_ALT_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
12452/* File: armv5te/alt_stub.S */
12453/*
12454 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12455 * any interesting requests and then jump to the real instruction
12456 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12457 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12458 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12459 * bail to the real handler if breakFlags==0.
12460 */
12461    ldrb   r3, [rSELF, #offThread_breakFlags]
12462    adrl   lr, dvmAsmInstructionStart + (120 * 64)
12463    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12464    cmp    r3, #0
12465    bxeq   lr                   @ nothing to do - jump to real handler
12466    EXPORT_PC()
12467    mov    r0, rPC              @ arg0
12468    mov    r1, rFP              @ arg1
12469    mov    r2, rSELF            @ arg2
12470    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12471
12472/* ------------------------------ */
12473    .balign 64
12474.L_ALT_OP_UNUSED_79: /* 0x79 */
12475/* File: armv5te/alt_stub.S */
12476/*
12477 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12478 * any interesting requests and then jump to the real instruction
12479 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12480 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12481 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12482 * bail to the real handler if breakFlags==0.
12483 */
12484    ldrb   r3, [rSELF, #offThread_breakFlags]
12485    adrl   lr, dvmAsmInstructionStart + (121 * 64)
12486    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12487    cmp    r3, #0
12488    bxeq   lr                   @ nothing to do - jump to real handler
12489    EXPORT_PC()
12490    mov    r0, rPC              @ arg0
12491    mov    r1, rFP              @ arg1
12492    mov    r2, rSELF            @ arg2
12493    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12494
12495/* ------------------------------ */
12496    .balign 64
12497.L_ALT_OP_UNUSED_7A: /* 0x7a */
12498/* File: armv5te/alt_stub.S */
12499/*
12500 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12501 * any interesting requests and then jump to the real instruction
12502 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12503 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12504 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12505 * bail to the real handler if breakFlags==0.
12506 */
12507    ldrb   r3, [rSELF, #offThread_breakFlags]
12508    adrl   lr, dvmAsmInstructionStart + (122 * 64)
12509    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12510    cmp    r3, #0
12511    bxeq   lr                   @ nothing to do - jump to real handler
12512    EXPORT_PC()
12513    mov    r0, rPC              @ arg0
12514    mov    r1, rFP              @ arg1
12515    mov    r2, rSELF            @ arg2
12516    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12517
12518/* ------------------------------ */
12519    .balign 64
12520.L_ALT_OP_NEG_INT: /* 0x7b */
12521/* File: armv5te/alt_stub.S */
12522/*
12523 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12524 * any interesting requests and then jump to the real instruction
12525 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12526 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12527 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12528 * bail to the real handler if breakFlags==0.
12529 */
12530    ldrb   r3, [rSELF, #offThread_breakFlags]
12531    adrl   lr, dvmAsmInstructionStart + (123 * 64)
12532    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12533    cmp    r3, #0
12534    bxeq   lr                   @ nothing to do - jump to real handler
12535    EXPORT_PC()
12536    mov    r0, rPC              @ arg0
12537    mov    r1, rFP              @ arg1
12538    mov    r2, rSELF            @ arg2
12539    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12540
12541/* ------------------------------ */
12542    .balign 64
12543.L_ALT_OP_NOT_INT: /* 0x7c */
12544/* File: armv5te/alt_stub.S */
12545/*
12546 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12547 * any interesting requests and then jump to the real instruction
12548 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12549 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12550 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12551 * bail to the real handler if breakFlags==0.
12552 */
12553    ldrb   r3, [rSELF, #offThread_breakFlags]
12554    adrl   lr, dvmAsmInstructionStart + (124 * 64)
12555    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12556    cmp    r3, #0
12557    bxeq   lr                   @ nothing to do - jump to real handler
12558    EXPORT_PC()
12559    mov    r0, rPC              @ arg0
12560    mov    r1, rFP              @ arg1
12561    mov    r2, rSELF            @ arg2
12562    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12563
12564/* ------------------------------ */
12565    .balign 64
12566.L_ALT_OP_NEG_LONG: /* 0x7d */
12567/* File: armv5te/alt_stub.S */
12568/*
12569 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12570 * any interesting requests and then jump to the real instruction
12571 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12572 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12573 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12574 * bail to the real handler if breakFlags==0.
12575 */
12576    ldrb   r3, [rSELF, #offThread_breakFlags]
12577    adrl   lr, dvmAsmInstructionStart + (125 * 64)
12578    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12579    cmp    r3, #0
12580    bxeq   lr                   @ nothing to do - jump to real handler
12581    EXPORT_PC()
12582    mov    r0, rPC              @ arg0
12583    mov    r1, rFP              @ arg1
12584    mov    r2, rSELF            @ arg2
12585    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12586
12587/* ------------------------------ */
12588    .balign 64
12589.L_ALT_OP_NOT_LONG: /* 0x7e */
12590/* File: armv5te/alt_stub.S */
12591/*
12592 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12593 * any interesting requests and then jump to the real instruction
12594 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12595 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12596 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12597 * bail to the real handler if breakFlags==0.
12598 */
12599    ldrb   r3, [rSELF, #offThread_breakFlags]
12600    adrl   lr, dvmAsmInstructionStart + (126 * 64)
12601    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12602    cmp    r3, #0
12603    bxeq   lr                   @ nothing to do - jump to real handler
12604    EXPORT_PC()
12605    mov    r0, rPC              @ arg0
12606    mov    r1, rFP              @ arg1
12607    mov    r2, rSELF            @ arg2
12608    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12609
12610/* ------------------------------ */
12611    .balign 64
12612.L_ALT_OP_NEG_FLOAT: /* 0x7f */
12613/* File: armv5te/alt_stub.S */
12614/*
12615 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12616 * any interesting requests and then jump to the real instruction
12617 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12618 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12619 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12620 * bail to the real handler if breakFlags==0.
12621 */
12622    ldrb   r3, [rSELF, #offThread_breakFlags]
12623    adrl   lr, dvmAsmInstructionStart + (127 * 64)
12624    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12625    cmp    r3, #0
12626    bxeq   lr                   @ nothing to do - jump to real handler
12627    EXPORT_PC()
12628    mov    r0, rPC              @ arg0
12629    mov    r1, rFP              @ arg1
12630    mov    r2, rSELF            @ arg2
12631    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12632
12633/* ------------------------------ */
12634    .balign 64
12635.L_ALT_OP_NEG_DOUBLE: /* 0x80 */
12636/* File: armv5te/alt_stub.S */
12637/*
12638 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12639 * any interesting requests and then jump to the real instruction
12640 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12641 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12642 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12643 * bail to the real handler if breakFlags==0.
12644 */
12645    ldrb   r3, [rSELF, #offThread_breakFlags]
12646    adrl   lr, dvmAsmInstructionStart + (128 * 64)
12647    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12648    cmp    r3, #0
12649    bxeq   lr                   @ nothing to do - jump to real handler
12650    EXPORT_PC()
12651    mov    r0, rPC              @ arg0
12652    mov    r1, rFP              @ arg1
12653    mov    r2, rSELF            @ arg2
12654    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12655
12656/* ------------------------------ */
12657    .balign 64
12658.L_ALT_OP_INT_TO_LONG: /* 0x81 */
12659/* File: armv5te/alt_stub.S */
12660/*
12661 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12662 * any interesting requests and then jump to the real instruction
12663 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12664 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12665 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12666 * bail to the real handler if breakFlags==0.
12667 */
12668    ldrb   r3, [rSELF, #offThread_breakFlags]
12669    adrl   lr, dvmAsmInstructionStart + (129 * 64)
12670    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12671    cmp    r3, #0
12672    bxeq   lr                   @ nothing to do - jump to real handler
12673    EXPORT_PC()
12674    mov    r0, rPC              @ arg0
12675    mov    r1, rFP              @ arg1
12676    mov    r2, rSELF            @ arg2
12677    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12678
12679/* ------------------------------ */
12680    .balign 64
12681.L_ALT_OP_INT_TO_FLOAT: /* 0x82 */
12682/* File: armv5te/alt_stub.S */
12683/*
12684 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12685 * any interesting requests and then jump to the real instruction
12686 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12687 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12688 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12689 * bail to the real handler if breakFlags==0.
12690 */
12691    ldrb   r3, [rSELF, #offThread_breakFlags]
12692    adrl   lr, dvmAsmInstructionStart + (130 * 64)
12693    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12694    cmp    r3, #0
12695    bxeq   lr                   @ nothing to do - jump to real handler
12696    EXPORT_PC()
12697    mov    r0, rPC              @ arg0
12698    mov    r1, rFP              @ arg1
12699    mov    r2, rSELF            @ arg2
12700    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12701
12702/* ------------------------------ */
12703    .balign 64
12704.L_ALT_OP_INT_TO_DOUBLE: /* 0x83 */
12705/* File: armv5te/alt_stub.S */
12706/*
12707 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12708 * any interesting requests and then jump to the real instruction
12709 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12710 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12711 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12712 * bail to the real handler if breakFlags==0.
12713 */
12714    ldrb   r3, [rSELF, #offThread_breakFlags]
12715    adrl   lr, dvmAsmInstructionStart + (131 * 64)
12716    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12717    cmp    r3, #0
12718    bxeq   lr                   @ nothing to do - jump to real handler
12719    EXPORT_PC()
12720    mov    r0, rPC              @ arg0
12721    mov    r1, rFP              @ arg1
12722    mov    r2, rSELF            @ arg2
12723    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12724
12725/* ------------------------------ */
12726    .balign 64
12727.L_ALT_OP_LONG_TO_INT: /* 0x84 */
12728/* File: armv5te/alt_stub.S */
12729/*
12730 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12731 * any interesting requests and then jump to the real instruction
12732 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12733 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12734 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12735 * bail to the real handler if breakFlags==0.
12736 */
12737    ldrb   r3, [rSELF, #offThread_breakFlags]
12738    adrl   lr, dvmAsmInstructionStart + (132 * 64)
12739    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12740    cmp    r3, #0
12741    bxeq   lr                   @ nothing to do - jump to real handler
12742    EXPORT_PC()
12743    mov    r0, rPC              @ arg0
12744    mov    r1, rFP              @ arg1
12745    mov    r2, rSELF            @ arg2
12746    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12747
12748/* ------------------------------ */
12749    .balign 64
12750.L_ALT_OP_LONG_TO_FLOAT: /* 0x85 */
12751/* File: armv5te/alt_stub.S */
12752/*
12753 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12754 * any interesting requests and then jump to the real instruction
12755 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12756 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12757 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12758 * bail to the real handler if breakFlags==0.
12759 */
12760    ldrb   r3, [rSELF, #offThread_breakFlags]
12761    adrl   lr, dvmAsmInstructionStart + (133 * 64)
12762    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12763    cmp    r3, #0
12764    bxeq   lr                   @ nothing to do - jump to real handler
12765    EXPORT_PC()
12766    mov    r0, rPC              @ arg0
12767    mov    r1, rFP              @ arg1
12768    mov    r2, rSELF            @ arg2
12769    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12770
12771/* ------------------------------ */
12772    .balign 64
12773.L_ALT_OP_LONG_TO_DOUBLE: /* 0x86 */
12774/* File: armv5te/alt_stub.S */
12775/*
12776 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12777 * any interesting requests and then jump to the real instruction
12778 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12779 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12780 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12781 * bail to the real handler if breakFlags==0.
12782 */
12783    ldrb   r3, [rSELF, #offThread_breakFlags]
12784    adrl   lr, dvmAsmInstructionStart + (134 * 64)
12785    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12786    cmp    r3, #0
12787    bxeq   lr                   @ nothing to do - jump to real handler
12788    EXPORT_PC()
12789    mov    r0, rPC              @ arg0
12790    mov    r1, rFP              @ arg1
12791    mov    r2, rSELF            @ arg2
12792    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12793
12794/* ------------------------------ */
12795    .balign 64
12796.L_ALT_OP_FLOAT_TO_INT: /* 0x87 */
12797/* File: armv5te/alt_stub.S */
12798/*
12799 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12800 * any interesting requests and then jump to the real instruction
12801 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12802 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12803 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12804 * bail to the real handler if breakFlags==0.
12805 */
12806    ldrb   r3, [rSELF, #offThread_breakFlags]
12807    adrl   lr, dvmAsmInstructionStart + (135 * 64)
12808    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12809    cmp    r3, #0
12810    bxeq   lr                   @ nothing to do - jump to real handler
12811    EXPORT_PC()
12812    mov    r0, rPC              @ arg0
12813    mov    r1, rFP              @ arg1
12814    mov    r2, rSELF            @ arg2
12815    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12816
12817/* ------------------------------ */
12818    .balign 64
12819.L_ALT_OP_FLOAT_TO_LONG: /* 0x88 */
12820/* File: armv5te/alt_stub.S */
12821/*
12822 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12823 * any interesting requests and then jump to the real instruction
12824 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12825 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12826 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12827 * bail to the real handler if breakFlags==0.
12828 */
12829    ldrb   r3, [rSELF, #offThread_breakFlags]
12830    adrl   lr, dvmAsmInstructionStart + (136 * 64)
12831    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12832    cmp    r3, #0
12833    bxeq   lr                   @ nothing to do - jump to real handler
12834    EXPORT_PC()
12835    mov    r0, rPC              @ arg0
12836    mov    r1, rFP              @ arg1
12837    mov    r2, rSELF            @ arg2
12838    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12839
12840/* ------------------------------ */
12841    .balign 64
12842.L_ALT_OP_FLOAT_TO_DOUBLE: /* 0x89 */
12843/* File: armv5te/alt_stub.S */
12844/*
12845 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12846 * any interesting requests and then jump to the real instruction
12847 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12848 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12849 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12850 * bail to the real handler if breakFlags==0.
12851 */
12852    ldrb   r3, [rSELF, #offThread_breakFlags]
12853    adrl   lr, dvmAsmInstructionStart + (137 * 64)
12854    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12855    cmp    r3, #0
12856    bxeq   lr                   @ nothing to do - jump to real handler
12857    EXPORT_PC()
12858    mov    r0, rPC              @ arg0
12859    mov    r1, rFP              @ arg1
12860    mov    r2, rSELF            @ arg2
12861    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12862
12863/* ------------------------------ */
12864    .balign 64
12865.L_ALT_OP_DOUBLE_TO_INT: /* 0x8a */
12866/* File: armv5te/alt_stub.S */
12867/*
12868 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12869 * any interesting requests and then jump to the real instruction
12870 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12871 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12872 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12873 * bail to the real handler if breakFlags==0.
12874 */
12875    ldrb   r3, [rSELF, #offThread_breakFlags]
12876    adrl   lr, dvmAsmInstructionStart + (138 * 64)
12877    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12878    cmp    r3, #0
12879    bxeq   lr                   @ nothing to do - jump to real handler
12880    EXPORT_PC()
12881    mov    r0, rPC              @ arg0
12882    mov    r1, rFP              @ arg1
12883    mov    r2, rSELF            @ arg2
12884    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12885
12886/* ------------------------------ */
12887    .balign 64
12888.L_ALT_OP_DOUBLE_TO_LONG: /* 0x8b */
12889/* File: armv5te/alt_stub.S */
12890/*
12891 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12892 * any interesting requests and then jump to the real instruction
12893 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12894 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12895 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12896 * bail to the real handler if breakFlags==0.
12897 */
12898    ldrb   r3, [rSELF, #offThread_breakFlags]
12899    adrl   lr, dvmAsmInstructionStart + (139 * 64)
12900    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12901    cmp    r3, #0
12902    bxeq   lr                   @ nothing to do - jump to real handler
12903    EXPORT_PC()
12904    mov    r0, rPC              @ arg0
12905    mov    r1, rFP              @ arg1
12906    mov    r2, rSELF            @ arg2
12907    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12908
12909/* ------------------------------ */
12910    .balign 64
12911.L_ALT_OP_DOUBLE_TO_FLOAT: /* 0x8c */
12912/* File: armv5te/alt_stub.S */
12913/*
12914 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12915 * any interesting requests and then jump to the real instruction
12916 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12917 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12918 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12919 * bail to the real handler if breakFlags==0.
12920 */
12921    ldrb   r3, [rSELF, #offThread_breakFlags]
12922    adrl   lr, dvmAsmInstructionStart + (140 * 64)
12923    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12924    cmp    r3, #0
12925    bxeq   lr                   @ nothing to do - jump to real handler
12926    EXPORT_PC()
12927    mov    r0, rPC              @ arg0
12928    mov    r1, rFP              @ arg1
12929    mov    r2, rSELF            @ arg2
12930    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12931
12932/* ------------------------------ */
12933    .balign 64
12934.L_ALT_OP_INT_TO_BYTE: /* 0x8d */
12935/* File: armv5te/alt_stub.S */
12936/*
12937 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12938 * any interesting requests and then jump to the real instruction
12939 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12940 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12941 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12942 * bail to the real handler if breakFlags==0.
12943 */
12944    ldrb   r3, [rSELF, #offThread_breakFlags]
12945    adrl   lr, dvmAsmInstructionStart + (141 * 64)
12946    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12947    cmp    r3, #0
12948    bxeq   lr                   @ nothing to do - jump to real handler
12949    EXPORT_PC()
12950    mov    r0, rPC              @ arg0
12951    mov    r1, rFP              @ arg1
12952    mov    r2, rSELF            @ arg2
12953    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12954
12955/* ------------------------------ */
12956    .balign 64
12957.L_ALT_OP_INT_TO_CHAR: /* 0x8e */
12958/* File: armv5te/alt_stub.S */
12959/*
12960 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12961 * any interesting requests and then jump to the real instruction
12962 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12963 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12964 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12965 * bail to the real handler if breakFlags==0.
12966 */
12967    ldrb   r3, [rSELF, #offThread_breakFlags]
12968    adrl   lr, dvmAsmInstructionStart + (142 * 64)
12969    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12970    cmp    r3, #0
12971    bxeq   lr                   @ nothing to do - jump to real handler
12972    EXPORT_PC()
12973    mov    r0, rPC              @ arg0
12974    mov    r1, rFP              @ arg1
12975    mov    r2, rSELF            @ arg2
12976    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12977
12978/* ------------------------------ */
12979    .balign 64
12980.L_ALT_OP_INT_TO_SHORT: /* 0x8f */
12981/* File: armv5te/alt_stub.S */
12982/*
12983 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12984 * any interesting requests and then jump to the real instruction
12985 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12986 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12987 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12988 * bail to the real handler if breakFlags==0.
12989 */
12990    ldrb   r3, [rSELF, #offThread_breakFlags]
12991    adrl   lr, dvmAsmInstructionStart + (143 * 64)
12992    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12993    cmp    r3, #0
12994    bxeq   lr                   @ nothing to do - jump to real handler
12995    EXPORT_PC()
12996    mov    r0, rPC              @ arg0
12997    mov    r1, rFP              @ arg1
12998    mov    r2, rSELF            @ arg2
12999    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13000
13001/* ------------------------------ */
13002    .balign 64
13003.L_ALT_OP_ADD_INT: /* 0x90 */
13004/* File: armv5te/alt_stub.S */
13005/*
13006 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13007 * any interesting requests and then jump to the real instruction
13008 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13009 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13010 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13011 * bail to the real handler if breakFlags==0.
13012 */
13013    ldrb   r3, [rSELF, #offThread_breakFlags]
13014    adrl   lr, dvmAsmInstructionStart + (144 * 64)
13015    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13016    cmp    r3, #0
13017    bxeq   lr                   @ nothing to do - jump to real handler
13018    EXPORT_PC()
13019    mov    r0, rPC              @ arg0
13020    mov    r1, rFP              @ arg1
13021    mov    r2, rSELF            @ arg2
13022    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13023
13024/* ------------------------------ */
13025    .balign 64
13026.L_ALT_OP_SUB_INT: /* 0x91 */
13027/* File: armv5te/alt_stub.S */
13028/*
13029 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13030 * any interesting requests and then jump to the real instruction
13031 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13032 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13033 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13034 * bail to the real handler if breakFlags==0.
13035 */
13036    ldrb   r3, [rSELF, #offThread_breakFlags]
13037    adrl   lr, dvmAsmInstructionStart + (145 * 64)
13038    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13039    cmp    r3, #0
13040    bxeq   lr                   @ nothing to do - jump to real handler
13041    EXPORT_PC()
13042    mov    r0, rPC              @ arg0
13043    mov    r1, rFP              @ arg1
13044    mov    r2, rSELF            @ arg2
13045    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13046
13047/* ------------------------------ */
13048    .balign 64
13049.L_ALT_OP_MUL_INT: /* 0x92 */
13050/* File: armv5te/alt_stub.S */
13051/*
13052 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13053 * any interesting requests and then jump to the real instruction
13054 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13055 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13056 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13057 * bail to the real handler if breakFlags==0.
13058 */
13059    ldrb   r3, [rSELF, #offThread_breakFlags]
13060    adrl   lr, dvmAsmInstructionStart + (146 * 64)
13061    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13062    cmp    r3, #0
13063    bxeq   lr                   @ nothing to do - jump to real handler
13064    EXPORT_PC()
13065    mov    r0, rPC              @ arg0
13066    mov    r1, rFP              @ arg1
13067    mov    r2, rSELF            @ arg2
13068    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13069
13070/* ------------------------------ */
13071    .balign 64
13072.L_ALT_OP_DIV_INT: /* 0x93 */
13073/* File: armv5te/alt_stub.S */
13074/*
13075 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13076 * any interesting requests and then jump to the real instruction
13077 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13078 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13079 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13080 * bail to the real handler if breakFlags==0.
13081 */
13082    ldrb   r3, [rSELF, #offThread_breakFlags]
13083    adrl   lr, dvmAsmInstructionStart + (147 * 64)
13084    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13085    cmp    r3, #0
13086    bxeq   lr                   @ nothing to do - jump to real handler
13087    EXPORT_PC()
13088    mov    r0, rPC              @ arg0
13089    mov    r1, rFP              @ arg1
13090    mov    r2, rSELF            @ arg2
13091    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13092
13093/* ------------------------------ */
13094    .balign 64
13095.L_ALT_OP_REM_INT: /* 0x94 */
13096/* File: armv5te/alt_stub.S */
13097/*
13098 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13099 * any interesting requests and then jump to the real instruction
13100 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13101 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13102 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13103 * bail to the real handler if breakFlags==0.
13104 */
13105    ldrb   r3, [rSELF, #offThread_breakFlags]
13106    adrl   lr, dvmAsmInstructionStart + (148 * 64)
13107    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13108    cmp    r3, #0
13109    bxeq   lr                   @ nothing to do - jump to real handler
13110    EXPORT_PC()
13111    mov    r0, rPC              @ arg0
13112    mov    r1, rFP              @ arg1
13113    mov    r2, rSELF            @ arg2
13114    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13115
13116/* ------------------------------ */
13117    .balign 64
13118.L_ALT_OP_AND_INT: /* 0x95 */
13119/* File: armv5te/alt_stub.S */
13120/*
13121 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13122 * any interesting requests and then jump to the real instruction
13123 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13124 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13125 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13126 * bail to the real handler if breakFlags==0.
13127 */
13128    ldrb   r3, [rSELF, #offThread_breakFlags]
13129    adrl   lr, dvmAsmInstructionStart + (149 * 64)
13130    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13131    cmp    r3, #0
13132    bxeq   lr                   @ nothing to do - jump to real handler
13133    EXPORT_PC()
13134    mov    r0, rPC              @ arg0
13135    mov    r1, rFP              @ arg1
13136    mov    r2, rSELF            @ arg2
13137    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13138
13139/* ------------------------------ */
13140    .balign 64
13141.L_ALT_OP_OR_INT: /* 0x96 */
13142/* File: armv5te/alt_stub.S */
13143/*
13144 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13145 * any interesting requests and then jump to the real instruction
13146 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13147 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13148 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13149 * bail to the real handler if breakFlags==0.
13150 */
13151    ldrb   r3, [rSELF, #offThread_breakFlags]
13152    adrl   lr, dvmAsmInstructionStart + (150 * 64)
13153    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13154    cmp    r3, #0
13155    bxeq   lr                   @ nothing to do - jump to real handler
13156    EXPORT_PC()
13157    mov    r0, rPC              @ arg0
13158    mov    r1, rFP              @ arg1
13159    mov    r2, rSELF            @ arg2
13160    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13161
13162/* ------------------------------ */
13163    .balign 64
13164.L_ALT_OP_XOR_INT: /* 0x97 */
13165/* File: armv5te/alt_stub.S */
13166/*
13167 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13168 * any interesting requests and then jump to the real instruction
13169 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13170 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13171 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13172 * bail to the real handler if breakFlags==0.
13173 */
13174    ldrb   r3, [rSELF, #offThread_breakFlags]
13175    adrl   lr, dvmAsmInstructionStart + (151 * 64)
13176    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13177    cmp    r3, #0
13178    bxeq   lr                   @ nothing to do - jump to real handler
13179    EXPORT_PC()
13180    mov    r0, rPC              @ arg0
13181    mov    r1, rFP              @ arg1
13182    mov    r2, rSELF            @ arg2
13183    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13184
13185/* ------------------------------ */
13186    .balign 64
13187.L_ALT_OP_SHL_INT: /* 0x98 */
13188/* File: armv5te/alt_stub.S */
13189/*
13190 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13191 * any interesting requests and then jump to the real instruction
13192 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13193 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13194 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13195 * bail to the real handler if breakFlags==0.
13196 */
13197    ldrb   r3, [rSELF, #offThread_breakFlags]
13198    adrl   lr, dvmAsmInstructionStart + (152 * 64)
13199    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13200    cmp    r3, #0
13201    bxeq   lr                   @ nothing to do - jump to real handler
13202    EXPORT_PC()
13203    mov    r0, rPC              @ arg0
13204    mov    r1, rFP              @ arg1
13205    mov    r2, rSELF            @ arg2
13206    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13207
13208/* ------------------------------ */
13209    .balign 64
13210.L_ALT_OP_SHR_INT: /* 0x99 */
13211/* File: armv5te/alt_stub.S */
13212/*
13213 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13214 * any interesting requests and then jump to the real instruction
13215 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13216 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13217 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13218 * bail to the real handler if breakFlags==0.
13219 */
13220    ldrb   r3, [rSELF, #offThread_breakFlags]
13221    adrl   lr, dvmAsmInstructionStart + (153 * 64)
13222    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13223    cmp    r3, #0
13224    bxeq   lr                   @ nothing to do - jump to real handler
13225    EXPORT_PC()
13226    mov    r0, rPC              @ arg0
13227    mov    r1, rFP              @ arg1
13228    mov    r2, rSELF            @ arg2
13229    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13230
13231/* ------------------------------ */
13232    .balign 64
13233.L_ALT_OP_USHR_INT: /* 0x9a */
13234/* File: armv5te/alt_stub.S */
13235/*
13236 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13237 * any interesting requests and then jump to the real instruction
13238 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13239 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13240 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13241 * bail to the real handler if breakFlags==0.
13242 */
13243    ldrb   r3, [rSELF, #offThread_breakFlags]
13244    adrl   lr, dvmAsmInstructionStart + (154 * 64)
13245    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13246    cmp    r3, #0
13247    bxeq   lr                   @ nothing to do - jump to real handler
13248    EXPORT_PC()
13249    mov    r0, rPC              @ arg0
13250    mov    r1, rFP              @ arg1
13251    mov    r2, rSELF            @ arg2
13252    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13253
13254/* ------------------------------ */
13255    .balign 64
13256.L_ALT_OP_ADD_LONG: /* 0x9b */
13257/* File: armv5te/alt_stub.S */
13258/*
13259 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13260 * any interesting requests and then jump to the real instruction
13261 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13262 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13263 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13264 * bail to the real handler if breakFlags==0.
13265 */
13266    ldrb   r3, [rSELF, #offThread_breakFlags]
13267    adrl   lr, dvmAsmInstructionStart + (155 * 64)
13268    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13269    cmp    r3, #0
13270    bxeq   lr                   @ nothing to do - jump to real handler
13271    EXPORT_PC()
13272    mov    r0, rPC              @ arg0
13273    mov    r1, rFP              @ arg1
13274    mov    r2, rSELF            @ arg2
13275    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13276
13277/* ------------------------------ */
13278    .balign 64
13279.L_ALT_OP_SUB_LONG: /* 0x9c */
13280/* File: armv5te/alt_stub.S */
13281/*
13282 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13283 * any interesting requests and then jump to the real instruction
13284 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13285 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13286 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13287 * bail to the real handler if breakFlags==0.
13288 */
13289    ldrb   r3, [rSELF, #offThread_breakFlags]
13290    adrl   lr, dvmAsmInstructionStart + (156 * 64)
13291    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13292    cmp    r3, #0
13293    bxeq   lr                   @ nothing to do - jump to real handler
13294    EXPORT_PC()
13295    mov    r0, rPC              @ arg0
13296    mov    r1, rFP              @ arg1
13297    mov    r2, rSELF            @ arg2
13298    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13299
13300/* ------------------------------ */
13301    .balign 64
13302.L_ALT_OP_MUL_LONG: /* 0x9d */
13303/* File: armv5te/alt_stub.S */
13304/*
13305 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13306 * any interesting requests and then jump to the real instruction
13307 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13308 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13309 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13310 * bail to the real handler if breakFlags==0.
13311 */
13312    ldrb   r3, [rSELF, #offThread_breakFlags]
13313    adrl   lr, dvmAsmInstructionStart + (157 * 64)
13314    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13315    cmp    r3, #0
13316    bxeq   lr                   @ nothing to do - jump to real handler
13317    EXPORT_PC()
13318    mov    r0, rPC              @ arg0
13319    mov    r1, rFP              @ arg1
13320    mov    r2, rSELF            @ arg2
13321    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13322
13323/* ------------------------------ */
13324    .balign 64
13325.L_ALT_OP_DIV_LONG: /* 0x9e */
13326/* File: armv5te/alt_stub.S */
13327/*
13328 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13329 * any interesting requests and then jump to the real instruction
13330 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13331 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13332 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13333 * bail to the real handler if breakFlags==0.
13334 */
13335    ldrb   r3, [rSELF, #offThread_breakFlags]
13336    adrl   lr, dvmAsmInstructionStart + (158 * 64)
13337    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13338    cmp    r3, #0
13339    bxeq   lr                   @ nothing to do - jump to real handler
13340    EXPORT_PC()
13341    mov    r0, rPC              @ arg0
13342    mov    r1, rFP              @ arg1
13343    mov    r2, rSELF            @ arg2
13344    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13345
13346/* ------------------------------ */
13347    .balign 64
13348.L_ALT_OP_REM_LONG: /* 0x9f */
13349/* File: armv5te/alt_stub.S */
13350/*
13351 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13352 * any interesting requests and then jump to the real instruction
13353 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13354 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13355 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13356 * bail to the real handler if breakFlags==0.
13357 */
13358    ldrb   r3, [rSELF, #offThread_breakFlags]
13359    adrl   lr, dvmAsmInstructionStart + (159 * 64)
13360    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13361    cmp    r3, #0
13362    bxeq   lr                   @ nothing to do - jump to real handler
13363    EXPORT_PC()
13364    mov    r0, rPC              @ arg0
13365    mov    r1, rFP              @ arg1
13366    mov    r2, rSELF            @ arg2
13367    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13368
13369/* ------------------------------ */
13370    .balign 64
13371.L_ALT_OP_AND_LONG: /* 0xa0 */
13372/* File: armv5te/alt_stub.S */
13373/*
13374 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13375 * any interesting requests and then jump to the real instruction
13376 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13377 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13378 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13379 * bail to the real handler if breakFlags==0.
13380 */
13381    ldrb   r3, [rSELF, #offThread_breakFlags]
13382    adrl   lr, dvmAsmInstructionStart + (160 * 64)
13383    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13384    cmp    r3, #0
13385    bxeq   lr                   @ nothing to do - jump to real handler
13386    EXPORT_PC()
13387    mov    r0, rPC              @ arg0
13388    mov    r1, rFP              @ arg1
13389    mov    r2, rSELF            @ arg2
13390    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13391
13392/* ------------------------------ */
13393    .balign 64
13394.L_ALT_OP_OR_LONG: /* 0xa1 */
13395/* File: armv5te/alt_stub.S */
13396/*
13397 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13398 * any interesting requests and then jump to the real instruction
13399 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13400 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13401 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13402 * bail to the real handler if breakFlags==0.
13403 */
13404    ldrb   r3, [rSELF, #offThread_breakFlags]
13405    adrl   lr, dvmAsmInstructionStart + (161 * 64)
13406    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13407    cmp    r3, #0
13408    bxeq   lr                   @ nothing to do - jump to real handler
13409    EXPORT_PC()
13410    mov    r0, rPC              @ arg0
13411    mov    r1, rFP              @ arg1
13412    mov    r2, rSELF            @ arg2
13413    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13414
13415/* ------------------------------ */
13416    .balign 64
13417.L_ALT_OP_XOR_LONG: /* 0xa2 */
13418/* File: armv5te/alt_stub.S */
13419/*
13420 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13421 * any interesting requests and then jump to the real instruction
13422 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13423 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13424 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13425 * bail to the real handler if breakFlags==0.
13426 */
13427    ldrb   r3, [rSELF, #offThread_breakFlags]
13428    adrl   lr, dvmAsmInstructionStart + (162 * 64)
13429    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13430    cmp    r3, #0
13431    bxeq   lr                   @ nothing to do - jump to real handler
13432    EXPORT_PC()
13433    mov    r0, rPC              @ arg0
13434    mov    r1, rFP              @ arg1
13435    mov    r2, rSELF            @ arg2
13436    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13437
13438/* ------------------------------ */
13439    .balign 64
13440.L_ALT_OP_SHL_LONG: /* 0xa3 */
13441/* File: armv5te/alt_stub.S */
13442/*
13443 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13444 * any interesting requests and then jump to the real instruction
13445 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13446 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13447 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13448 * bail to the real handler if breakFlags==0.
13449 */
13450    ldrb   r3, [rSELF, #offThread_breakFlags]
13451    adrl   lr, dvmAsmInstructionStart + (163 * 64)
13452    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13453    cmp    r3, #0
13454    bxeq   lr                   @ nothing to do - jump to real handler
13455    EXPORT_PC()
13456    mov    r0, rPC              @ arg0
13457    mov    r1, rFP              @ arg1
13458    mov    r2, rSELF            @ arg2
13459    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13460
13461/* ------------------------------ */
13462    .balign 64
13463.L_ALT_OP_SHR_LONG: /* 0xa4 */
13464/* File: armv5te/alt_stub.S */
13465/*
13466 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13467 * any interesting requests and then jump to the real instruction
13468 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13469 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13470 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13471 * bail to the real handler if breakFlags==0.
13472 */
13473    ldrb   r3, [rSELF, #offThread_breakFlags]
13474    adrl   lr, dvmAsmInstructionStart + (164 * 64)
13475    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13476    cmp    r3, #0
13477    bxeq   lr                   @ nothing to do - jump to real handler
13478    EXPORT_PC()
13479    mov    r0, rPC              @ arg0
13480    mov    r1, rFP              @ arg1
13481    mov    r2, rSELF            @ arg2
13482    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13483
13484/* ------------------------------ */
13485    .balign 64
13486.L_ALT_OP_USHR_LONG: /* 0xa5 */
13487/* File: armv5te/alt_stub.S */
13488/*
13489 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13490 * any interesting requests and then jump to the real instruction
13491 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13492 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13493 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13494 * bail to the real handler if breakFlags==0.
13495 */
13496    ldrb   r3, [rSELF, #offThread_breakFlags]
13497    adrl   lr, dvmAsmInstructionStart + (165 * 64)
13498    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13499    cmp    r3, #0
13500    bxeq   lr                   @ nothing to do - jump to real handler
13501    EXPORT_PC()
13502    mov    r0, rPC              @ arg0
13503    mov    r1, rFP              @ arg1
13504    mov    r2, rSELF            @ arg2
13505    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13506
13507/* ------------------------------ */
13508    .balign 64
13509.L_ALT_OP_ADD_FLOAT: /* 0xa6 */
13510/* File: armv5te/alt_stub.S */
13511/*
13512 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13513 * any interesting requests and then jump to the real instruction
13514 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13515 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13516 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13517 * bail to the real handler if breakFlags==0.
13518 */
13519    ldrb   r3, [rSELF, #offThread_breakFlags]
13520    adrl   lr, dvmAsmInstructionStart + (166 * 64)
13521    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13522    cmp    r3, #0
13523    bxeq   lr                   @ nothing to do - jump to real handler
13524    EXPORT_PC()
13525    mov    r0, rPC              @ arg0
13526    mov    r1, rFP              @ arg1
13527    mov    r2, rSELF            @ arg2
13528    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13529
13530/* ------------------------------ */
13531    .balign 64
13532.L_ALT_OP_SUB_FLOAT: /* 0xa7 */
13533/* File: armv5te/alt_stub.S */
13534/*
13535 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13536 * any interesting requests and then jump to the real instruction
13537 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13538 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13539 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13540 * bail to the real handler if breakFlags==0.
13541 */
13542    ldrb   r3, [rSELF, #offThread_breakFlags]
13543    adrl   lr, dvmAsmInstructionStart + (167 * 64)
13544    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13545    cmp    r3, #0
13546    bxeq   lr                   @ nothing to do - jump to real handler
13547    EXPORT_PC()
13548    mov    r0, rPC              @ arg0
13549    mov    r1, rFP              @ arg1
13550    mov    r2, rSELF            @ arg2
13551    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13552
13553/* ------------------------------ */
13554    .balign 64
13555.L_ALT_OP_MUL_FLOAT: /* 0xa8 */
13556/* File: armv5te/alt_stub.S */
13557/*
13558 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13559 * any interesting requests and then jump to the real instruction
13560 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13561 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13562 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13563 * bail to the real handler if breakFlags==0.
13564 */
13565    ldrb   r3, [rSELF, #offThread_breakFlags]
13566    adrl   lr, dvmAsmInstructionStart + (168 * 64)
13567    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13568    cmp    r3, #0
13569    bxeq   lr                   @ nothing to do - jump to real handler
13570    EXPORT_PC()
13571    mov    r0, rPC              @ arg0
13572    mov    r1, rFP              @ arg1
13573    mov    r2, rSELF            @ arg2
13574    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13575
13576/* ------------------------------ */
13577    .balign 64
13578.L_ALT_OP_DIV_FLOAT: /* 0xa9 */
13579/* File: armv5te/alt_stub.S */
13580/*
13581 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13582 * any interesting requests and then jump to the real instruction
13583 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13584 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13585 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13586 * bail to the real handler if breakFlags==0.
13587 */
13588    ldrb   r3, [rSELF, #offThread_breakFlags]
13589    adrl   lr, dvmAsmInstructionStart + (169 * 64)
13590    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13591    cmp    r3, #0
13592    bxeq   lr                   @ nothing to do - jump to real handler
13593    EXPORT_PC()
13594    mov    r0, rPC              @ arg0
13595    mov    r1, rFP              @ arg1
13596    mov    r2, rSELF            @ arg2
13597    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13598
13599/* ------------------------------ */
13600    .balign 64
13601.L_ALT_OP_REM_FLOAT: /* 0xaa */
13602/* File: armv5te/alt_stub.S */
13603/*
13604 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13605 * any interesting requests and then jump to the real instruction
13606 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13607 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13608 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13609 * bail to the real handler if breakFlags==0.
13610 */
13611    ldrb   r3, [rSELF, #offThread_breakFlags]
13612    adrl   lr, dvmAsmInstructionStart + (170 * 64)
13613    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13614    cmp    r3, #0
13615    bxeq   lr                   @ nothing to do - jump to real handler
13616    EXPORT_PC()
13617    mov    r0, rPC              @ arg0
13618    mov    r1, rFP              @ arg1
13619    mov    r2, rSELF            @ arg2
13620    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13621
13622/* ------------------------------ */
13623    .balign 64
13624.L_ALT_OP_ADD_DOUBLE: /* 0xab */
13625/* File: armv5te/alt_stub.S */
13626/*
13627 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13628 * any interesting requests and then jump to the real instruction
13629 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13630 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13631 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13632 * bail to the real handler if breakFlags==0.
13633 */
13634    ldrb   r3, [rSELF, #offThread_breakFlags]
13635    adrl   lr, dvmAsmInstructionStart + (171 * 64)
13636    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13637    cmp    r3, #0
13638    bxeq   lr                   @ nothing to do - jump to real handler
13639    EXPORT_PC()
13640    mov    r0, rPC              @ arg0
13641    mov    r1, rFP              @ arg1
13642    mov    r2, rSELF            @ arg2
13643    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13644
13645/* ------------------------------ */
13646    .balign 64
13647.L_ALT_OP_SUB_DOUBLE: /* 0xac */
13648/* File: armv5te/alt_stub.S */
13649/*
13650 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13651 * any interesting requests and then jump to the real instruction
13652 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13653 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13654 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13655 * bail to the real handler if breakFlags==0.
13656 */
13657    ldrb   r3, [rSELF, #offThread_breakFlags]
13658    adrl   lr, dvmAsmInstructionStart + (172 * 64)
13659    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13660    cmp    r3, #0
13661    bxeq   lr                   @ nothing to do - jump to real handler
13662    EXPORT_PC()
13663    mov    r0, rPC              @ arg0
13664    mov    r1, rFP              @ arg1
13665    mov    r2, rSELF            @ arg2
13666    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13667
13668/* ------------------------------ */
13669    .balign 64
13670.L_ALT_OP_MUL_DOUBLE: /* 0xad */
13671/* File: armv5te/alt_stub.S */
13672/*
13673 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13674 * any interesting requests and then jump to the real instruction
13675 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13676 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13677 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13678 * bail to the real handler if breakFlags==0.
13679 */
13680    ldrb   r3, [rSELF, #offThread_breakFlags]
13681    adrl   lr, dvmAsmInstructionStart + (173 * 64)
13682    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13683    cmp    r3, #0
13684    bxeq   lr                   @ nothing to do - jump to real handler
13685    EXPORT_PC()
13686    mov    r0, rPC              @ arg0
13687    mov    r1, rFP              @ arg1
13688    mov    r2, rSELF            @ arg2
13689    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13690
13691/* ------------------------------ */
13692    .balign 64
13693.L_ALT_OP_DIV_DOUBLE: /* 0xae */
13694/* File: armv5te/alt_stub.S */
13695/*
13696 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13697 * any interesting requests and then jump to the real instruction
13698 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13699 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13700 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13701 * bail to the real handler if breakFlags==0.
13702 */
13703    ldrb   r3, [rSELF, #offThread_breakFlags]
13704    adrl   lr, dvmAsmInstructionStart + (174 * 64)
13705    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13706    cmp    r3, #0
13707    bxeq   lr                   @ nothing to do - jump to real handler
13708    EXPORT_PC()
13709    mov    r0, rPC              @ arg0
13710    mov    r1, rFP              @ arg1
13711    mov    r2, rSELF            @ arg2
13712    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13713
13714/* ------------------------------ */
13715    .balign 64
13716.L_ALT_OP_REM_DOUBLE: /* 0xaf */
13717/* File: armv5te/alt_stub.S */
13718/*
13719 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13720 * any interesting requests and then jump to the real instruction
13721 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13722 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13723 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13724 * bail to the real handler if breakFlags==0.
13725 */
13726    ldrb   r3, [rSELF, #offThread_breakFlags]
13727    adrl   lr, dvmAsmInstructionStart + (175 * 64)
13728    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13729    cmp    r3, #0
13730    bxeq   lr                   @ nothing to do - jump to real handler
13731    EXPORT_PC()
13732    mov    r0, rPC              @ arg0
13733    mov    r1, rFP              @ arg1
13734    mov    r2, rSELF            @ arg2
13735    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13736
13737/* ------------------------------ */
13738    .balign 64
13739.L_ALT_OP_ADD_INT_2ADDR: /* 0xb0 */
13740/* File: armv5te/alt_stub.S */
13741/*
13742 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13743 * any interesting requests and then jump to the real instruction
13744 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13745 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13746 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13747 * bail to the real handler if breakFlags==0.
13748 */
13749    ldrb   r3, [rSELF, #offThread_breakFlags]
13750    adrl   lr, dvmAsmInstructionStart + (176 * 64)
13751    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13752    cmp    r3, #0
13753    bxeq   lr                   @ nothing to do - jump to real handler
13754    EXPORT_PC()
13755    mov    r0, rPC              @ arg0
13756    mov    r1, rFP              @ arg1
13757    mov    r2, rSELF            @ arg2
13758    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13759
13760/* ------------------------------ */
13761    .balign 64
13762.L_ALT_OP_SUB_INT_2ADDR: /* 0xb1 */
13763/* File: armv5te/alt_stub.S */
13764/*
13765 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13766 * any interesting requests and then jump to the real instruction
13767 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13768 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13769 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13770 * bail to the real handler if breakFlags==0.
13771 */
13772    ldrb   r3, [rSELF, #offThread_breakFlags]
13773    adrl   lr, dvmAsmInstructionStart + (177 * 64)
13774    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13775    cmp    r3, #0
13776    bxeq   lr                   @ nothing to do - jump to real handler
13777    EXPORT_PC()
13778    mov    r0, rPC              @ arg0
13779    mov    r1, rFP              @ arg1
13780    mov    r2, rSELF            @ arg2
13781    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13782
13783/* ------------------------------ */
13784    .balign 64
13785.L_ALT_OP_MUL_INT_2ADDR: /* 0xb2 */
13786/* File: armv5te/alt_stub.S */
13787/*
13788 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13789 * any interesting requests and then jump to the real instruction
13790 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13791 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13792 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13793 * bail to the real handler if breakFlags==0.
13794 */
13795    ldrb   r3, [rSELF, #offThread_breakFlags]
13796    adrl   lr, dvmAsmInstructionStart + (178 * 64)
13797    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13798    cmp    r3, #0
13799    bxeq   lr                   @ nothing to do - jump to real handler
13800    EXPORT_PC()
13801    mov    r0, rPC              @ arg0
13802    mov    r1, rFP              @ arg1
13803    mov    r2, rSELF            @ arg2
13804    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13805
13806/* ------------------------------ */
13807    .balign 64
13808.L_ALT_OP_DIV_INT_2ADDR: /* 0xb3 */
13809/* File: armv5te/alt_stub.S */
13810/*
13811 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13812 * any interesting requests and then jump to the real instruction
13813 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13814 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13815 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13816 * bail to the real handler if breakFlags==0.
13817 */
13818    ldrb   r3, [rSELF, #offThread_breakFlags]
13819    adrl   lr, dvmAsmInstructionStart + (179 * 64)
13820    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13821    cmp    r3, #0
13822    bxeq   lr                   @ nothing to do - jump to real handler
13823    EXPORT_PC()
13824    mov    r0, rPC              @ arg0
13825    mov    r1, rFP              @ arg1
13826    mov    r2, rSELF            @ arg2
13827    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13828
13829/* ------------------------------ */
13830    .balign 64
13831.L_ALT_OP_REM_INT_2ADDR: /* 0xb4 */
13832/* File: armv5te/alt_stub.S */
13833/*
13834 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13835 * any interesting requests and then jump to the real instruction
13836 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13837 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13838 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13839 * bail to the real handler if breakFlags==0.
13840 */
13841    ldrb   r3, [rSELF, #offThread_breakFlags]
13842    adrl   lr, dvmAsmInstructionStart + (180 * 64)
13843    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13844    cmp    r3, #0
13845    bxeq   lr                   @ nothing to do - jump to real handler
13846    EXPORT_PC()
13847    mov    r0, rPC              @ arg0
13848    mov    r1, rFP              @ arg1
13849    mov    r2, rSELF            @ arg2
13850    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13851
13852/* ------------------------------ */
13853    .balign 64
13854.L_ALT_OP_AND_INT_2ADDR: /* 0xb5 */
13855/* File: armv5te/alt_stub.S */
13856/*
13857 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13858 * any interesting requests and then jump to the real instruction
13859 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13860 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13861 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13862 * bail to the real handler if breakFlags==0.
13863 */
13864    ldrb   r3, [rSELF, #offThread_breakFlags]
13865    adrl   lr, dvmAsmInstructionStart + (181 * 64)
13866    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13867    cmp    r3, #0
13868    bxeq   lr                   @ nothing to do - jump to real handler
13869    EXPORT_PC()
13870    mov    r0, rPC              @ arg0
13871    mov    r1, rFP              @ arg1
13872    mov    r2, rSELF            @ arg2
13873    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13874
13875/* ------------------------------ */
13876    .balign 64
13877.L_ALT_OP_OR_INT_2ADDR: /* 0xb6 */
13878/* File: armv5te/alt_stub.S */
13879/*
13880 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13881 * any interesting requests and then jump to the real instruction
13882 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13883 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13884 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13885 * bail to the real handler if breakFlags==0.
13886 */
13887    ldrb   r3, [rSELF, #offThread_breakFlags]
13888    adrl   lr, dvmAsmInstructionStart + (182 * 64)
13889    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13890    cmp    r3, #0
13891    bxeq   lr                   @ nothing to do - jump to real handler
13892    EXPORT_PC()
13893    mov    r0, rPC              @ arg0
13894    mov    r1, rFP              @ arg1
13895    mov    r2, rSELF            @ arg2
13896    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13897
13898/* ------------------------------ */
13899    .balign 64
13900.L_ALT_OP_XOR_INT_2ADDR: /* 0xb7 */
13901/* File: armv5te/alt_stub.S */
13902/*
13903 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13904 * any interesting requests and then jump to the real instruction
13905 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13906 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13907 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13908 * bail to the real handler if breakFlags==0.
13909 */
13910    ldrb   r3, [rSELF, #offThread_breakFlags]
13911    adrl   lr, dvmAsmInstructionStart + (183 * 64)
13912    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13913    cmp    r3, #0
13914    bxeq   lr                   @ nothing to do - jump to real handler
13915    EXPORT_PC()
13916    mov    r0, rPC              @ arg0
13917    mov    r1, rFP              @ arg1
13918    mov    r2, rSELF            @ arg2
13919    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13920
13921/* ------------------------------ */
13922    .balign 64
13923.L_ALT_OP_SHL_INT_2ADDR: /* 0xb8 */
13924/* File: armv5te/alt_stub.S */
13925/*
13926 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13927 * any interesting requests and then jump to the real instruction
13928 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13929 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13930 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13931 * bail to the real handler if breakFlags==0.
13932 */
13933    ldrb   r3, [rSELF, #offThread_breakFlags]
13934    adrl   lr, dvmAsmInstructionStart + (184 * 64)
13935    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13936    cmp    r3, #0
13937    bxeq   lr                   @ nothing to do - jump to real handler
13938    EXPORT_PC()
13939    mov    r0, rPC              @ arg0
13940    mov    r1, rFP              @ arg1
13941    mov    r2, rSELF            @ arg2
13942    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13943
13944/* ------------------------------ */
13945    .balign 64
13946.L_ALT_OP_SHR_INT_2ADDR: /* 0xb9 */
13947/* File: armv5te/alt_stub.S */
13948/*
13949 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13950 * any interesting requests and then jump to the real instruction
13951 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13952 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13953 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13954 * bail to the real handler if breakFlags==0.
13955 */
13956    ldrb   r3, [rSELF, #offThread_breakFlags]
13957    adrl   lr, dvmAsmInstructionStart + (185 * 64)
13958    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13959    cmp    r3, #0
13960    bxeq   lr                   @ nothing to do - jump to real handler
13961    EXPORT_PC()
13962    mov    r0, rPC              @ arg0
13963    mov    r1, rFP              @ arg1
13964    mov    r2, rSELF            @ arg2
13965    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13966
13967/* ------------------------------ */
13968    .balign 64
13969.L_ALT_OP_USHR_INT_2ADDR: /* 0xba */
13970/* File: armv5te/alt_stub.S */
13971/*
13972 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13973 * any interesting requests and then jump to the real instruction
13974 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13975 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13976 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13977 * bail to the real handler if breakFlags==0.
13978 */
13979    ldrb   r3, [rSELF, #offThread_breakFlags]
13980    adrl   lr, dvmAsmInstructionStart + (186 * 64)
13981    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13982    cmp    r3, #0
13983    bxeq   lr                   @ nothing to do - jump to real handler
13984    EXPORT_PC()
13985    mov    r0, rPC              @ arg0
13986    mov    r1, rFP              @ arg1
13987    mov    r2, rSELF            @ arg2
13988    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13989
13990/* ------------------------------ */
13991    .balign 64
13992.L_ALT_OP_ADD_LONG_2ADDR: /* 0xbb */
13993/* File: armv5te/alt_stub.S */
13994/*
13995 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13996 * any interesting requests and then jump to the real instruction
13997 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13998 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13999 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14000 * bail to the real handler if breakFlags==0.
14001 */
14002    ldrb   r3, [rSELF, #offThread_breakFlags]
14003    adrl   lr, dvmAsmInstructionStart + (187 * 64)
14004    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14005    cmp    r3, #0
14006    bxeq   lr                   @ nothing to do - jump to real handler
14007    EXPORT_PC()
14008    mov    r0, rPC              @ arg0
14009    mov    r1, rFP              @ arg1
14010    mov    r2, rSELF            @ arg2
14011    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14012
14013/* ------------------------------ */
14014    .balign 64
14015.L_ALT_OP_SUB_LONG_2ADDR: /* 0xbc */
14016/* File: armv5te/alt_stub.S */
14017/*
14018 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14019 * any interesting requests and then jump to the real instruction
14020 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14021 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14022 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14023 * bail to the real handler if breakFlags==0.
14024 */
14025    ldrb   r3, [rSELF, #offThread_breakFlags]
14026    adrl   lr, dvmAsmInstructionStart + (188 * 64)
14027    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14028    cmp    r3, #0
14029    bxeq   lr                   @ nothing to do - jump to real handler
14030    EXPORT_PC()
14031    mov    r0, rPC              @ arg0
14032    mov    r1, rFP              @ arg1
14033    mov    r2, rSELF            @ arg2
14034    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14035
14036/* ------------------------------ */
14037    .balign 64
14038.L_ALT_OP_MUL_LONG_2ADDR: /* 0xbd */
14039/* File: armv5te/alt_stub.S */
14040/*
14041 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14042 * any interesting requests and then jump to the real instruction
14043 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14044 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14045 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14046 * bail to the real handler if breakFlags==0.
14047 */
14048    ldrb   r3, [rSELF, #offThread_breakFlags]
14049    adrl   lr, dvmAsmInstructionStart + (189 * 64)
14050    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14051    cmp    r3, #0
14052    bxeq   lr                   @ nothing to do - jump to real handler
14053    EXPORT_PC()
14054    mov    r0, rPC              @ arg0
14055    mov    r1, rFP              @ arg1
14056    mov    r2, rSELF            @ arg2
14057    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14058
14059/* ------------------------------ */
14060    .balign 64
14061.L_ALT_OP_DIV_LONG_2ADDR: /* 0xbe */
14062/* File: armv5te/alt_stub.S */
14063/*
14064 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14065 * any interesting requests and then jump to the real instruction
14066 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14067 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14068 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14069 * bail to the real handler if breakFlags==0.
14070 */
14071    ldrb   r3, [rSELF, #offThread_breakFlags]
14072    adrl   lr, dvmAsmInstructionStart + (190 * 64)
14073    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14074    cmp    r3, #0
14075    bxeq   lr                   @ nothing to do - jump to real handler
14076    EXPORT_PC()
14077    mov    r0, rPC              @ arg0
14078    mov    r1, rFP              @ arg1
14079    mov    r2, rSELF            @ arg2
14080    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14081
14082/* ------------------------------ */
14083    .balign 64
14084.L_ALT_OP_REM_LONG_2ADDR: /* 0xbf */
14085/* File: armv5te/alt_stub.S */
14086/*
14087 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14088 * any interesting requests and then jump to the real instruction
14089 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14090 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14091 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14092 * bail to the real handler if breakFlags==0.
14093 */
14094    ldrb   r3, [rSELF, #offThread_breakFlags]
14095    adrl   lr, dvmAsmInstructionStart + (191 * 64)
14096    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14097    cmp    r3, #0
14098    bxeq   lr                   @ nothing to do - jump to real handler
14099    EXPORT_PC()
14100    mov    r0, rPC              @ arg0
14101    mov    r1, rFP              @ arg1
14102    mov    r2, rSELF            @ arg2
14103    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14104
14105/* ------------------------------ */
14106    .balign 64
14107.L_ALT_OP_AND_LONG_2ADDR: /* 0xc0 */
14108/* File: armv5te/alt_stub.S */
14109/*
14110 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14111 * any interesting requests and then jump to the real instruction
14112 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14113 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14114 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14115 * bail to the real handler if breakFlags==0.
14116 */
14117    ldrb   r3, [rSELF, #offThread_breakFlags]
14118    adrl   lr, dvmAsmInstructionStart + (192 * 64)
14119    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14120    cmp    r3, #0
14121    bxeq   lr                   @ nothing to do - jump to real handler
14122    EXPORT_PC()
14123    mov    r0, rPC              @ arg0
14124    mov    r1, rFP              @ arg1
14125    mov    r2, rSELF            @ arg2
14126    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14127
14128/* ------------------------------ */
14129    .balign 64
14130.L_ALT_OP_OR_LONG_2ADDR: /* 0xc1 */
14131/* File: armv5te/alt_stub.S */
14132/*
14133 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14134 * any interesting requests and then jump to the real instruction
14135 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14136 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14137 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14138 * bail to the real handler if breakFlags==0.
14139 */
14140    ldrb   r3, [rSELF, #offThread_breakFlags]
14141    adrl   lr, dvmAsmInstructionStart + (193 * 64)
14142    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14143    cmp    r3, #0
14144    bxeq   lr                   @ nothing to do - jump to real handler
14145    EXPORT_PC()
14146    mov    r0, rPC              @ arg0
14147    mov    r1, rFP              @ arg1
14148    mov    r2, rSELF            @ arg2
14149    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14150
14151/* ------------------------------ */
14152    .balign 64
14153.L_ALT_OP_XOR_LONG_2ADDR: /* 0xc2 */
14154/* File: armv5te/alt_stub.S */
14155/*
14156 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14157 * any interesting requests and then jump to the real instruction
14158 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14159 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14160 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14161 * bail to the real handler if breakFlags==0.
14162 */
14163    ldrb   r3, [rSELF, #offThread_breakFlags]
14164    adrl   lr, dvmAsmInstructionStart + (194 * 64)
14165    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14166    cmp    r3, #0
14167    bxeq   lr                   @ nothing to do - jump to real handler
14168    EXPORT_PC()
14169    mov    r0, rPC              @ arg0
14170    mov    r1, rFP              @ arg1
14171    mov    r2, rSELF            @ arg2
14172    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14173
14174/* ------------------------------ */
14175    .balign 64
14176.L_ALT_OP_SHL_LONG_2ADDR: /* 0xc3 */
14177/* File: armv5te/alt_stub.S */
14178/*
14179 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14180 * any interesting requests and then jump to the real instruction
14181 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14182 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14183 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14184 * bail to the real handler if breakFlags==0.
14185 */
14186    ldrb   r3, [rSELF, #offThread_breakFlags]
14187    adrl   lr, dvmAsmInstructionStart + (195 * 64)
14188    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14189    cmp    r3, #0
14190    bxeq   lr                   @ nothing to do - jump to real handler
14191    EXPORT_PC()
14192    mov    r0, rPC              @ arg0
14193    mov    r1, rFP              @ arg1
14194    mov    r2, rSELF            @ arg2
14195    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14196
14197/* ------------------------------ */
14198    .balign 64
14199.L_ALT_OP_SHR_LONG_2ADDR: /* 0xc4 */
14200/* File: armv5te/alt_stub.S */
14201/*
14202 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14203 * any interesting requests and then jump to the real instruction
14204 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14205 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14206 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14207 * bail to the real handler if breakFlags==0.
14208 */
14209    ldrb   r3, [rSELF, #offThread_breakFlags]
14210    adrl   lr, dvmAsmInstructionStart + (196 * 64)
14211    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14212    cmp    r3, #0
14213    bxeq   lr                   @ nothing to do - jump to real handler
14214    EXPORT_PC()
14215    mov    r0, rPC              @ arg0
14216    mov    r1, rFP              @ arg1
14217    mov    r2, rSELF            @ arg2
14218    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14219
14220/* ------------------------------ */
14221    .balign 64
14222.L_ALT_OP_USHR_LONG_2ADDR: /* 0xc5 */
14223/* File: armv5te/alt_stub.S */
14224/*
14225 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14226 * any interesting requests and then jump to the real instruction
14227 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14228 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14229 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14230 * bail to the real handler if breakFlags==0.
14231 */
14232    ldrb   r3, [rSELF, #offThread_breakFlags]
14233    adrl   lr, dvmAsmInstructionStart + (197 * 64)
14234    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14235    cmp    r3, #0
14236    bxeq   lr                   @ nothing to do - jump to real handler
14237    EXPORT_PC()
14238    mov    r0, rPC              @ arg0
14239    mov    r1, rFP              @ arg1
14240    mov    r2, rSELF            @ arg2
14241    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14242
14243/* ------------------------------ */
14244    .balign 64
14245.L_ALT_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
14246/* File: armv5te/alt_stub.S */
14247/*
14248 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14249 * any interesting requests and then jump to the real instruction
14250 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14251 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14252 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14253 * bail to the real handler if breakFlags==0.
14254 */
14255    ldrb   r3, [rSELF, #offThread_breakFlags]
14256    adrl   lr, dvmAsmInstructionStart + (198 * 64)
14257    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14258    cmp    r3, #0
14259    bxeq   lr                   @ nothing to do - jump to real handler
14260    EXPORT_PC()
14261    mov    r0, rPC              @ arg0
14262    mov    r1, rFP              @ arg1
14263    mov    r2, rSELF            @ arg2
14264    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14265
14266/* ------------------------------ */
14267    .balign 64
14268.L_ALT_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
14269/* File: armv5te/alt_stub.S */
14270/*
14271 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14272 * any interesting requests and then jump to the real instruction
14273 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14274 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14275 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14276 * bail to the real handler if breakFlags==0.
14277 */
14278    ldrb   r3, [rSELF, #offThread_breakFlags]
14279    adrl   lr, dvmAsmInstructionStart + (199 * 64)
14280    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14281    cmp    r3, #0
14282    bxeq   lr                   @ nothing to do - jump to real handler
14283    EXPORT_PC()
14284    mov    r0, rPC              @ arg0
14285    mov    r1, rFP              @ arg1
14286    mov    r2, rSELF            @ arg2
14287    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14288
14289/* ------------------------------ */
14290    .balign 64
14291.L_ALT_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
14292/* File: armv5te/alt_stub.S */
14293/*
14294 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14295 * any interesting requests and then jump to the real instruction
14296 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14297 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14298 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14299 * bail to the real handler if breakFlags==0.
14300 */
14301    ldrb   r3, [rSELF, #offThread_breakFlags]
14302    adrl   lr, dvmAsmInstructionStart + (200 * 64)
14303    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14304    cmp    r3, #0
14305    bxeq   lr                   @ nothing to do - jump to real handler
14306    EXPORT_PC()
14307    mov    r0, rPC              @ arg0
14308    mov    r1, rFP              @ arg1
14309    mov    r2, rSELF            @ arg2
14310    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14311
14312/* ------------------------------ */
14313    .balign 64
14314.L_ALT_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
14315/* File: armv5te/alt_stub.S */
14316/*
14317 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14318 * any interesting requests and then jump to the real instruction
14319 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14320 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14321 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14322 * bail to the real handler if breakFlags==0.
14323 */
14324    ldrb   r3, [rSELF, #offThread_breakFlags]
14325    adrl   lr, dvmAsmInstructionStart + (201 * 64)
14326    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14327    cmp    r3, #0
14328    bxeq   lr                   @ nothing to do - jump to real handler
14329    EXPORT_PC()
14330    mov    r0, rPC              @ arg0
14331    mov    r1, rFP              @ arg1
14332    mov    r2, rSELF            @ arg2
14333    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14334
14335/* ------------------------------ */
14336    .balign 64
14337.L_ALT_OP_REM_FLOAT_2ADDR: /* 0xca */
14338/* File: armv5te/alt_stub.S */
14339/*
14340 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14341 * any interesting requests and then jump to the real instruction
14342 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14343 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14344 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14345 * bail to the real handler if breakFlags==0.
14346 */
14347    ldrb   r3, [rSELF, #offThread_breakFlags]
14348    adrl   lr, dvmAsmInstructionStart + (202 * 64)
14349    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14350    cmp    r3, #0
14351    bxeq   lr                   @ nothing to do - jump to real handler
14352    EXPORT_PC()
14353    mov    r0, rPC              @ arg0
14354    mov    r1, rFP              @ arg1
14355    mov    r2, rSELF            @ arg2
14356    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14357
14358/* ------------------------------ */
14359    .balign 64
14360.L_ALT_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
14361/* File: armv5te/alt_stub.S */
14362/*
14363 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14364 * any interesting requests and then jump to the real instruction
14365 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14366 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14367 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14368 * bail to the real handler if breakFlags==0.
14369 */
14370    ldrb   r3, [rSELF, #offThread_breakFlags]
14371    adrl   lr, dvmAsmInstructionStart + (203 * 64)
14372    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14373    cmp    r3, #0
14374    bxeq   lr                   @ nothing to do - jump to real handler
14375    EXPORT_PC()
14376    mov    r0, rPC              @ arg0
14377    mov    r1, rFP              @ arg1
14378    mov    r2, rSELF            @ arg2
14379    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14380
14381/* ------------------------------ */
14382    .balign 64
14383.L_ALT_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
14384/* File: armv5te/alt_stub.S */
14385/*
14386 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14387 * any interesting requests and then jump to the real instruction
14388 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14389 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14390 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14391 * bail to the real handler if breakFlags==0.
14392 */
14393    ldrb   r3, [rSELF, #offThread_breakFlags]
14394    adrl   lr, dvmAsmInstructionStart + (204 * 64)
14395    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14396    cmp    r3, #0
14397    bxeq   lr                   @ nothing to do - jump to real handler
14398    EXPORT_PC()
14399    mov    r0, rPC              @ arg0
14400    mov    r1, rFP              @ arg1
14401    mov    r2, rSELF            @ arg2
14402    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14403
14404/* ------------------------------ */
14405    .balign 64
14406.L_ALT_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
14407/* File: armv5te/alt_stub.S */
14408/*
14409 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14410 * any interesting requests and then jump to the real instruction
14411 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14412 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14413 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14414 * bail to the real handler if breakFlags==0.
14415 */
14416    ldrb   r3, [rSELF, #offThread_breakFlags]
14417    adrl   lr, dvmAsmInstructionStart + (205 * 64)
14418    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14419    cmp    r3, #0
14420    bxeq   lr                   @ nothing to do - jump to real handler
14421    EXPORT_PC()
14422    mov    r0, rPC              @ arg0
14423    mov    r1, rFP              @ arg1
14424    mov    r2, rSELF            @ arg2
14425    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14426
14427/* ------------------------------ */
14428    .balign 64
14429.L_ALT_OP_DIV_DOUBLE_2ADDR: /* 0xce */
14430/* File: armv5te/alt_stub.S */
14431/*
14432 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14433 * any interesting requests and then jump to the real instruction
14434 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14435 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14436 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14437 * bail to the real handler if breakFlags==0.
14438 */
14439    ldrb   r3, [rSELF, #offThread_breakFlags]
14440    adrl   lr, dvmAsmInstructionStart + (206 * 64)
14441    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14442    cmp    r3, #0
14443    bxeq   lr                   @ nothing to do - jump to real handler
14444    EXPORT_PC()
14445    mov    r0, rPC              @ arg0
14446    mov    r1, rFP              @ arg1
14447    mov    r2, rSELF            @ arg2
14448    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14449
14450/* ------------------------------ */
14451    .balign 64
14452.L_ALT_OP_REM_DOUBLE_2ADDR: /* 0xcf */
14453/* File: armv5te/alt_stub.S */
14454/*
14455 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14456 * any interesting requests and then jump to the real instruction
14457 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14458 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14459 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14460 * bail to the real handler if breakFlags==0.
14461 */
14462    ldrb   r3, [rSELF, #offThread_breakFlags]
14463    adrl   lr, dvmAsmInstructionStart + (207 * 64)
14464    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14465    cmp    r3, #0
14466    bxeq   lr                   @ nothing to do - jump to real handler
14467    EXPORT_PC()
14468    mov    r0, rPC              @ arg0
14469    mov    r1, rFP              @ arg1
14470    mov    r2, rSELF            @ arg2
14471    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14472
14473/* ------------------------------ */
14474    .balign 64
14475.L_ALT_OP_ADD_INT_LIT16: /* 0xd0 */
14476/* File: armv5te/alt_stub.S */
14477/*
14478 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14479 * any interesting requests and then jump to the real instruction
14480 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14481 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14482 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14483 * bail to the real handler if breakFlags==0.
14484 */
14485    ldrb   r3, [rSELF, #offThread_breakFlags]
14486    adrl   lr, dvmAsmInstructionStart + (208 * 64)
14487    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14488    cmp    r3, #0
14489    bxeq   lr                   @ nothing to do - jump to real handler
14490    EXPORT_PC()
14491    mov    r0, rPC              @ arg0
14492    mov    r1, rFP              @ arg1
14493    mov    r2, rSELF            @ arg2
14494    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14495
14496/* ------------------------------ */
14497    .balign 64
14498.L_ALT_OP_RSUB_INT: /* 0xd1 */
14499/* File: armv5te/alt_stub.S */
14500/*
14501 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14502 * any interesting requests and then jump to the real instruction
14503 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14504 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14505 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14506 * bail to the real handler if breakFlags==0.
14507 */
14508    ldrb   r3, [rSELF, #offThread_breakFlags]
14509    adrl   lr, dvmAsmInstructionStart + (209 * 64)
14510    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14511    cmp    r3, #0
14512    bxeq   lr                   @ nothing to do - jump to real handler
14513    EXPORT_PC()
14514    mov    r0, rPC              @ arg0
14515    mov    r1, rFP              @ arg1
14516    mov    r2, rSELF            @ arg2
14517    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14518
14519/* ------------------------------ */
14520    .balign 64
14521.L_ALT_OP_MUL_INT_LIT16: /* 0xd2 */
14522/* File: armv5te/alt_stub.S */
14523/*
14524 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14525 * any interesting requests and then jump to the real instruction
14526 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14527 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14528 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14529 * bail to the real handler if breakFlags==0.
14530 */
14531    ldrb   r3, [rSELF, #offThread_breakFlags]
14532    adrl   lr, dvmAsmInstructionStart + (210 * 64)
14533    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14534    cmp    r3, #0
14535    bxeq   lr                   @ nothing to do - jump to real handler
14536    EXPORT_PC()
14537    mov    r0, rPC              @ arg0
14538    mov    r1, rFP              @ arg1
14539    mov    r2, rSELF            @ arg2
14540    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14541
14542/* ------------------------------ */
14543    .balign 64
14544.L_ALT_OP_DIV_INT_LIT16: /* 0xd3 */
14545/* File: armv5te/alt_stub.S */
14546/*
14547 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14548 * any interesting requests and then jump to the real instruction
14549 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14550 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14551 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14552 * bail to the real handler if breakFlags==0.
14553 */
14554    ldrb   r3, [rSELF, #offThread_breakFlags]
14555    adrl   lr, dvmAsmInstructionStart + (211 * 64)
14556    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14557    cmp    r3, #0
14558    bxeq   lr                   @ nothing to do - jump to real handler
14559    EXPORT_PC()
14560    mov    r0, rPC              @ arg0
14561    mov    r1, rFP              @ arg1
14562    mov    r2, rSELF            @ arg2
14563    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14564
14565/* ------------------------------ */
14566    .balign 64
14567.L_ALT_OP_REM_INT_LIT16: /* 0xd4 */
14568/* File: armv5te/alt_stub.S */
14569/*
14570 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14571 * any interesting requests and then jump to the real instruction
14572 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14573 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14574 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14575 * bail to the real handler if breakFlags==0.
14576 */
14577    ldrb   r3, [rSELF, #offThread_breakFlags]
14578    adrl   lr, dvmAsmInstructionStart + (212 * 64)
14579    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14580    cmp    r3, #0
14581    bxeq   lr                   @ nothing to do - jump to real handler
14582    EXPORT_PC()
14583    mov    r0, rPC              @ arg0
14584    mov    r1, rFP              @ arg1
14585    mov    r2, rSELF            @ arg2
14586    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14587
14588/* ------------------------------ */
14589    .balign 64
14590.L_ALT_OP_AND_INT_LIT16: /* 0xd5 */
14591/* File: armv5te/alt_stub.S */
14592/*
14593 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14594 * any interesting requests and then jump to the real instruction
14595 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14596 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14597 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14598 * bail to the real handler if breakFlags==0.
14599 */
14600    ldrb   r3, [rSELF, #offThread_breakFlags]
14601    adrl   lr, dvmAsmInstructionStart + (213 * 64)
14602    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14603    cmp    r3, #0
14604    bxeq   lr                   @ nothing to do - jump to real handler
14605    EXPORT_PC()
14606    mov    r0, rPC              @ arg0
14607    mov    r1, rFP              @ arg1
14608    mov    r2, rSELF            @ arg2
14609    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14610
14611/* ------------------------------ */
14612    .balign 64
14613.L_ALT_OP_OR_INT_LIT16: /* 0xd6 */
14614/* File: armv5te/alt_stub.S */
14615/*
14616 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14617 * any interesting requests and then jump to the real instruction
14618 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14619 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14620 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14621 * bail to the real handler if breakFlags==0.
14622 */
14623    ldrb   r3, [rSELF, #offThread_breakFlags]
14624    adrl   lr, dvmAsmInstructionStart + (214 * 64)
14625    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14626    cmp    r3, #0
14627    bxeq   lr                   @ nothing to do - jump to real handler
14628    EXPORT_PC()
14629    mov    r0, rPC              @ arg0
14630    mov    r1, rFP              @ arg1
14631    mov    r2, rSELF            @ arg2
14632    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14633
14634/* ------------------------------ */
14635    .balign 64
14636.L_ALT_OP_XOR_INT_LIT16: /* 0xd7 */
14637/* File: armv5te/alt_stub.S */
14638/*
14639 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14640 * any interesting requests and then jump to the real instruction
14641 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14642 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14643 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14644 * bail to the real handler if breakFlags==0.
14645 */
14646    ldrb   r3, [rSELF, #offThread_breakFlags]
14647    adrl   lr, dvmAsmInstructionStart + (215 * 64)
14648    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14649    cmp    r3, #0
14650    bxeq   lr                   @ nothing to do - jump to real handler
14651    EXPORT_PC()
14652    mov    r0, rPC              @ arg0
14653    mov    r1, rFP              @ arg1
14654    mov    r2, rSELF            @ arg2
14655    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14656
14657/* ------------------------------ */
14658    .balign 64
14659.L_ALT_OP_ADD_INT_LIT8: /* 0xd8 */
14660/* File: armv5te/alt_stub.S */
14661/*
14662 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14663 * any interesting requests and then jump to the real instruction
14664 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14665 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14666 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14667 * bail to the real handler if breakFlags==0.
14668 */
14669    ldrb   r3, [rSELF, #offThread_breakFlags]
14670    adrl   lr, dvmAsmInstructionStart + (216 * 64)
14671    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14672    cmp    r3, #0
14673    bxeq   lr                   @ nothing to do - jump to real handler
14674    EXPORT_PC()
14675    mov    r0, rPC              @ arg0
14676    mov    r1, rFP              @ arg1
14677    mov    r2, rSELF            @ arg2
14678    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14679
14680/* ------------------------------ */
14681    .balign 64
14682.L_ALT_OP_RSUB_INT_LIT8: /* 0xd9 */
14683/* File: armv5te/alt_stub.S */
14684/*
14685 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14686 * any interesting requests and then jump to the real instruction
14687 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14688 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14689 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14690 * bail to the real handler if breakFlags==0.
14691 */
14692    ldrb   r3, [rSELF, #offThread_breakFlags]
14693    adrl   lr, dvmAsmInstructionStart + (217 * 64)
14694    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14695    cmp    r3, #0
14696    bxeq   lr                   @ nothing to do - jump to real handler
14697    EXPORT_PC()
14698    mov    r0, rPC              @ arg0
14699    mov    r1, rFP              @ arg1
14700    mov    r2, rSELF            @ arg2
14701    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14702
14703/* ------------------------------ */
14704    .balign 64
14705.L_ALT_OP_MUL_INT_LIT8: /* 0xda */
14706/* File: armv5te/alt_stub.S */
14707/*
14708 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14709 * any interesting requests and then jump to the real instruction
14710 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14711 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14712 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14713 * bail to the real handler if breakFlags==0.
14714 */
14715    ldrb   r3, [rSELF, #offThread_breakFlags]
14716    adrl   lr, dvmAsmInstructionStart + (218 * 64)
14717    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14718    cmp    r3, #0
14719    bxeq   lr                   @ nothing to do - jump to real handler
14720    EXPORT_PC()
14721    mov    r0, rPC              @ arg0
14722    mov    r1, rFP              @ arg1
14723    mov    r2, rSELF            @ arg2
14724    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14725
14726/* ------------------------------ */
14727    .balign 64
14728.L_ALT_OP_DIV_INT_LIT8: /* 0xdb */
14729/* File: armv5te/alt_stub.S */
14730/*
14731 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14732 * any interesting requests and then jump to the real instruction
14733 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14734 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14735 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14736 * bail to the real handler if breakFlags==0.
14737 */
14738    ldrb   r3, [rSELF, #offThread_breakFlags]
14739    adrl   lr, dvmAsmInstructionStart + (219 * 64)
14740    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14741    cmp    r3, #0
14742    bxeq   lr                   @ nothing to do - jump to real handler
14743    EXPORT_PC()
14744    mov    r0, rPC              @ arg0
14745    mov    r1, rFP              @ arg1
14746    mov    r2, rSELF            @ arg2
14747    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14748
14749/* ------------------------------ */
14750    .balign 64
14751.L_ALT_OP_REM_INT_LIT8: /* 0xdc */
14752/* File: armv5te/alt_stub.S */
14753/*
14754 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14755 * any interesting requests and then jump to the real instruction
14756 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14757 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14758 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14759 * bail to the real handler if breakFlags==0.
14760 */
14761    ldrb   r3, [rSELF, #offThread_breakFlags]
14762    adrl   lr, dvmAsmInstructionStart + (220 * 64)
14763    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14764    cmp    r3, #0
14765    bxeq   lr                   @ nothing to do - jump to real handler
14766    EXPORT_PC()
14767    mov    r0, rPC              @ arg0
14768    mov    r1, rFP              @ arg1
14769    mov    r2, rSELF            @ arg2
14770    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14771
14772/* ------------------------------ */
14773    .balign 64
14774.L_ALT_OP_AND_INT_LIT8: /* 0xdd */
14775/* File: armv5te/alt_stub.S */
14776/*
14777 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14778 * any interesting requests and then jump to the real instruction
14779 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14780 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14781 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14782 * bail to the real handler if breakFlags==0.
14783 */
14784    ldrb   r3, [rSELF, #offThread_breakFlags]
14785    adrl   lr, dvmAsmInstructionStart + (221 * 64)
14786    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14787    cmp    r3, #0
14788    bxeq   lr                   @ nothing to do - jump to real handler
14789    EXPORT_PC()
14790    mov    r0, rPC              @ arg0
14791    mov    r1, rFP              @ arg1
14792    mov    r2, rSELF            @ arg2
14793    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14794
14795/* ------------------------------ */
14796    .balign 64
14797.L_ALT_OP_OR_INT_LIT8: /* 0xde */
14798/* File: armv5te/alt_stub.S */
14799/*
14800 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14801 * any interesting requests and then jump to the real instruction
14802 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14803 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14804 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14805 * bail to the real handler if breakFlags==0.
14806 */
14807    ldrb   r3, [rSELF, #offThread_breakFlags]
14808    adrl   lr, dvmAsmInstructionStart + (222 * 64)
14809    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14810    cmp    r3, #0
14811    bxeq   lr                   @ nothing to do - jump to real handler
14812    EXPORT_PC()
14813    mov    r0, rPC              @ arg0
14814    mov    r1, rFP              @ arg1
14815    mov    r2, rSELF            @ arg2
14816    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14817
14818/* ------------------------------ */
14819    .balign 64
14820.L_ALT_OP_XOR_INT_LIT8: /* 0xdf */
14821/* File: armv5te/alt_stub.S */
14822/*
14823 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14824 * any interesting requests and then jump to the real instruction
14825 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14826 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14827 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14828 * bail to the real handler if breakFlags==0.
14829 */
14830    ldrb   r3, [rSELF, #offThread_breakFlags]
14831    adrl   lr, dvmAsmInstructionStart + (223 * 64)
14832    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14833    cmp    r3, #0
14834    bxeq   lr                   @ nothing to do - jump to real handler
14835    EXPORT_PC()
14836    mov    r0, rPC              @ arg0
14837    mov    r1, rFP              @ arg1
14838    mov    r2, rSELF            @ arg2
14839    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14840
14841/* ------------------------------ */
14842    .balign 64
14843.L_ALT_OP_SHL_INT_LIT8: /* 0xe0 */
14844/* File: armv5te/alt_stub.S */
14845/*
14846 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14847 * any interesting requests and then jump to the real instruction
14848 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14849 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14850 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14851 * bail to the real handler if breakFlags==0.
14852 */
14853    ldrb   r3, [rSELF, #offThread_breakFlags]
14854    adrl   lr, dvmAsmInstructionStart + (224 * 64)
14855    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14856    cmp    r3, #0
14857    bxeq   lr                   @ nothing to do - jump to real handler
14858    EXPORT_PC()
14859    mov    r0, rPC              @ arg0
14860    mov    r1, rFP              @ arg1
14861    mov    r2, rSELF            @ arg2
14862    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14863
14864/* ------------------------------ */
14865    .balign 64
14866.L_ALT_OP_SHR_INT_LIT8: /* 0xe1 */
14867/* File: armv5te/alt_stub.S */
14868/*
14869 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14870 * any interesting requests and then jump to the real instruction
14871 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14872 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14873 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14874 * bail to the real handler if breakFlags==0.
14875 */
14876    ldrb   r3, [rSELF, #offThread_breakFlags]
14877    adrl   lr, dvmAsmInstructionStart + (225 * 64)
14878    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14879    cmp    r3, #0
14880    bxeq   lr                   @ nothing to do - jump to real handler
14881    EXPORT_PC()
14882    mov    r0, rPC              @ arg0
14883    mov    r1, rFP              @ arg1
14884    mov    r2, rSELF            @ arg2
14885    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14886
14887/* ------------------------------ */
14888    .balign 64
14889.L_ALT_OP_USHR_INT_LIT8: /* 0xe2 */
14890/* File: armv5te/alt_stub.S */
14891/*
14892 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14893 * any interesting requests and then jump to the real instruction
14894 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14895 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14896 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14897 * bail to the real handler if breakFlags==0.
14898 */
14899    ldrb   r3, [rSELF, #offThread_breakFlags]
14900    adrl   lr, dvmAsmInstructionStart + (226 * 64)
14901    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14902    cmp    r3, #0
14903    bxeq   lr                   @ nothing to do - jump to real handler
14904    EXPORT_PC()
14905    mov    r0, rPC              @ arg0
14906    mov    r1, rFP              @ arg1
14907    mov    r2, rSELF            @ arg2
14908    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14909
14910/* ------------------------------ */
14911    .balign 64
14912.L_ALT_OP_IGET_VOLATILE: /* 0xe3 */
14913/* File: armv5te/alt_stub.S */
14914/*
14915 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14916 * any interesting requests and then jump to the real instruction
14917 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14918 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14919 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14920 * bail to the real handler if breakFlags==0.
14921 */
14922    ldrb   r3, [rSELF, #offThread_breakFlags]
14923    adrl   lr, dvmAsmInstructionStart + (227 * 64)
14924    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14925    cmp    r3, #0
14926    bxeq   lr                   @ nothing to do - jump to real handler
14927    EXPORT_PC()
14928    mov    r0, rPC              @ arg0
14929    mov    r1, rFP              @ arg1
14930    mov    r2, rSELF            @ arg2
14931    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14932
14933/* ------------------------------ */
14934    .balign 64
14935.L_ALT_OP_IPUT_VOLATILE: /* 0xe4 */
14936/* File: armv5te/alt_stub.S */
14937/*
14938 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14939 * any interesting requests and then jump to the real instruction
14940 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14941 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14942 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14943 * bail to the real handler if breakFlags==0.
14944 */
14945    ldrb   r3, [rSELF, #offThread_breakFlags]
14946    adrl   lr, dvmAsmInstructionStart + (228 * 64)
14947    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14948    cmp    r3, #0
14949    bxeq   lr                   @ nothing to do - jump to real handler
14950    EXPORT_PC()
14951    mov    r0, rPC              @ arg0
14952    mov    r1, rFP              @ arg1
14953    mov    r2, rSELF            @ arg2
14954    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14955
14956/* ------------------------------ */
14957    .balign 64
14958.L_ALT_OP_SGET_VOLATILE: /* 0xe5 */
14959/* File: armv5te/alt_stub.S */
14960/*
14961 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14962 * any interesting requests and then jump to the real instruction
14963 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14964 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14965 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14966 * bail to the real handler if breakFlags==0.
14967 */
14968    ldrb   r3, [rSELF, #offThread_breakFlags]
14969    adrl   lr, dvmAsmInstructionStart + (229 * 64)
14970    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14971    cmp    r3, #0
14972    bxeq   lr                   @ nothing to do - jump to real handler
14973    EXPORT_PC()
14974    mov    r0, rPC              @ arg0
14975    mov    r1, rFP              @ arg1
14976    mov    r2, rSELF            @ arg2
14977    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14978
14979/* ------------------------------ */
14980    .balign 64
14981.L_ALT_OP_SPUT_VOLATILE: /* 0xe6 */
14982/* File: armv5te/alt_stub.S */
14983/*
14984 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14985 * any interesting requests and then jump to the real instruction
14986 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14987 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14988 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14989 * bail to the real handler if breakFlags==0.
14990 */
14991    ldrb   r3, [rSELF, #offThread_breakFlags]
14992    adrl   lr, dvmAsmInstructionStart + (230 * 64)
14993    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14994    cmp    r3, #0
14995    bxeq   lr                   @ nothing to do - jump to real handler
14996    EXPORT_PC()
14997    mov    r0, rPC              @ arg0
14998    mov    r1, rFP              @ arg1
14999    mov    r2, rSELF            @ arg2
15000    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15001
15002/* ------------------------------ */
15003    .balign 64
15004.L_ALT_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
15005/* File: armv5te/alt_stub.S */
15006/*
15007 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15008 * any interesting requests and then jump to the real instruction
15009 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15010 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15011 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15012 * bail to the real handler if breakFlags==0.
15013 */
15014    ldrb   r3, [rSELF, #offThread_breakFlags]
15015    adrl   lr, dvmAsmInstructionStart + (231 * 64)
15016    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15017    cmp    r3, #0
15018    bxeq   lr                   @ nothing to do - jump to real handler
15019    EXPORT_PC()
15020    mov    r0, rPC              @ arg0
15021    mov    r1, rFP              @ arg1
15022    mov    r2, rSELF            @ arg2
15023    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15024
15025/* ------------------------------ */
15026    .balign 64
15027.L_ALT_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
15028/* File: armv5te/alt_stub.S */
15029/*
15030 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15031 * any interesting requests and then jump to the real instruction
15032 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15033 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15034 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15035 * bail to the real handler if breakFlags==0.
15036 */
15037    ldrb   r3, [rSELF, #offThread_breakFlags]
15038    adrl   lr, dvmAsmInstructionStart + (232 * 64)
15039    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15040    cmp    r3, #0
15041    bxeq   lr                   @ nothing to do - jump to real handler
15042    EXPORT_PC()
15043    mov    r0, rPC              @ arg0
15044    mov    r1, rFP              @ arg1
15045    mov    r2, rSELF            @ arg2
15046    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15047
15048/* ------------------------------ */
15049    .balign 64
15050.L_ALT_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
15051/* File: armv5te/alt_stub.S */
15052/*
15053 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15054 * any interesting requests and then jump to the real instruction
15055 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15056 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15057 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15058 * bail to the real handler if breakFlags==0.
15059 */
15060    ldrb   r3, [rSELF, #offThread_breakFlags]
15061    adrl   lr, dvmAsmInstructionStart + (233 * 64)
15062    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15063    cmp    r3, #0
15064    bxeq   lr                   @ nothing to do - jump to real handler
15065    EXPORT_PC()
15066    mov    r0, rPC              @ arg0
15067    mov    r1, rFP              @ arg1
15068    mov    r2, rSELF            @ arg2
15069    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15070
15071/* ------------------------------ */
15072    .balign 64
15073.L_ALT_OP_SGET_WIDE_VOLATILE: /* 0xea */
15074/* File: armv5te/alt_stub.S */
15075/*
15076 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15077 * any interesting requests and then jump to the real instruction
15078 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15079 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15080 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15081 * bail to the real handler if breakFlags==0.
15082 */
15083    ldrb   r3, [rSELF, #offThread_breakFlags]
15084    adrl   lr, dvmAsmInstructionStart + (234 * 64)
15085    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15086    cmp    r3, #0
15087    bxeq   lr                   @ nothing to do - jump to real handler
15088    EXPORT_PC()
15089    mov    r0, rPC              @ arg0
15090    mov    r1, rFP              @ arg1
15091    mov    r2, rSELF            @ arg2
15092    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15093
15094/* ------------------------------ */
15095    .balign 64
15096.L_ALT_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
15097/* File: armv5te/alt_stub.S */
15098/*
15099 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15100 * any interesting requests and then jump to the real instruction
15101 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15102 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15103 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15104 * bail to the real handler if breakFlags==0.
15105 */
15106    ldrb   r3, [rSELF, #offThread_breakFlags]
15107    adrl   lr, dvmAsmInstructionStart + (235 * 64)
15108    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15109    cmp    r3, #0
15110    bxeq   lr                   @ nothing to do - jump to real handler
15111    EXPORT_PC()
15112    mov    r0, rPC              @ arg0
15113    mov    r1, rFP              @ arg1
15114    mov    r2, rSELF            @ arg2
15115    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15116
15117/* ------------------------------ */
15118    .balign 64
15119.L_ALT_OP_BREAKPOINT: /* 0xec */
15120/* File: armv5te/alt_stub.S */
15121/*
15122 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15123 * any interesting requests and then jump to the real instruction
15124 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15125 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15126 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15127 * bail to the real handler if breakFlags==0.
15128 */
15129    ldrb   r3, [rSELF, #offThread_breakFlags]
15130    adrl   lr, dvmAsmInstructionStart + (236 * 64)
15131    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15132    cmp    r3, #0
15133    bxeq   lr                   @ nothing to do - jump to real handler
15134    EXPORT_PC()
15135    mov    r0, rPC              @ arg0
15136    mov    r1, rFP              @ arg1
15137    mov    r2, rSELF            @ arg2
15138    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15139
15140/* ------------------------------ */
15141    .balign 64
15142.L_ALT_OP_THROW_VERIFICATION_ERROR: /* 0xed */
15143/* File: armv5te/alt_stub.S */
15144/*
15145 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15146 * any interesting requests and then jump to the real instruction
15147 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15148 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15149 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15150 * bail to the real handler if breakFlags==0.
15151 */
15152    ldrb   r3, [rSELF, #offThread_breakFlags]
15153    adrl   lr, dvmAsmInstructionStart + (237 * 64)
15154    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15155    cmp    r3, #0
15156    bxeq   lr                   @ nothing to do - jump to real handler
15157    EXPORT_PC()
15158    mov    r0, rPC              @ arg0
15159    mov    r1, rFP              @ arg1
15160    mov    r2, rSELF            @ arg2
15161    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15162
15163/* ------------------------------ */
15164    .balign 64
15165.L_ALT_OP_EXECUTE_INLINE: /* 0xee */
15166/* File: armv5te/alt_stub.S */
15167/*
15168 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15169 * any interesting requests and then jump to the real instruction
15170 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15171 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15172 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15173 * bail to the real handler if breakFlags==0.
15174 */
15175    ldrb   r3, [rSELF, #offThread_breakFlags]
15176    adrl   lr, dvmAsmInstructionStart + (238 * 64)
15177    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15178    cmp    r3, #0
15179    bxeq   lr                   @ nothing to do - jump to real handler
15180    EXPORT_PC()
15181    mov    r0, rPC              @ arg0
15182    mov    r1, rFP              @ arg1
15183    mov    r2, rSELF            @ arg2
15184    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15185
15186/* ------------------------------ */
15187    .balign 64
15188.L_ALT_OP_EXECUTE_INLINE_RANGE: /* 0xef */
15189/* File: armv5te/alt_stub.S */
15190/*
15191 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15192 * any interesting requests and then jump to the real instruction
15193 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15194 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15195 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15196 * bail to the real handler if breakFlags==0.
15197 */
15198    ldrb   r3, [rSELF, #offThread_breakFlags]
15199    adrl   lr, dvmAsmInstructionStart + (239 * 64)
15200    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15201    cmp    r3, #0
15202    bxeq   lr                   @ nothing to do - jump to real handler
15203    EXPORT_PC()
15204    mov    r0, rPC              @ arg0
15205    mov    r1, rFP              @ arg1
15206    mov    r2, rSELF            @ arg2
15207    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15208
15209/* ------------------------------ */
15210    .balign 64
15211.L_ALT_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */
15212/* File: armv5te/alt_stub.S */
15213/*
15214 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15215 * any interesting requests and then jump to the real instruction
15216 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15217 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15218 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15219 * bail to the real handler if breakFlags==0.
15220 */
15221    ldrb   r3, [rSELF, #offThread_breakFlags]
15222    adrl   lr, dvmAsmInstructionStart + (240 * 64)
15223    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15224    cmp    r3, #0
15225    bxeq   lr                   @ nothing to do - jump to real handler
15226    EXPORT_PC()
15227    mov    r0, rPC              @ arg0
15228    mov    r1, rFP              @ arg1
15229    mov    r2, rSELF            @ arg2
15230    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15231
15232/* ------------------------------ */
15233    .balign 64
15234.L_ALT_OP_RETURN_VOID_BARRIER: /* 0xf1 */
15235/* File: armv5te/alt_stub.S */
15236/*
15237 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15238 * any interesting requests and then jump to the real instruction
15239 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15240 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15241 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15242 * bail to the real handler if breakFlags==0.
15243 */
15244    ldrb   r3, [rSELF, #offThread_breakFlags]
15245    adrl   lr, dvmAsmInstructionStart + (241 * 64)
15246    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15247    cmp    r3, #0
15248    bxeq   lr                   @ nothing to do - jump to real handler
15249    EXPORT_PC()
15250    mov    r0, rPC              @ arg0
15251    mov    r1, rFP              @ arg1
15252    mov    r2, rSELF            @ arg2
15253    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15254
15255/* ------------------------------ */
15256    .balign 64
15257.L_ALT_OP_IGET_QUICK: /* 0xf2 */
15258/* File: armv5te/alt_stub.S */
15259/*
15260 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15261 * any interesting requests and then jump to the real instruction
15262 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15263 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15264 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15265 * bail to the real handler if breakFlags==0.
15266 */
15267    ldrb   r3, [rSELF, #offThread_breakFlags]
15268    adrl   lr, dvmAsmInstructionStart + (242 * 64)
15269    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15270    cmp    r3, #0
15271    bxeq   lr                   @ nothing to do - jump to real handler
15272    EXPORT_PC()
15273    mov    r0, rPC              @ arg0
15274    mov    r1, rFP              @ arg1
15275    mov    r2, rSELF            @ arg2
15276    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15277
15278/* ------------------------------ */
15279    .balign 64
15280.L_ALT_OP_IGET_WIDE_QUICK: /* 0xf3 */
15281/* File: armv5te/alt_stub.S */
15282/*
15283 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15284 * any interesting requests and then jump to the real instruction
15285 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15286 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15287 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15288 * bail to the real handler if breakFlags==0.
15289 */
15290    ldrb   r3, [rSELF, #offThread_breakFlags]
15291    adrl   lr, dvmAsmInstructionStart + (243 * 64)
15292    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15293    cmp    r3, #0
15294    bxeq   lr                   @ nothing to do - jump to real handler
15295    EXPORT_PC()
15296    mov    r0, rPC              @ arg0
15297    mov    r1, rFP              @ arg1
15298    mov    r2, rSELF            @ arg2
15299    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15300
15301/* ------------------------------ */
15302    .balign 64
15303.L_ALT_OP_IGET_OBJECT_QUICK: /* 0xf4 */
15304/* File: armv5te/alt_stub.S */
15305/*
15306 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15307 * any interesting requests and then jump to the real instruction
15308 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15309 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15310 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15311 * bail to the real handler if breakFlags==0.
15312 */
15313    ldrb   r3, [rSELF, #offThread_breakFlags]
15314    adrl   lr, dvmAsmInstructionStart + (244 * 64)
15315    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15316    cmp    r3, #0
15317    bxeq   lr                   @ nothing to do - jump to real handler
15318    EXPORT_PC()
15319    mov    r0, rPC              @ arg0
15320    mov    r1, rFP              @ arg1
15321    mov    r2, rSELF            @ arg2
15322    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15323
15324/* ------------------------------ */
15325    .balign 64
15326.L_ALT_OP_IPUT_QUICK: /* 0xf5 */
15327/* File: armv5te/alt_stub.S */
15328/*
15329 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15330 * any interesting requests and then jump to the real instruction
15331 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15332 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15333 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15334 * bail to the real handler if breakFlags==0.
15335 */
15336    ldrb   r3, [rSELF, #offThread_breakFlags]
15337    adrl   lr, dvmAsmInstructionStart + (245 * 64)
15338    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15339    cmp    r3, #0
15340    bxeq   lr                   @ nothing to do - jump to real handler
15341    EXPORT_PC()
15342    mov    r0, rPC              @ arg0
15343    mov    r1, rFP              @ arg1
15344    mov    r2, rSELF            @ arg2
15345    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15346
15347/* ------------------------------ */
15348    .balign 64
15349.L_ALT_OP_IPUT_WIDE_QUICK: /* 0xf6 */
15350/* File: armv5te/alt_stub.S */
15351/*
15352 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15353 * any interesting requests and then jump to the real instruction
15354 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15355 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15356 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15357 * bail to the real handler if breakFlags==0.
15358 */
15359    ldrb   r3, [rSELF, #offThread_breakFlags]
15360    adrl   lr, dvmAsmInstructionStart + (246 * 64)
15361    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15362    cmp    r3, #0
15363    bxeq   lr                   @ nothing to do - jump to real handler
15364    EXPORT_PC()
15365    mov    r0, rPC              @ arg0
15366    mov    r1, rFP              @ arg1
15367    mov    r2, rSELF            @ arg2
15368    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15369
15370/* ------------------------------ */
15371    .balign 64
15372.L_ALT_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
15373/* File: armv5te/alt_stub.S */
15374/*
15375 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15376 * any interesting requests and then jump to the real instruction
15377 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15378 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15379 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15380 * bail to the real handler if breakFlags==0.
15381 */
15382    ldrb   r3, [rSELF, #offThread_breakFlags]
15383    adrl   lr, dvmAsmInstructionStart + (247 * 64)
15384    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15385    cmp    r3, #0
15386    bxeq   lr                   @ nothing to do - jump to real handler
15387    EXPORT_PC()
15388    mov    r0, rPC              @ arg0
15389    mov    r1, rFP              @ arg1
15390    mov    r2, rSELF            @ arg2
15391    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15392
15393/* ------------------------------ */
15394    .balign 64
15395.L_ALT_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
15396/* File: armv5te/alt_stub.S */
15397/*
15398 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15399 * any interesting requests and then jump to the real instruction
15400 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15401 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15402 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15403 * bail to the real handler if breakFlags==0.
15404 */
15405    ldrb   r3, [rSELF, #offThread_breakFlags]
15406    adrl   lr, dvmAsmInstructionStart + (248 * 64)
15407    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15408    cmp    r3, #0
15409    bxeq   lr                   @ nothing to do - jump to real handler
15410    EXPORT_PC()
15411    mov    r0, rPC              @ arg0
15412    mov    r1, rFP              @ arg1
15413    mov    r2, rSELF            @ arg2
15414    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15415
15416/* ------------------------------ */
15417    .balign 64
15418.L_ALT_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
15419/* File: armv5te/alt_stub.S */
15420/*
15421 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15422 * any interesting requests and then jump to the real instruction
15423 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15424 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15425 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15426 * bail to the real handler if breakFlags==0.
15427 */
15428    ldrb   r3, [rSELF, #offThread_breakFlags]
15429    adrl   lr, dvmAsmInstructionStart + (249 * 64)
15430    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15431    cmp    r3, #0
15432    bxeq   lr                   @ nothing to do - jump to real handler
15433    EXPORT_PC()
15434    mov    r0, rPC              @ arg0
15435    mov    r1, rFP              @ arg1
15436    mov    r2, rSELF            @ arg2
15437    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15438
15439/* ------------------------------ */
15440    .balign 64
15441.L_ALT_OP_INVOKE_SUPER_QUICK: /* 0xfa */
15442/* File: armv5te/alt_stub.S */
15443/*
15444 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15445 * any interesting requests and then jump to the real instruction
15446 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15447 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15448 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15449 * bail to the real handler if breakFlags==0.
15450 */
15451    ldrb   r3, [rSELF, #offThread_breakFlags]
15452    adrl   lr, dvmAsmInstructionStart + (250 * 64)
15453    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15454    cmp    r3, #0
15455    bxeq   lr                   @ nothing to do - jump to real handler
15456    EXPORT_PC()
15457    mov    r0, rPC              @ arg0
15458    mov    r1, rFP              @ arg1
15459    mov    r2, rSELF            @ arg2
15460    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15461
15462/* ------------------------------ */
15463    .balign 64
15464.L_ALT_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
15465/* File: armv5te/alt_stub.S */
15466/*
15467 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15468 * any interesting requests and then jump to the real instruction
15469 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15470 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15471 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15472 * bail to the real handler if breakFlags==0.
15473 */
15474    ldrb   r3, [rSELF, #offThread_breakFlags]
15475    adrl   lr, dvmAsmInstructionStart + (251 * 64)
15476    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15477    cmp    r3, #0
15478    bxeq   lr                   @ nothing to do - jump to real handler
15479    EXPORT_PC()
15480    mov    r0, rPC              @ arg0
15481    mov    r1, rFP              @ arg1
15482    mov    r2, rSELF            @ arg2
15483    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15484
15485/* ------------------------------ */
15486    .balign 64
15487.L_ALT_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
15488/* File: armv5te/alt_stub.S */
15489/*
15490 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15491 * any interesting requests and then jump to the real instruction
15492 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15493 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15494 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15495 * bail to the real handler if breakFlags==0.
15496 */
15497    ldrb   r3, [rSELF, #offThread_breakFlags]
15498    adrl   lr, dvmAsmInstructionStart + (252 * 64)
15499    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15500    cmp    r3, #0
15501    bxeq   lr                   @ nothing to do - jump to real handler
15502    EXPORT_PC()
15503    mov    r0, rPC              @ arg0
15504    mov    r1, rFP              @ arg1
15505    mov    r2, rSELF            @ arg2
15506    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15507
15508/* ------------------------------ */
15509    .balign 64
15510.L_ALT_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
15511/* File: armv5te/alt_stub.S */
15512/*
15513 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15514 * any interesting requests and then jump to the real instruction
15515 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15516 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15517 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15518 * bail to the real handler if breakFlags==0.
15519 */
15520    ldrb   r3, [rSELF, #offThread_breakFlags]
15521    adrl   lr, dvmAsmInstructionStart + (253 * 64)
15522    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15523    cmp    r3, #0
15524    bxeq   lr                   @ nothing to do - jump to real handler
15525    EXPORT_PC()
15526    mov    r0, rPC              @ arg0
15527    mov    r1, rFP              @ arg1
15528    mov    r2, rSELF            @ arg2
15529    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15530
15531/* ------------------------------ */
15532    .balign 64
15533.L_ALT_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
15534/* File: armv5te/alt_stub.S */
15535/*
15536 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15537 * any interesting requests and then jump to the real instruction
15538 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15539 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15540 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15541 * bail to the real handler if breakFlags==0.
15542 */
15543    ldrb   r3, [rSELF, #offThread_breakFlags]
15544    adrl   lr, dvmAsmInstructionStart + (254 * 64)
15545    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15546    cmp    r3, #0
15547    bxeq   lr                   @ nothing to do - jump to real handler
15548    EXPORT_PC()
15549    mov    r0, rPC              @ arg0
15550    mov    r1, rFP              @ arg1
15551    mov    r2, rSELF            @ arg2
15552    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15553
15554/* ------------------------------ */
15555    .balign 64
15556.L_ALT_OP_UNUSED_FF: /* 0xff */
15557/* File: armv5te/alt_stub.S */
15558/*
15559 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15560 * any interesting requests and then jump to the real instruction
15561 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15562 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15563 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15564 * bail to the real handler if breakFlags==0.
15565 */
15566    ldrb   r3, [rSELF, #offThread_breakFlags]
15567    adrl   lr, dvmAsmInstructionStart + (255 * 64)
15568    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15569    cmp    r3, #0
15570    bxeq   lr                   @ nothing to do - jump to real handler
15571    EXPORT_PC()
15572    mov    r0, rPC              @ arg0
15573    mov    r1, rFP              @ arg1
15574    mov    r2, rSELF            @ arg2
15575    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15576
15577    .balign 64
15578    .size   dvmAsmAltInstructionStart, .-dvmAsmAltInstructionStart
15579    .global dvmAsmAltInstructionEnd
15580dvmAsmAltInstructionEnd:
15581/* File: armv5te/footer.S */
15582/*
15583 * ===========================================================================
15584 *  Common subroutines and data
15585 * ===========================================================================
15586 */
15587
15588    .text
15589    .align  2
15590
15591#if defined(WITH_JIT)
15592
15593#if defined(WITH_SELF_VERIFICATION)
15594/*
15595 * "longjmp" to a translation after single-stepping.  Before returning
15596 * to translation, must save state for self-verification.
15597 */
15598    .global dvmJitResumeTranslation              @ (Thread* self, u4* dFP)
15599dvmJitResumeTranslation:
15600    mov    rSELF, r0                             @ restore self
15601    mov    rPC, r1                               @ restore Dalvik pc
15602    mov    rFP, r2                               @ restore Dalvik fp
15603    ldr    r10, [rSELF,#offThread_jitResumeNPC]  @ resume address
15604    mov    r2, #0
15605    str    r2, [rSELF,#offThread_jitResumeNPC]   @ reset resume address
15606    ldr    sp, [rSELF,#offThread_jitResumeNSP]   @ cut back native stack
15607    b      jitSVShadowRunStart                   @ resume as if cache hit
15608                                                 @ expects resume addr in r10
15609
15610    .global dvmJitToInterpPunt
15611dvmJitToInterpPunt:
15612    mov    r2,#kSVSPunt                 @ r2<- interpreter entry point
15613    mov    r3, #0
15614    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
15615    b      jitSVShadowRunEnd            @ doesn't return
15616
15617    .global dvmJitToInterpSingleStep
15618dvmJitToInterpSingleStep:
15619    mov    rPC, r0              @ set up dalvik pc
15620    EXPORT_PC()
15621    str    lr, [rSELF,#offThread_jitResumeNPC]
15622    str    sp, [rSELF,#offThread_jitResumeNSP]
15623    str    r1, [rSELF,#offThread_jitResumeDPC]
15624    mov    r2,#kSVSSingleStep           @ r2<- interpreter entry point
15625    b      jitSVShadowRunEnd            @ doesn't return
15626
15627
15628    .global dvmJitToInterpNoChainNoProfile
15629dvmJitToInterpNoChainNoProfile:
15630    mov    r0,rPC                       @ pass our target PC
15631    mov    r2,#kSVSNoProfile            @ r2<- interpreter entry point
15632    mov    r3, #0                       @ 0 means !inJitCodeCache
15633    str    r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land
15634    b      jitSVShadowRunEnd            @ doesn't return
15635
15636    .global dvmJitToInterpTraceSelectNoChain
15637dvmJitToInterpTraceSelectNoChain:
15638    mov    r0,rPC                       @ pass our target PC
15639    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
15640    mov    r3, #0                       @ 0 means !inJitCodeCache
15641    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
15642    b      jitSVShadowRunEnd            @ doesn't return
15643
15644    .global dvmJitToInterpTraceSelect
15645dvmJitToInterpTraceSelect:
15646    ldr    r0,[lr, #-1]                 @ pass our target PC
15647    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
15648    mov    r3, #0                       @ 0 means !inJitCodeCache
15649    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
15650    b      jitSVShadowRunEnd            @ doesn't return
15651
15652    .global dvmJitToInterpBackwardBranch
15653dvmJitToInterpBackwardBranch:
15654    ldr    r0,[lr, #-1]                 @ pass our target PC
15655    mov    r2,#kSVSBackwardBranch       @ r2<- interpreter entry point
15656    mov    r3, #0                       @ 0 means !inJitCodeCache
15657    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
15658    b      jitSVShadowRunEnd            @ doesn't return
15659
15660    .global dvmJitToInterpNormal
15661dvmJitToInterpNormal:
15662    ldr    r0,[lr, #-1]                 @ pass our target PC
15663    mov    r2,#kSVSNormal               @ r2<- interpreter entry point
15664    mov    r3, #0                       @ 0 means !inJitCodeCache
15665    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
15666    b      jitSVShadowRunEnd            @ doesn't return
15667
15668    .global dvmJitToInterpNoChain
15669dvmJitToInterpNoChain:
15670    mov    r0,rPC                       @ pass our target PC
15671    mov    r2,#kSVSNoChain              @ r2<- interpreter entry point
15672    mov    r3, #0                       @ 0 means !inJitCodeCache
15673    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
15674    b      jitSVShadowRunEnd            @ doesn't return
15675#else
15676
15677/*
15678 * "longjmp" to a translation after single-stepping.
15679 */
15680    .global dvmJitResumeTranslation              @ (Thread* self, u4* dFP)
15681dvmJitResumeTranslation:
15682    mov    rSELF, r0                             @ restore self
15683    mov    rPC, r1                               @ restore Dalvik pc
15684    mov    rFP, r2                               @ restore Dalvik fp
15685    ldr    r0, [rSELF,#offThread_jitResumeNPC]
15686    mov    r2, #0
15687    str    r2, [rSELF,#offThread_jitResumeNPC]   @ reset resume address
15688    ldr    sp, [rSELF,#offThread_jitResumeNSP]   @ cut back native stack
15689    bx     r0                                    @ resume translation
15690
15691/*
15692 * Return from the translation cache to the interpreter when the compiler is
15693 * having issues translating/executing a Dalvik instruction. We have to skip
15694 * the code cache lookup otherwise it is possible to indefinitely bouce
15695 * between the interpreter and the code cache if the instruction that fails
15696 * to be compiled happens to be at a trace start.
15697 */
15698    .global dvmJitToInterpPunt
15699dvmJitToInterpPunt:
15700    mov    rPC, r0
15701#if defined(WITH_JIT_TUNING)
15702    mov    r0,lr
15703    bl     dvmBumpPunt;
15704#endif
15705    EXPORT_PC()
15706    mov    r0, #0
15707    str    r0, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
15708    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15709    FETCH_INST()
15710    GET_INST_OPCODE(ip)
15711    GOTO_OPCODE(ip)
15712
15713/*
15714 * Return to the interpreter to handle a single instruction.
15715 * We'll use the normal single-stepping mechanism via interpBreak,
15716 * but also save the native pc of the resume point in the translation
15717 * and the native sp so that we can later do the equivalent of a
15718 * longjmp() to resume.
15719 * On entry:
15720 *    dPC <= Dalvik PC of instrucion to interpret
15721 *    lr <= resume point in translation
15722 *    r1 <= Dalvik PC of next instruction
15723 */
15724    .global dvmJitToInterpSingleStep
15725dvmJitToInterpSingleStep:
15726    mov    rPC, r0              @ set up dalvik pc
15727    EXPORT_PC()
15728    str    lr, [rSELF,#offThread_jitResumeNPC]
15729    str    sp, [rSELF,#offThread_jitResumeNSP]
15730    str    r1, [rSELF,#offThread_jitResumeDPC]
15731    mov    r1, #1
15732    str    r1, [rSELF,#offThread_singleStepCount]  @ just step once
15733    mov    r0, rSELF
15734    mov    r1, #kSubModeCountedStep
15735    bl     dvmEnableSubMode     @ (self, newMode)
15736    ldr    rIBASE, [rSELF,#offThread_curHandlerTable]
15737    FETCH_INST()
15738    GET_INST_OPCODE(ip)
15739    GOTO_OPCODE(ip)
15740
15741/*
15742 * Return from the translation cache and immediately request
15743 * a translation for the exit target.  Commonly used for callees.
15744 */
15745    .global dvmJitToInterpTraceSelectNoChain
15746dvmJitToInterpTraceSelectNoChain:
15747#if defined(WITH_JIT_TUNING)
15748    bl     dvmBumpNoChain
15749#endif
15750    mov    r0,rPC
15751    mov    r1,rSELF
15752    bl     dvmJitGetTraceAddrThread @ (pc, self)
15753    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
15754    mov    r1, rPC                  @ arg1 of translation may need this
15755    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
15756    cmp    r0,#0                    @ !0 means translation exists
15757    bxne   r0                       @ continue native execution if so
15758    b      2f                       @ branch over to use the interpreter
15759
15760/*
15761 * Return from the translation cache and immediately request
15762 * a translation for the exit target.  Commonly used following
15763 * invokes.
15764 */
15765    .global dvmJitToInterpTraceSelect
15766dvmJitToInterpTraceSelect:
15767    ldr    rPC,[lr, #-1]           @ get our target PC
15768    add    rINST,lr,#-5            @ save start of chain branch
15769    add    rINST, #-4              @  .. which is 9 bytes back
15770    mov    r0,rPC
15771    mov    r1,rSELF
15772    bl     dvmJitGetTraceAddrThread @ (pc, self)
15773    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
15774    cmp    r0,#0
15775    beq    2f
15776    mov    r1,rINST
15777    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
15778    mov    r1, rPC                  @ arg1 of translation may need this
15779    mov    lr, #0                   @ in case target is HANDLER_INTERPRET
15780    cmp    r0,#0                    @ successful chain?
15781    bxne   r0                       @ continue native execution
15782    b      toInterpreter            @ didn't chain - resume with interpreter
15783
15784/* No translation, so request one if profiling isn't disabled*/
157852:
15786    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15787    ldr    r0, [rSELF, #offThread_pJitProfTable]
15788    FETCH_INST()
15789    cmp    r0, #0
15790    movne  r2,#kJitTSelectRequestHot   @ ask for trace selection
15791    bne    common_selectTrace
15792    GET_INST_OPCODE(ip)
15793    GOTO_OPCODE(ip)
15794
15795/*
15796 * Return from the translation cache to the interpreter.
15797 * The return was done with a BLX from thumb mode, and
15798 * the following 32-bit word contains the target rPC value.
15799 * Note that lr (r14) will have its low-order bit set to denote
15800 * its thumb-mode origin.
15801 *
15802 * We'll need to stash our lr origin away, recover the new
15803 * target and then check to see if there is a translation available
15804 * for our new target.  If so, we do a translation chain and
15805 * go back to native execution.  Otherwise, it's back to the
15806 * interpreter (after treating this entry as a potential
15807 * trace start).
15808 */
15809    .global dvmJitToInterpNormal
15810dvmJitToInterpNormal:
15811    ldr    rPC,[lr, #-1]           @ get our target PC
15812    add    rINST,lr,#-5            @ save start of chain branch
15813    add    rINST,#-4               @ .. which is 9 bytes back
15814#if defined(WITH_JIT_TUNING)
15815    bl     dvmBumpNormal
15816#endif
15817    mov    r0,rPC
15818    mov    r1,rSELF
15819    bl     dvmJitGetTraceAddrThread @ (pc, self)
15820    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
15821    cmp    r0,#0
15822    beq    toInterpreter            @ go if not, otherwise do chain
15823    mov    r1,rINST
15824    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
15825    mov    r1, rPC                  @ arg1 of translation may need this
15826    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
15827    cmp    r0,#0                    @ successful chain?
15828    bxne   r0                       @ continue native execution
15829    b      toInterpreter            @ didn't chain - resume with interpreter
15830
15831/*
15832 * Return from the translation cache to the interpreter to do method invocation.
15833 * Check if translation exists for the callee, but don't chain to it.
15834 */
15835    .global dvmJitToInterpNoChainNoProfile
15836dvmJitToInterpNoChainNoProfile:
15837#if defined(WITH_JIT_TUNING)
15838    bl     dvmBumpNoChain
15839#endif
15840    mov    r0,rPC
15841    mov    r1,rSELF
15842    bl     dvmJitGetTraceAddrThread @ (pc, self)
15843    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
15844    mov    r1, rPC                  @ arg1 of translation may need this
15845    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
15846    cmp    r0,#0
15847    bxne   r0                       @ continue native execution if so
15848    EXPORT_PC()
15849    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15850    FETCH_INST()
15851    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
15852    GOTO_OPCODE(ip)                     @ jump to next instruction
15853
15854/*
15855 * Return from the translation cache to the interpreter to do method invocation.
15856 * Check if translation exists for the callee, but don't chain to it.
15857 */
15858    .global dvmJitToInterpNoChain
15859dvmJitToInterpNoChain:
15860#if defined(WITH_JIT_TUNING)
15861    bl     dvmBumpNoChain
15862#endif
15863    mov    r0,rPC
15864    mov    r1,rSELF
15865    bl     dvmJitGetTraceAddrThread @ (pc, self)
15866    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
15867    mov    r1, rPC                  @ arg1 of translation may need this
15868    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
15869    cmp    r0,#0
15870    bxne   r0                       @ continue native execution if so
15871#endif
15872
15873/*
15874 * No translation, restore interpreter regs and start interpreting.
15875 * rSELF & rFP were preserved in the translated code, and rPC has
15876 * already been restored by the time we get here.  We'll need to set
15877 * up rIBASE & rINST, and load the address of the JitTable into r0.
15878 */
15879toInterpreter:
15880    EXPORT_PC()
15881    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15882    FETCH_INST()
15883    ldr    r0, [rSELF, #offThread_pJitProfTable]
15884    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15885    @ NOTE: intended fallthrough
15886
15887/*
15888 * Similar to common_updateProfile, but tests for null pJitProfTable
15889 * r0 holds pJifProfTAble, rINST is loaded, rPC is current and
15890 * rIBASE has been recently refreshed.
15891 */
15892common_testUpdateProfile:
15893    cmp     r0, #0               @ JIT switched off?
15894    beq     4f                   @ return to interp if so
15895
15896/*
15897 * Common code to update potential trace start counter, and initiate
15898 * a trace-build if appropriate.
15899 * On entry here:
15900 *    r0    <= pJitProfTable (verified non-NULL)
15901 *    rPC   <= Dalvik PC
15902 *    rINST <= next instruction
15903 */
15904common_updateProfile:
15905    eor     r3,rPC,rPC,lsr #12 @ cheap, but fast hash function
15906    lsl     r3,r3,#(32 - JIT_PROF_SIZE_LOG_2)          @ shift out excess bits
15907    ldrb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter
15908    GET_INST_OPCODE(ip)
15909    subs    r1,r1,#1           @ decrement counter
15910    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it
15911    GOTO_OPCODE_IFNE(ip)       @ if not threshold, fallthrough otherwise */
15912
15913    /* Looks good, reset the counter */
15914    ldr     r1, [rSELF, #offThread_jitThreshold]
15915    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter
15916    EXPORT_PC()
15917    mov     r0,rPC
15918    mov     r1,rSELF
15919    bl      dvmJitGetTraceAddrThread    @ (pc, self)
15920    str     r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
15921    mov     r1, rPC                     @ arg1 of translation may need this
15922    mov     lr, #0                      @  in case target is HANDLER_INTERPRET
15923    cmp     r0,#0
15924#if !defined(WITH_SELF_VERIFICATION)
15925    bxne    r0                          @ jump to the translation
15926    mov     r2,#kJitTSelectRequest      @ ask for trace selection
15927    @ fall-through to common_selectTrace
15928#else
15929    moveq   r2,#kJitTSelectRequest      @ ask for trace selection
15930    beq     common_selectTrace
15931    /*
15932     * At this point, we have a target translation.  However, if
15933     * that translation is actually the interpret-only pseudo-translation
15934     * we want to treat it the same as no translation.
15935     */
15936    mov     r10, r0                     @ save target
15937    bl      dvmCompilerGetInterpretTemplate
15938    cmp     r0, r10                     @ special case?
15939    bne     jitSVShadowRunStart         @ set up self verification shadow space
15940    @ Need to clear the inJitCodeCache flag
15941    mov    r3, #0                       @ 0 means not in the JIT code cache
15942    str    r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land
15943    GET_INST_OPCODE(ip)
15944    GOTO_OPCODE(ip)
15945    /* no return */
15946#endif
15947
15948/*
15949 * On entry:
15950 *  r2 is jit state.
15951 */
15952common_selectTrace:
15953    ldrh    r0,[rSELF,#offThread_subMode]
15954    ands    r0, #(kSubModeJitTraceBuild | kSubModeJitSV)
15955    bne     3f                         @ already doing JIT work, continue
15956    str     r2,[rSELF,#offThread_jitState]
15957    mov     r0, rSELF
15958/*
15959 * Call out to validate trace-building request.  If successful,
15960 * rIBASE will be swapped to to send us into single-stepping trace
15961 * building mode, so we need to refresh before we continue.
15962 */
15963    EXPORT_PC()
15964    SAVE_PC_FP_TO_SELF()                 @ copy of pc/fp to Thread
15965    bl      dvmJitCheckTraceRequest
159663:
15967    FETCH_INST()
15968    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
159694:
15970    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
15971    GOTO_OPCODE(ip)
15972    /* no return */
15973#endif
15974
15975#if defined(WITH_SELF_VERIFICATION)
15976/*
15977 * Save PC and registers to shadow memory for self verification mode
15978 * before jumping to native translation.
15979 * On entry:
15980 *    rPC, rFP, rSELF: the values that they should contain
15981 *    r10: the address of the target translation.
15982 */
15983jitSVShadowRunStart:
15984    mov     r0,rPC                      @ r0<- program counter
15985    mov     r1,rFP                      @ r1<- frame pointer
15986    mov     r2,rSELF                    @ r2<- self (Thread) pointer
15987    mov     r3,r10                      @ r3<- target translation
15988    bl      dvmSelfVerificationSaveState @ save registers to shadow space
15989    ldr     rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space
15990    bx      r10                         @ jump to the translation
15991
15992/*
15993 * Restore PC, registers, and interpreter state to original values
15994 * before jumping back to the interpreter.
15995 * On entry:
15996 *   r0:  dPC
15997 *   r2:  self verification state
15998 */
15999jitSVShadowRunEnd:
16000    mov    r1,rFP                        @ pass ending fp
16001    mov    r3,rSELF                      @ pass self ptr for convenience
16002    bl     dvmSelfVerificationRestoreState @ restore pc and fp values
16003    LOAD_PC_FP_FROM_SELF()               @ restore pc, fp
16004    ldr    r1,[r0,#offShadowSpace_svState] @ get self verification state
16005    cmp    r1,#0                         @ check for punt condition
16006    beq    1f
16007    @ Set up SV single-stepping
16008    mov    r0, rSELF
16009    mov    r1, #kSubModeJitSV
16010    bl     dvmEnableSubMode              @ (self, subMode)
16011    mov    r2,#kJitSelfVerification      @ ask for self verification
16012    str    r2,[rSELF,#offThread_jitState]
16013    @ intentional fallthrough
160141:                                       @ exit to interpreter without check
16015    EXPORT_PC()
16016    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
16017    FETCH_INST()
16018    GET_INST_OPCODE(ip)
16019    GOTO_OPCODE(ip)
16020#endif
16021
16022/*
16023 * The equivalent of "goto bail", this calls through the "bail handler".
16024 * It will end this interpreter activation, and return to the caller
16025 * of dvmMterpStdRun.
16026 *
16027 * State registers will be saved to the "thread" area before bailing
16028 * debugging purposes
16029 */
16030common_gotoBail:
16031    SAVE_PC_FP_TO_SELF()                @ export state to "thread"
16032    mov     r0, rSELF                   @ r0<- self ptr
16033    b       dvmMterpStdBail             @ call(self, changeInterp)
16034
16035/*
16036 * The JIT's invoke method needs to remember the callsite class and
16037 * target pair.  Save them here so that they are available to
16038 * dvmCheckJit following the interpretation of this invoke.
16039 */
16040#if defined(WITH_JIT)
16041save_callsiteinfo:
16042    cmp     r9, #0
16043    ldrne   r9, [r9, #offObject_clazz]
16044    str     r0, [rSELF, #offThread_methodToCall]
16045    str     r9, [rSELF, #offThread_callsiteClass]
16046    bx      lr
16047#endif
16048
16049/*
16050 * Common code for method invocation with range.
16051 *
16052 * On entry:
16053 *  r0 is "Method* methodToCall", r9 is "this"
16054 */
16055common_invokeMethodRange:
16056.LinvokeNewRange:
16057#if defined(WITH_JIT)
16058    ldrh    r1, [rSELF, #offThread_subMode]
16059    ands    r1, #kSubModeJitTraceBuild
16060    blne    save_callsiteinfo
16061#endif
16062    @ prepare to copy args to "outs" area of current frame
16063    movs    r2, rINST, lsr #8           @ r2<- AA (arg count) -- test for zero
16064    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
16065    beq     .LinvokeArgsDone            @ if no args, skip the rest
16066    FETCH(r1, 2)                        @ r1<- CCCC
16067
16068.LinvokeRangeArgs:
16069    @ r0=methodToCall, r1=CCCC, r2=count, r10=outs
16070    @ (very few methods have > 10 args; could unroll for common cases)
16071    add     r3, rFP, r1, lsl #2         @ r3<- &fp[CCCC]
16072    sub     r10, r10, r2, lsl #2        @ r10<- "outs" area, for call args
160731:  ldr     r1, [r3], #4                @ val = *fp++
16074    subs    r2, r2, #1                  @ count--
16075    str     r1, [r10], #4               @ *outs++ = val
16076    bne     1b                          @ ...while count != 0
16077    b       .LinvokeArgsDone
16078
16079/*
16080 * Common code for method invocation without range.
16081 *
16082 * On entry:
16083 *  r0 is "Method* methodToCall", r9 is "this"
16084 */
16085common_invokeMethodNoRange:
16086.LinvokeNewNoRange:
16087#if defined(WITH_JIT)
16088    ldrh    r1, [rSELF, #offThread_subMode]
16089    ands    r1, #kSubModeJitTraceBuild
16090    blne    save_callsiteinfo
16091#endif
16092    @ prepare to copy args to "outs" area of current frame
16093    movs    r2, rINST, lsr #12          @ r2<- B (arg count) -- test for zero
16094    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
16095    FETCH(r1, 2)                        @ r1<- GFED (load here to hide latency)
16096    beq     .LinvokeArgsDone
16097
16098    @ r0=methodToCall, r1=GFED, r2=count, r10=outs
16099.LinvokeNonRange:
16100    rsb     r2, r2, #5                  @ r2<- 5-r2
16101    add     pc, pc, r2, lsl #4          @ computed goto, 4 instrs each
16102    bl      common_abort                @ (skipped due to ARM prefetch)
161035:  and     ip, rINST, #0x0f00          @ isolate A
16104    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vA (shift right 8, left 2)
16105    mov     r0, r0                      @ nop
16106    str     r2, [r10, #-4]!             @ *--outs = vA
161074:  and     ip, r1, #0xf000             @ isolate G
16108    ldr     r2, [rFP, ip, lsr #10]      @ r2<- vG (shift right 12, left 2)
16109    mov     r0, r0                      @ nop
16110    str     r2, [r10, #-4]!             @ *--outs = vG
161113:  and     ip, r1, #0x0f00             @ isolate F
16112    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vF
16113    mov     r0, r0                      @ nop
16114    str     r2, [r10, #-4]!             @ *--outs = vF
161152:  and     ip, r1, #0x00f0             @ isolate E
16116    ldr     r2, [rFP, ip, lsr #2]       @ r2<- vE
16117    mov     r0, r0                      @ nop
16118    str     r2, [r10, #-4]!             @ *--outs = vE
161191:  and     ip, r1, #0x000f             @ isolate D
16120    ldr     r2, [rFP, ip, lsl #2]       @ r2<- vD
16121    mov     r0, r0                      @ nop
16122    str     r2, [r10, #-4]!             @ *--outs = vD
161230:  @ fall through to .LinvokeArgsDone
16124
16125.LinvokeArgsDone: @ r0=methodToCall
16126    ldrh    r9, [r0, #offMethod_registersSize]  @ r9<- methodToCall->regsSize
16127    ldrh    r3, [r0, #offMethod_outsSize]  @ r3<- methodToCall->outsSize
16128    ldr     r2, [r0, #offMethod_insns]  @ r2<- method->insns
16129    ldr     rINST, [r0, #offMethod_clazz]  @ rINST<- method->clazz
16130    @ find space for the new stack frame, check for overflow
16131    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- stack save area
16132    sub     r1, r1, r9, lsl #2          @ r1<- newFp (old savearea - regsSize)
16133    SAVEAREA_FROM_FP(r10, r1)           @ r10<- newSaveArea
16134@    bl      common_dumpRegs
16135    ldr     r9, [rSELF, #offThread_interpStackEnd]    @ r9<- interpStackEnd
16136    sub     r3, r10, r3, lsl #2         @ r3<- bottom (newsave - outsSize)
16137    cmp     r3, r9                      @ bottom < interpStackEnd?
16138    ldrh    lr, [rSELF, #offThread_subMode]
16139    ldr     r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags
16140    blo     .LstackOverflow             @ yes, this frame will overflow stack
16141
16142    @ set up newSaveArea
16143#ifdef EASY_GDB
16144    SAVEAREA_FROM_FP(ip, rFP)           @ ip<- stack save area
16145    str     ip, [r10, #offStackSaveArea_prevSave]
16146#endif
16147    str     rFP, [r10, #offStackSaveArea_prevFrame]
16148    str     rPC, [r10, #offStackSaveArea_savedPc]
16149#if defined(WITH_JIT)
16150    mov     r9, #0
16151    str     r9, [r10, #offStackSaveArea_returnAddr]
16152#endif
16153    str     r0, [r10, #offStackSaveArea_method]
16154
16155    @ Profiling?
16156    cmp     lr, #0                      @ any special modes happening?
16157    bne     2f                          @ go if so
161581:
16159    tst     r3, #ACC_NATIVE
16160    bne     .LinvokeNative
16161
16162    /*
16163    stmfd   sp!, {r0-r3}
16164    bl      common_printNewline
16165    mov     r0, rFP
16166    mov     r1, #0
16167    bl      dvmDumpFp
16168    ldmfd   sp!, {r0-r3}
16169    stmfd   sp!, {r0-r3}
16170    mov     r0, r1
16171    mov     r1, r10
16172    bl      dvmDumpFp
16173    bl      common_printNewline
16174    ldmfd   sp!, {r0-r3}
16175    */
16176
16177    ldrh    r9, [r2]                        @ r9 <- load INST from new PC
16178    ldr     r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
16179    mov     rPC, r2                         @ publish new rPC
16180
16181    @ Update state values for the new method
16182    @ r0=methodToCall, r1=newFp, r3=newMethodClass, r9=newINST
16183    str     r0, [rSELF, #offThread_method]    @ self->method = methodToCall
16184    str     r3, [rSELF, #offThread_methodClassDex] @ self->methodClassDex = ...
16185    mov     r2, #1
16186    str     r2, [rSELF, #offThread_debugIsMethodEntry]
16187#if defined(WITH_JIT)
16188    ldr     r0, [rSELF, #offThread_pJitProfTable]
16189    mov     rFP, r1                         @ fp = newFp
16190    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
16191    mov     rINST, r9                       @ publish new rINST
16192    str     r1, [rSELF, #offThread_curFrame]   @ curFrame = newFp
16193    cmp     r0,#0
16194    bne     common_updateProfile
16195    GOTO_OPCODE(ip)                         @ jump to next instruction
16196#else
16197    mov     rFP, r1                         @ fp = newFp
16198    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
16199    mov     rINST, r9                       @ publish new rINST
16200    str     r1, [rSELF, #offThread_curFrame]   @ curFrame = newFp
16201    GOTO_OPCODE(ip)                         @ jump to next instruction
16202#endif
16203
162042:
16205    @ Profiling - record method entry.  r0: methodToCall
16206    stmfd   sp!, {r0-r3}                @ preserve r0-r3
16207    str     rPC, [rSELF, #offThread_pc] @ update interpSave.pc
16208    mov     r1, r0
16209    mov     r0, rSELF
16210    bl      dvmReportInvoke             @ (self, method)
16211    ldmfd   sp!, {r0-r3}                @ restore r0-r3
16212    b       1b
16213
16214.LinvokeNative:
16215    @ Prep for the native call
16216    @ r0=methodToCall, r1=newFp, r10=newSaveArea
16217    ldrh    lr, [rSELF, #offThread_subMode]
16218    ldr     r9, [rSELF, #offThread_jniLocal_topCookie]@r9<-thread->localRef->...
16219    str     r1, [rSELF, #offThread_curFrame]   @ curFrame = newFp
16220    str     r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top
16221    mov     r2, r0                      @ r2<- methodToCall
16222    mov     r0, r1                      @ r0<- newFp (points to args)
16223    add     r1, rSELF, #offThread_retval  @ r1<- &retval
16224    mov     r3, rSELF                   @ arg3<- self
16225
16226#ifdef ASSIST_DEBUGGER
16227    /* insert fake function header to help gdb find the stack frame */
16228    b       .Lskip
16229    .type   dalvik_mterp, %function
16230dalvik_mterp:
16231    .fnstart
16232    MTERP_ENTRY1
16233    MTERP_ENTRY2
16234.Lskip:
16235#endif
16236
16237    cmp     lr, #0                      @ any special SubModes active?
16238    bne     11f                         @ go handle them if so
16239    ldr     ip, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
16240    blx     ip
162417:
16242
16243    @ native return; r10=newSaveArea
16244    @ equivalent to dvmPopJniLocals
16245    ldr     r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top
16246    ldr     r1, [rSELF, #offThread_exception] @ check for exception
16247    str     rFP, [rSELF, #offThread_curFrame]  @ curFrame = fp
16248    cmp     r1, #0                      @ null?
16249    str     r0, [rSELF, #offThread_jniLocal_topCookie] @ new top <- old top
16250    bne     common_exceptionThrown      @ no, handle exception
16251
16252    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
16253    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
16254    GOTO_OPCODE(ip)                     @ jump to next instruction
16255
1625611:
16257    @ r0=newFp, r1=&retval, r2=methodToCall, r3=self, lr=subModes
16258    stmfd   sp!, {r0-r3}                @ save all but subModes
16259    mov     r0, r2                      @ r0<- methodToCall
16260    mov     r1, rSELF
16261    mov     r2, rFP
16262    bl      dvmReportPreNativeInvoke    @ (methodToCall, self, fp)
16263    ldmfd   sp, {r0-r3}                 @ refresh.  NOTE: no sp autoincrement
16264
16265    @ Call the native method
16266    ldr     ip, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
16267    blx     ip
16268
16269    @ Restore the pre-call arguments
16270    ldmfd   sp!, {r0-r3}                @ r2<- methodToCall (others unneeded)
16271
16272    @ Finish up any post-invoke subMode requirements
16273    mov     r0, r2                      @ r0<- methodToCall
16274    mov     r1, rSELF
16275    mov     r2, rFP
16276    bl      dvmReportPostNativeInvoke   @ (methodToCall, self, fp)
16277    b       7b                          @ resume
16278
16279.LstackOverflow:    @ r0=methodToCall
16280    mov     r1, r0                      @ r1<- methodToCall
16281    mov     r0, rSELF                   @ r0<- self
16282    bl      dvmHandleStackOverflow
16283    b       common_exceptionThrown
16284#ifdef ASSIST_DEBUGGER
16285    .fnend
16286    .size   dalvik_mterp, .-dalvik_mterp
16287#endif
16288
16289
16290    /*
16291     * Common code for method invocation, calling through "glue code".
16292     *
16293     * TODO: now that we have range and non-range invoke handlers, this
16294     *       needs to be split into two.  Maybe just create entry points
16295     *       that set r9 and jump here?
16296     *
16297     * On entry:
16298     *  r0 is "Method* methodToCall", the method we're trying to call
16299     *  r9 is "bool methodCallRange", indicating if this is a /range variant
16300     */
16301     .if    0
16302.LinvokeOld:
16303    sub     sp, sp, #8                  @ space for args + pad
16304    FETCH(ip, 2)                        @ ip<- FEDC or CCCC
16305    mov     r2, r0                      @ A2<- methodToCall
16306    mov     r0, rSELF                   @ A0<- self
16307    SAVE_PC_FP_TO_SELF()                @ export state to "self"
16308    mov     r1, r9                      @ A1<- methodCallRange
16309    mov     r3, rINST, lsr #8           @ A3<- AA
16310    str     ip, [sp, #0]                @ A4<- ip
16311    bl      dvmMterp_invokeMethod       @ call the C invokeMethod
16312    add     sp, sp, #8                  @ remove arg area
16313    b       common_resumeAfterGlueCall  @ continue to next instruction
16314    .endif
16315
16316
16317
16318/*
16319 * Common code for handling a return instruction.
16320 *
16321 * This does not return.
16322 */
16323common_returnFromMethod:
16324.LreturnNew:
16325    ldrh    lr, [rSELF, #offThread_subMode]
16326    SAVEAREA_FROM_FP(r0, rFP)
16327    ldr     r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc
16328    cmp     lr, #0                      @ any special subMode handling needed?
16329    bne     19f
1633014:
16331    ldr     rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame
16332    ldr     r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)]
16333                                        @ r2<- method we're returning to
16334    cmp     r2, #0                      @ is this a break frame?
16335#if defined(WORKAROUND_CORTEX_A9_745320)
16336    /* Don't use conditional loads if the HW defect exists */
16337    beq     15f
16338    ldr     r10, [r2, #offMethod_clazz] @ r10<- method->clazz
1633915:
16340#else
16341    ldrne   r10, [r2, #offMethod_clazz] @ r10<- method->clazz
16342#endif
16343    beq     common_gotoBail             @ break frame, bail out completely
16344
16345    ldr     rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
16346    PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST
16347    str     r2, [rSELF, #offThread_method]@ self->method = newSave->method
16348    ldr     r1, [r10, #offClassObject_pDvmDex]   @ r1<- method->clazz->pDvmDex
16349    str     rFP, [rSELF, #offThread_curFrame]  @ curFrame = fp
16350#if defined(WITH_JIT)
16351    ldr     r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr
16352    mov     rPC, r9                     @ publish new rPC
16353    str     r1, [rSELF, #offThread_methodClassDex]
16354    str     r10, [rSELF, #offThread_inJitCodeCache]  @ may return to JIT'ed land
16355    cmp     r10, #0                      @ caller is compiled code
16356    blxne   r10
16357    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
16358    GOTO_OPCODE(ip)                     @ jump to next instruction
16359#else
16360    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
16361    mov     rPC, r9                     @ publish new rPC
16362    str     r1, [rSELF, #offThread_methodClassDex]
16363    GOTO_OPCODE(ip)                     @ jump to next instruction
16364#endif
16365
1636619:
16367    @ Handle special actions
16368    @ On entry, r0: StackSaveArea
16369    ldr     r1, [r0, #offStackSaveArea_prevFrame]  @ r2<- prevFP
16370    str     rPC, [rSELF, #offThread_pc] @ update interpSave.pc
16371    str     r1, [rSELF, #offThread_curFrame]   @ update interpSave.curFrame
16372    mov     r0, rSELF
16373    bl      dvmReportReturn             @ (self)
16374    SAVEAREA_FROM_FP(r0, rFP)           @ restore StackSaveArea
16375    b       14b                         @ continue
16376
16377    /*
16378     * Return handling, calls through "glue code".
16379     */
16380     .if    0
16381.LreturnOld:
16382    SAVE_PC_FP_TO_SELF()                @ export state
16383    mov     r0, rSELF                   @ arg to function
16384    bl      dvmMterp_returnFromMethod
16385    b       common_resumeAfterGlueCall
16386    .endif
16387
16388
16389/*
16390 * Somebody has thrown an exception.  Handle it.
16391 *
16392 * If the exception processing code returns to us (instead of falling
16393 * out of the interpreter), continue with whatever the next instruction
16394 * now happens to be.
16395 *
16396 * This does not return.
16397 */
16398     .global dvmMterpCommonExceptionThrown
16399dvmMterpCommonExceptionThrown:
16400common_exceptionThrown:
16401.LexceptionNew:
16402
16403    EXPORT_PC()
16404
16405    mov     r0, rSELF
16406    bl      dvmCheckSuspendPending
16407
16408    ldr     r9, [rSELF, #offThread_exception] @ r9<- self->exception
16409    mov     r1, rSELF                   @ r1<- self
16410    mov     r0, r9                      @ r0<- exception
16411    bl      dvmAddTrackedAlloc          @ don't let the exception be GCed
16412    ldrh    r2, [rSELF, #offThread_subMode]  @ get subMode flags
16413    mov     r3, #0                      @ r3<- NULL
16414    str     r3, [rSELF, #offThread_exception] @ self->exception = NULL
16415
16416    @ Special subMode?
16417    cmp     r2, #0                      @ any special subMode handling needed?
16418    bne     7f                          @ go if so
164198:
16420    /* set up args and a local for "&fp" */
16421    /* (str sp, [sp, #-4]!  would be perfect here, but is discouraged) */
16422    str     rFP, [sp, #-4]!             @ *--sp = fp
16423    mov     ip, sp                      @ ip<- &fp
16424    mov     r3, #0                      @ r3<- false
16425    str     ip, [sp, #-4]!              @ *--sp = &fp
16426    ldr     r1, [rSELF, #offThread_method] @ r1<- self->method
16427    mov     r0, rSELF                   @ r0<- self
16428    ldr     r1, [r1, #offMethod_insns]  @ r1<- method->insns
16429    ldrh    lr, [rSELF, #offThread_subMode]  @ lr<- subMode flags
16430    mov     r2, r9                      @ r2<- exception
16431    sub     r1, rPC, r1                 @ r1<- pc - method->insns
16432    mov     r1, r1, asr #1              @ r1<- offset in code units
16433
16434    /* call, r0 gets catchRelPc (a code-unit offset) */
16435    bl      dvmFindCatchBlock           @ call(self, relPc, exc, scan?, &fp)
16436
16437    /* fix earlier stack overflow if necessary; may trash rFP */
16438    ldrb    r1, [rSELF, #offThread_stackOverflowed]
16439    cmp     r1, #0                      @ did we overflow earlier?
16440    beq     1f                          @ no, skip ahead
16441    mov     rFP, r0                     @ save relPc result in rFP
16442    mov     r0, rSELF                   @ r0<- self
16443    mov     r1, r9                      @ r1<- exception
16444    bl      dvmCleanupStackOverflow     @ call(self)
16445    mov     r0, rFP                     @ restore result
164461:
16447
16448    /* update frame pointer and check result from dvmFindCatchBlock */
16449    ldr     rFP, [sp, #4]               @ retrieve the updated rFP
16450    cmp     r0, #0                      @ is catchRelPc < 0?
16451    add     sp, sp, #8                  @ restore stack
16452    bmi     .LnotCaughtLocally
16453
16454    /* adjust locals to match self->interpSave.curFrame and updated PC */
16455    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- new save area
16456    ldr     r1, [r1, #offStackSaveArea_method] @ r1<- new method
16457    str     r1, [rSELF, #offThread_method]  @ self->method = new method
16458    ldr     r2, [r1, #offMethod_clazz]      @ r2<- method->clazz
16459    ldr     r3, [r1, #offMethod_insns]      @ r3<- method->insns
16460    ldr     r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex
16461    add     rPC, r3, r0, asl #1             @ rPC<- method->insns + catchRelPc
16462    str     r2, [rSELF, #offThread_methodClassDex] @ self->pDvmDex = meth...
16463
16464    /* release the tracked alloc on the exception */
16465    mov     r0, r9                      @ r0<- exception
16466    mov     r1, rSELF                   @ r1<- self
16467    bl      dvmReleaseTrackedAlloc      @ release the exception
16468
16469    /* restore the exception if the handler wants it */
16470    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
16471    FETCH_INST()                        @ load rINST from rPC
16472    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
16473    cmp     ip, #OP_MOVE_EXCEPTION      @ is it "move-exception"?
16474    streq   r9, [rSELF, #offThread_exception] @ yes, restore the exception
16475    GOTO_OPCODE(ip)                     @ jump to next instruction
16476
16477    @ Manage debugger bookkeeping
164787:
16479    str     rPC, [rSELF, #offThread_pc]     @ update interpSave.pc
16480    str     rFP, [rSELF, #offThread_curFrame]     @ update interpSave.curFrame
16481    mov     r0, rSELF                       @ arg0<- self
16482    mov     r1, r9                          @ arg1<- exception
16483    bl      dvmReportExceptionThrow         @ (self, exception)
16484    b       8b                              @ resume with normal handling
16485
16486.LnotCaughtLocally: @ r9=exception
16487    /* fix stack overflow if necessary */
16488    ldrb    r1, [rSELF, #offThread_stackOverflowed]
16489    cmp     r1, #0                      @ did we overflow earlier?
16490    movne   r0, rSELF                   @ if yes: r0<- self
16491    movne   r1, r9                      @ if yes: r1<- exception
16492    blne    dvmCleanupStackOverflow     @ if yes: call(self)
16493
16494    @ may want to show "not caught locally" debug messages here
16495#if DVM_SHOW_EXCEPTION >= 2
16496    /* call __android_log_print(prio, tag, format, ...) */
16497    /* "Exception %s from %s:%d not caught locally" */
16498    @ dvmLineNumFromPC(method, pc - method->insns)
16499    ldr     r0, [rSELF, #offThread_method]
16500    ldr     r1, [r0, #offMethod_insns]
16501    sub     r1, rPC, r1
16502    asr     r1, r1, #1
16503    bl      dvmLineNumFromPC
16504    str     r0, [sp, #-4]!
16505    @ dvmGetMethodSourceFile(method)
16506    ldr     r0, [rSELF, #offThread_method]
16507    bl      dvmGetMethodSourceFile
16508    str     r0, [sp, #-4]!
16509    @ exception->clazz->descriptor
16510    ldr     r3, [r9, #offObject_clazz]
16511    ldr     r3, [r3, #offClassObject_descriptor]
16512    @
16513    ldr     r2, strExceptionNotCaughtLocally
165140:  add     r2, pc
16515    ldr     r1, strLogTag
165161:  add     r1, pc
16517    mov     r0, #3                      @ LOG_DEBUG
16518    bl      __android_log_print
16519#endif
16520    str     r9, [rSELF, #offThread_exception] @ restore exception
16521    mov     r0, r9                      @ r0<- exception
16522    mov     r1, rSELF                   @ r1<- self
16523    bl      dvmReleaseTrackedAlloc      @ release the exception
16524    b       common_gotoBail             @ bail out
16525
16526strExceptionNotCaughtLocally:
16527    .word   PCREL_REF(.LstrExceptionNotCaughtLocally,0b)
16528strLogTag:
16529    .word   PCREL_REF(.LstrLogTag,1b)
16530
16531    /*
16532     * Exception handling, calls through "glue code".
16533     */
16534    .if     0
16535.LexceptionOld:
16536    SAVE_PC_FP_TO_SELF()                @ export state
16537    mov     r0, rSELF                   @ arg to function
16538    bl      dvmMterp_exceptionThrown
16539    b       common_resumeAfterGlueCall
16540    .endif
16541
16542#if defined(WITH_JIT)
16543    /*
16544     * If the JIT is actively building a trace we need to make sure
16545     * that the field is fully resolved before including the current
16546     * instruction.
16547     *
16548     * On entry:
16549     *     r10: &dvmDex->pResFields[field]
16550     *     r0:  field pointer (must preserve)
16551     */
16552common_verifyField:
16553    ldrh    r3, [rSELF, #offThread_subMode]  @ r3 <- submode byte
16554    ands    r3, #kSubModeJitTraceBuild
16555    bxeq    lr                          @ Not building trace, continue
16556    ldr     r1, [r10]                   @ r1<- reload resolved StaticField ptr
16557    cmp     r1, #0                      @ resolution complete?
16558    bxne    lr                          @ yes, continue
16559    stmfd   sp!, {r0-r2,lr}             @ save regs
16560    mov     r0, rSELF
16561    mov     r1, rPC
16562    bl      dvmJitEndTraceSelect        @ (self,pc) end trace before this inst
16563    ldmfd   sp!, {r0-r2, lr}
16564    bx      lr                          @ return
16565#endif
16566
16567/*
16568 * After returning from a "glued" function, pull out the updated
16569 * values and start executing at the next instruction.
16570 */
16571common_resumeAfterGlueCall:
16572    LOAD_PC_FP_FROM_SELF()              @ pull rPC and rFP out of thread
16573    ldr     rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh
16574    FETCH_INST()                        @ load rINST from rPC
16575    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
16576    GOTO_OPCODE(ip)                     @ jump to next instruction
16577
16578/*
16579 * Invalid array index. Note that our calling convention is strange; we use r1
16580 * and r3 because those just happen to be the registers all our callers are
16581 * using. We move r3 before calling the C function, but r1 happens to match.
16582 * r1: index
16583 * r3: size
16584 */
16585common_errArrayIndex:
16586    EXPORT_PC()
16587    mov     r0, r3
16588    bl      dvmThrowArrayIndexOutOfBoundsException
16589    b       common_exceptionThrown
16590
16591/*
16592 * Integer divide or mod by zero.
16593 */
16594common_errDivideByZero:
16595    EXPORT_PC()
16596    ldr     r0, strDivideByZero
165970:  add     r0, pc
16598    bl      dvmThrowArithmeticException
16599    b       common_exceptionThrown
16600
16601strDivideByZero:
16602    .word   PCREL_REF(.LstrDivideByZero,0b)
16603
16604/*
16605 * Attempt to allocate an array with a negative size.
16606 * On entry: length in r1
16607 */
16608common_errNegativeArraySize:
16609    EXPORT_PC()
16610    mov     r0, r1                                @ arg0 <- len
16611    bl      dvmThrowNegativeArraySizeException    @ (len)
16612    b       common_exceptionThrown
16613
16614/*
16615 * Invocation of a non-existent method.
16616 * On entry: method name in r1
16617 */
16618common_errNoSuchMethod:
16619    EXPORT_PC()
16620    mov     r0, r1
16621    bl      dvmThrowNoSuchMethodError
16622    b       common_exceptionThrown
16623
16624/*
16625 * We encountered a null object when we weren't expecting one.  We
16626 * export the PC, throw a NullPointerException, and goto the exception
16627 * processing code.
16628 */
16629common_errNullObject:
16630    EXPORT_PC()
16631    mov     r0, #0
16632    bl      dvmThrowNullPointerException
16633    b       common_exceptionThrown
16634
16635/*
16636 * For debugging, cause an immediate fault.  The source address will
16637 * be in lr (use a bl instruction to jump here).
16638 */
16639common_abort:
16640    ldr     pc, .LdeadFood
16641.LdeadFood:
16642    .word   0xdeadf00d
16643
16644/*
16645 * Spit out a "we were here", preserving all registers.  (The attempt
16646 * to save ip won't work, but we need to save an even number of
16647 * registers for EABI 64-bit stack alignment.)
16648 */
16649    .macro  SQUEAK num
16650common_squeak\num:
16651    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
16652    ldr     r0, strSqueak\num
166530:  add     r0, pc
16654    mov     r1, #\num
16655    bl      printf
16656    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
16657    bx      lr
16658
16659strSqueak\num:
16660    .word   PCREL_REF(.LstrSqueak,0b)
16661    .endm
16662
16663    SQUEAK  0
16664    SQUEAK  1
16665    SQUEAK  2
16666    SQUEAK  3
16667    SQUEAK  4
16668    SQUEAK  5
16669
16670/*
16671 * Spit out the number in r0, preserving registers.
16672 */
16673common_printNum:
16674    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
16675    mov     r1, r0
16676    ldr     r0, strSqueak
166770:  add     r0, pc
16678    bl      printf
16679    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
16680    bx      lr
16681
16682strSqueak:
16683    .word   PCREL_REF(.LstrSqueak,0b)
16684
16685/*
16686 * Print a newline, preserving registers.
16687 */
16688common_printNewline:
16689    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
16690    ldr     r0, strNewline
166910:  add     r0, pc
16692    bl      printf
16693    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
16694    bx      lr
16695
16696strNewline:
16697    .word   PCREL_REF(.LstrNewline,0b)
16698
16699    /*
16700     * Print the 32-bit quantity in r0 as a hex value, preserving registers.
16701     */
16702common_printHex:
16703    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
16704    mov     r1, r0
16705    ldr     r0, strPrintHex
167060:  add     r0, pc
16707    bl      printf
16708    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
16709    bx      lr
16710
16711strPrintHex:
16712    .word   PCREL_REF(.LstrPrintHex,0b)
16713
16714/*
16715 * Print the 64-bit quantity in r0-r1, preserving registers.
16716 */
16717common_printLong:
16718    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
16719    mov     r3, r1
16720    mov     r2, r0
16721    ldr     r0, strPrintLong
167220:  add     r0, pc
16723    bl      printf
16724    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
16725    bx      lr
16726
16727strPrintLong:
16728    .word   PCREL_REF(.LstrPrintLong,0b)
16729
16730/*
16731 * Print full method info.  Pass the Method* in r0.  Preserves regs.
16732 */
16733common_printMethod:
16734    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
16735    bl      dvmMterpPrintMethod
16736    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
16737    bx      lr
16738
16739/*
16740 * Call a C helper function that dumps regs and possibly some
16741 * additional info.  Requires the C function to be compiled in.
16742 */
16743    .if     0
16744common_dumpRegs:
16745    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
16746    bl      dvmMterpDumpArmRegs
16747    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
16748    bx      lr
16749    .endif
16750
16751#if 0
16752/*
16753 * Experiment on VFP mode.
16754 *
16755 * uint32_t setFPSCR(uint32_t val, uint32_t mask)
16756 *
16757 * Updates the bits specified by "mask", setting them to the values in "val".
16758 */
16759setFPSCR:
16760    and     r0, r0, r1                  @ make sure no stray bits are set
16761    fmrx    r2, fpscr                   @ get VFP reg
16762    mvn     r1, r1                      @ bit-invert mask
16763    and     r2, r2, r1                  @ clear masked bits
16764    orr     r2, r2, r0                  @ set specified bits
16765    fmxr    fpscr, r2                   @ set VFP reg
16766    mov     r0, r2                      @ return new value
16767    bx      lr
16768
16769    .align  2
16770    .global dvmConfigureFP
16771    .type   dvmConfigureFP, %function
16772dvmConfigureFP:
16773    stmfd   sp!, {ip, lr}
16774    /* 0x03000000 sets DN/FZ */
16775    /* 0x00009f00 clears the six exception enable flags */
16776    bl      common_squeak0
16777    mov     r0, #0x03000000             @ r0<- 0x03000000
16778    add     r1, r0, #0x9f00             @ r1<- 0x03009f00
16779    bl      setFPSCR
16780    ldmfd   sp!, {ip, pc}
16781#endif
16782
16783
16784
16785/*
16786 * Zero-terminated ASCII string data.
16787 *
16788 * On ARM we have two choices: do like gcc does, and LDR from a .word
16789 * with the address, or use an ADR pseudo-op to get the address
16790 * directly.  ADR saves 4 bytes and an indirection, but it's using a
16791 * PC-relative addressing mode and hence has a limited range, which
16792 * makes it not work well with mergeable string sections.
16793 */
16794    .section .rodata.str1.4,"aMS",%progbits,1
16795
16796.LstrBadEntryPoint:
16797    .asciz  "Bad entry point %d\n"
16798.LstrFilledNewArrayNotImpl:
16799    .asciz  "filled-new-array only implemented for objects and 'int'"
16800.LstrDivideByZero:
16801    .asciz  "divide by zero"
16802.LstrLogTag:
16803    .asciz  "mterp"
16804.LstrExceptionNotCaughtLocally:
16805    .asciz  "Exception %s from %s:%d not caught locally\n"
16806
16807.LstrNewline:
16808    .asciz  "\n"
16809.LstrSqueak:
16810    .asciz  "<%d>"
16811.LstrPrintHex:
16812    .asciz  "<%#x>"
16813.LstrPrintLong:
16814    .asciz  "<%lld>"
16815
16816