1/*
2 * This file was generated automatically by gen-mterp.py for 'armv7-a'.
3 *
4 * --> DO NOT EDIT <--
5 */
6
7/* File: armv5te/header.S */
8/*
9 * Copyright (C) 2008 The Android Open Source Project
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 *      http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23
24/*
25 * ARMv5 definitions and declarations.
26 */
27
28/*
29ARM EABI general notes:
30
31r0-r3 hold first 4 args to a method; they are not preserved across method calls
32r4-r8 are available for general use
33r9 is given special treatment in some situations, but not for us
34r10 (sl) seems to be generally available
35r11 (fp) is used by gcc (unless -fomit-frame-pointer is set)
36r12 (ip) is scratch -- not preserved across method calls
37r13 (sp) should be managed carefully in case a signal arrives
38r14 (lr) must be preserved
39r15 (pc) can be tinkered with directly
40
41r0 holds returns of <= 4 bytes
42r0-r1 hold returns of 8 bytes, low word in r0
43
44Callee must save/restore r4+ (except r12) if it modifies them.  If VFP
45is present, registers s16-s31 (a/k/a d8-d15, a/k/a q4-q7) must be preserved,
46s0-s15 (d0-d7, q0-a3) do not need to be.
47
48Stack is "full descending".  Only the arguments that don't fit in the first 4
49registers are placed on the stack.  "sp" points at the first stacked argument
50(i.e. the 5th arg).
51
52VFP: single-precision results in s0, double-precision results in d0.
53
54In the EABI, "sp" must be 64-bit aligned on entry to a function, and any
5564-bit quantities (long long, double) must be 64-bit aligned.
56*/
57
58/*
59Mterp and ARM notes:
60
61The following registers have fixed assignments:
62
63  reg nick      purpose
64  r4  rPC       interpreted program counter, used for fetching instructions
65  r5  rFP       interpreted frame pointer, used for accessing locals and args
66  r6  rSELF     self (Thread) pointer
67  r7  rINST     first 16-bit code unit of current instruction
68  r8  rIBASE    interpreted instruction base pointer, used for computed goto
69
70Macros are provided for common operations.  Each macro MUST emit only
71one instruction to make instruction-counting easier.  They MUST NOT alter
72unspecified registers or condition codes.
73*/
74
75/* single-purpose registers, given names for clarity */
76#define rPC     r4
77#define rFP     r5
78#define rSELF   r6
79#define rINST   r7
80#define rIBASE  r8
81
82/* save/restore the PC and/or FP from the thread struct */
83#define LOAD_PC_FROM_SELF()     ldr     rPC, [rSELF, #offThread_pc]
84#define SAVE_PC_TO_SELF()       str     rPC, [rSELF, #offThread_pc]
85#define LOAD_FP_FROM_SELF()     ldr     rFP, [rSELF, #offThread_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
336    @ r1 holds value of entryPoint
337    bl      printf
338    bl      dvmAbort
339    .fnend
340    .size   dvmMterpStdRun, .-dvmMterpStdRun
341
342
343    .global dvmMterpStdBail
344    .type   dvmMterpStdBail, %function
345
346/*
347 * Restore the stack pointer and PC from the save point established on entry.
348 * This is essentially the same as a longjmp, but should be cheaper.  The
349 * last instruction causes us to return to whoever called dvmMterpStdRun.
350 *
351 * We pushed some registers on the stack in dvmMterpStdRun, then saved
352 * SP and LR.  Here we restore SP, restore the registers, and then restore
353 * LR to PC.
354 *
355 * On entry:
356 *  r0  Thread* self
357 */
358dvmMterpStdBail:
359    ldr     sp, [r0, #offThread_bailPtr]    @ sp<- saved SP
360    add     sp, sp, #4                      @ un-align 64
361    ldmfd   sp!, {r4-r10,fp,pc}             @ restore 9 regs and return
362
363
364/*
365 * String references.
366 */
367strBadEntryPoint:
368    .word   .LstrBadEntryPoint
369
370
371    .global dvmAsmInstructionStart
372    .type   dvmAsmInstructionStart, %function
373dvmAsmInstructionStart = .L_OP_NOP
374    .text
375
376/* ------------------------------ */
377    .balign 64
378.L_OP_NOP: /* 0x00 */
379/* File: armv5te/OP_NOP.S */
380    FETCH_ADVANCE_INST(1)               @ advance to next instr, load rINST
381    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
382    GOTO_OPCODE(ip)                     @ execute it
383
384#ifdef ASSIST_DEBUGGER
385    /* insert fake function header to help gdb find the stack frame */
386    .type   dalvik_inst, %function
387dalvik_inst:
388    .fnstart
389    MTERP_ENTRY1
390    MTERP_ENTRY2
391    .fnend
392#endif
393
394/* ------------------------------ */
395    .balign 64
396.L_OP_MOVE: /* 0x01 */
397/* File: armv6t2/OP_MOVE.S */
398    /* for move, move-object, long-to-int */
399    /* op vA, vB */
400    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
401    ubfx    r0, rINST, #8, #4           @ r0<- A from 11:8
402    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
403    GET_VREG(r2, r1)                    @ r2<- fp[B]
404    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
405    SET_VREG(r2, r0)                    @ fp[A]<- r2
406    GOTO_OPCODE(ip)                     @ execute next instruction
407
408/* ------------------------------ */
409    .balign 64
410.L_OP_MOVE_FROM16: /* 0x02 */
411/* File: armv5te/OP_MOVE_FROM16.S */
412    /* for: move/from16, move-object/from16 */
413    /* op vAA, vBBBB */
414    FETCH(r1, 1)                        @ r1<- BBBB
415    mov     r0, rINST, lsr #8           @ r0<- AA
416    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
417    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
418    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
419    SET_VREG(r2, r0)                    @ fp[AA]<- r2
420    GOTO_OPCODE(ip)                     @ jump to next instruction
421
422/* ------------------------------ */
423    .balign 64
424.L_OP_MOVE_16: /* 0x03 */
425/* File: armv5te/OP_MOVE_16.S */
426    /* for: move/16, move-object/16 */
427    /* op vAAAA, vBBBB */
428    FETCH(r1, 2)                        @ r1<- BBBB
429    FETCH(r0, 1)                        @ r0<- AAAA
430    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
431    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
432    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
433    SET_VREG(r2, r0)                    @ fp[AAAA]<- r2
434    GOTO_OPCODE(ip)                     @ jump to next instruction
435
436/* ------------------------------ */
437    .balign 64
438.L_OP_MOVE_WIDE: /* 0x04 */
439/* File: armv6t2/OP_MOVE_WIDE.S */
440    /* move-wide vA, vB */
441    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
442    mov     r3, rINST, lsr #12          @ r3<- B
443    ubfx    r2, rINST, #8, #4           @ r2<- A
444    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
445    add     r2, rFP, r2, lsl #2         @ r2<- &fp[A]
446    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[B]
447    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
448    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
449    stmia   r2, {r0-r1}                 @ fp[A]<- r0/r1
450    GOTO_OPCODE(ip)                     @ jump to next instruction
451
452/* ------------------------------ */
453    .balign 64
454.L_OP_MOVE_WIDE_FROM16: /* 0x05 */
455/* File: armv5te/OP_MOVE_WIDE_FROM16.S */
456    /* move-wide/from16 vAA, vBBBB */
457    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
458    FETCH(r3, 1)                        @ r3<- BBBB
459    mov     r2, rINST, lsr #8           @ r2<- AA
460    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BBBB]
461    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
462    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[BBBB]
463    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
464    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
465    stmia   r2, {r0-r1}                 @ fp[AA]<- r0/r1
466    GOTO_OPCODE(ip)                     @ jump to next instruction
467
468/* ------------------------------ */
469    .balign 64
470.L_OP_MOVE_WIDE_16: /* 0x06 */
471/* File: armv5te/OP_MOVE_WIDE_16.S */
472    /* move-wide/16 vAAAA, vBBBB */
473    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
474    FETCH(r3, 2)                        @ r3<- BBBB
475    FETCH(r2, 1)                        @ r2<- AAAA
476    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BBBB]
477    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AAAA]
478    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[BBBB]
479    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
480    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
481    stmia   r2, {r0-r1}                 @ fp[AAAA]<- r0/r1
482    GOTO_OPCODE(ip)                     @ jump to next instruction
483
484/* ------------------------------ */
485    .balign 64
486.L_OP_MOVE_OBJECT: /* 0x07 */
487/* File: armv5te/OP_MOVE_OBJECT.S */
488/* File: armv5te/OP_MOVE.S */
489    /* for move, move-object, long-to-int */
490    /* op vA, vB */
491    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
492    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
493    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
494    GET_VREG(r2, r1)                    @ r2<- fp[B]
495    and     r0, r0, #15
496    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
497    SET_VREG(r2, r0)                    @ fp[A]<- r2
498    GOTO_OPCODE(ip)                     @ execute next instruction
499
500
501/* ------------------------------ */
502    .balign 64
503.L_OP_MOVE_OBJECT_FROM16: /* 0x08 */
504/* File: armv5te/OP_MOVE_OBJECT_FROM16.S */
505/* File: armv5te/OP_MOVE_FROM16.S */
506    /* for: move/from16, move-object/from16 */
507    /* op vAA, vBBBB */
508    FETCH(r1, 1)                        @ r1<- BBBB
509    mov     r0, rINST, lsr #8           @ r0<- AA
510    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
511    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
512    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
513    SET_VREG(r2, r0)                    @ fp[AA]<- r2
514    GOTO_OPCODE(ip)                     @ jump to next instruction
515
516
517/* ------------------------------ */
518    .balign 64
519.L_OP_MOVE_OBJECT_16: /* 0x09 */
520/* File: armv5te/OP_MOVE_OBJECT_16.S */
521/* File: armv5te/OP_MOVE_16.S */
522    /* for: move/16, move-object/16 */
523    /* op vAAAA, vBBBB */
524    FETCH(r1, 2)                        @ r1<- BBBB
525    FETCH(r0, 1)                        @ r0<- AAAA
526    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
527    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
528    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
529    SET_VREG(r2, r0)                    @ fp[AAAA]<- r2
530    GOTO_OPCODE(ip)                     @ jump to next instruction
531
532
533/* ------------------------------ */
534    .balign 64
535.L_OP_MOVE_RESULT: /* 0x0a */
536/* File: armv5te/OP_MOVE_RESULT.S */
537    /* for: move-result, move-result-object */
538    /* op vAA */
539    mov     r2, rINST, lsr #8           @ r2<- AA
540    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
541    ldr     r0, [rSELF, #offThread_retval]    @ r0<- self->retval.i
542    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
543    SET_VREG(r0, r2)                    @ fp[AA]<- r0
544    GOTO_OPCODE(ip)                     @ jump to next instruction
545
546/* ------------------------------ */
547    .balign 64
548.L_OP_MOVE_RESULT_WIDE: /* 0x0b */
549/* File: armv5te/OP_MOVE_RESULT_WIDE.S */
550    /* move-result-wide vAA */
551    mov     r2, rINST, lsr #8           @ r2<- AA
552    add     r3, rSELF, #offThread_retval  @ r3<- &self->retval
553    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
554    ldmia   r3, {r0-r1}                 @ r0/r1<- retval.j
555    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
556    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
557    stmia   r2, {r0-r1}                 @ fp[AA]<- r0/r1
558    GOTO_OPCODE(ip)                     @ jump to next instruction
559
560/* ------------------------------ */
561    .balign 64
562.L_OP_MOVE_RESULT_OBJECT: /* 0x0c */
563/* File: armv5te/OP_MOVE_RESULT_OBJECT.S */
564/* File: armv5te/OP_MOVE_RESULT.S */
565    /* for: move-result, move-result-object */
566    /* op vAA */
567    mov     r2, rINST, lsr #8           @ r2<- AA
568    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
569    ldr     r0, [rSELF, #offThread_retval]    @ r0<- self->retval.i
570    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
571    SET_VREG(r0, r2)                    @ fp[AA]<- r0
572    GOTO_OPCODE(ip)                     @ jump to next instruction
573
574
575/* ------------------------------ */
576    .balign 64
577.L_OP_MOVE_EXCEPTION: /* 0x0d */
578/* File: armv5te/OP_MOVE_EXCEPTION.S */
579    /* move-exception vAA */
580    mov     r2, rINST, lsr #8           @ r2<- AA
581    ldr     r3, [rSELF, #offThread_exception]  @ r3<- dvmGetException bypass
582    mov     r1, #0                      @ r1<- 0
583    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
584    SET_VREG(r3, r2)                    @ fp[AA]<- exception obj
585    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
586    str     r1, [rSELF, #offThread_exception]  @ dvmClearException bypass
587    GOTO_OPCODE(ip)                     @ jump to next instruction
588
589/* ------------------------------ */
590    .balign 64
591.L_OP_RETURN_VOID: /* 0x0e */
592/* File: armv5te/OP_RETURN_VOID.S */
593    b       common_returnFromMethod
594
595/* ------------------------------ */
596    .balign 64
597.L_OP_RETURN: /* 0x0f */
598/* File: armv5te/OP_RETURN.S */
599    /*
600     * Return a 32-bit value.  Copies the return value into the "thread"
601     * structure, then jumps to the return handler.
602     *
603     * for: return, return-object
604     */
605    /* op vAA */
606    mov     r2, rINST, lsr #8           @ r2<- AA
607    GET_VREG(r0, r2)                    @ r0<- vAA
608    str     r0, [rSELF, #offThread_retval] @ retval.i <- vAA
609    b       common_returnFromMethod
610
611/* ------------------------------ */
612    .balign 64
613.L_OP_RETURN_WIDE: /* 0x10 */
614/* File: armv5te/OP_RETURN_WIDE.S */
615    /*
616     * Return a 64-bit value.  Copies the return value into the "thread"
617     * structure, then jumps to the return handler.
618     */
619    /* return-wide vAA */
620    mov     r2, rINST, lsr #8           @ r2<- AA
621    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
622    add     r3, rSELF, #offThread_retval  @ r3<- &self->retval
623    ldmia   r2, {r0-r1}                 @ r0/r1 <- vAA/vAA+1
624    stmia   r3, {r0-r1}                 @ retval<- r0/r1
625    b       common_returnFromMethod
626
627/* ------------------------------ */
628    .balign 64
629.L_OP_RETURN_OBJECT: /* 0x11 */
630/* File: armv5te/OP_RETURN_OBJECT.S */
631/* File: armv5te/OP_RETURN.S */
632    /*
633     * Return a 32-bit value.  Copies the return value into the "thread"
634     * structure, then jumps to the return handler.
635     *
636     * for: return, return-object
637     */
638    /* op vAA */
639    mov     r2, rINST, lsr #8           @ r2<- AA
640    GET_VREG(r0, r2)                    @ r0<- vAA
641    str     r0, [rSELF, #offThread_retval] @ retval.i <- vAA
642    b       common_returnFromMethod
643
644
645/* ------------------------------ */
646    .balign 64
647.L_OP_CONST_4: /* 0x12 */
648/* File: armv6t2/OP_CONST_4.S */
649    /* const/4 vA, #+B */
650    mov     r1, rINST, lsl #16          @ r1<- Bxxx0000
651    ubfx    r0, rINST, #8, #4           @ r0<- A
652    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
653    mov     r1, r1, asr #28             @ r1<- sssssssB (sign-extended)
654    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
655    SET_VREG(r1, r0)                    @ fp[A]<- r1
656    GOTO_OPCODE(ip)                     @ execute next instruction
657
658/* ------------------------------ */
659    .balign 64
660.L_OP_CONST_16: /* 0x13 */
661/* File: armv5te/OP_CONST_16.S */
662    /* const/16 vAA, #+BBBB */
663    FETCH_S(r0, 1)                      @ r0<- ssssBBBB (sign-extended)
664    mov     r3, rINST, lsr #8           @ r3<- AA
665    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
666    SET_VREG(r0, r3)                    @ vAA<- r0
667    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
668    GOTO_OPCODE(ip)                     @ jump to next instruction
669
670/* ------------------------------ */
671    .balign 64
672.L_OP_CONST: /* 0x14 */
673/* File: armv5te/OP_CONST.S */
674    /* const vAA, #+BBBBbbbb */
675    mov     r3, rINST, lsr #8           @ r3<- AA
676    FETCH(r0, 1)                        @ r0<- bbbb (low)
677    FETCH(r1, 2)                        @ r1<- BBBB (high)
678    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
679    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
680    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
681    SET_VREG(r0, r3)                    @ vAA<- r0
682    GOTO_OPCODE(ip)                     @ jump to next instruction
683
684/* ------------------------------ */
685    .balign 64
686.L_OP_CONST_HIGH16: /* 0x15 */
687/* File: armv5te/OP_CONST_HIGH16.S */
688    /* const/high16 vAA, #+BBBB0000 */
689    FETCH(r0, 1)                        @ r0<- 0000BBBB (zero-extended)
690    mov     r3, rINST, lsr #8           @ r3<- AA
691    mov     r0, r0, lsl #16             @ r0<- BBBB0000
692    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
693    SET_VREG(r0, r3)                    @ vAA<- r0
694    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
695    GOTO_OPCODE(ip)                     @ jump to next instruction
696
697/* ------------------------------ */
698    .balign 64
699.L_OP_CONST_WIDE_16: /* 0x16 */
700/* File: armv5te/OP_CONST_WIDE_16.S */
701    /* const-wide/16 vAA, #+BBBB */
702    FETCH_S(r0, 1)                      @ r0<- ssssBBBB (sign-extended)
703    mov     r3, rINST, lsr #8           @ r3<- AA
704    mov     r1, r0, asr #31             @ r1<- ssssssss
705    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
706    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
707    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
708    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
709    GOTO_OPCODE(ip)                     @ jump to next instruction
710
711/* ------------------------------ */
712    .balign 64
713.L_OP_CONST_WIDE_32: /* 0x17 */
714/* File: armv5te/OP_CONST_WIDE_32.S */
715    /* const-wide/32 vAA, #+BBBBbbbb */
716    FETCH(r0, 1)                        @ r0<- 0000bbbb (low)
717    mov     r3, rINST, lsr #8           @ r3<- AA
718    FETCH_S(r2, 2)                      @ r2<- ssssBBBB (high)
719    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
720    orr     r0, r0, r2, lsl #16         @ r0<- BBBBbbbb
721    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
722    mov     r1, r0, asr #31             @ r1<- ssssssss
723    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
724    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
725    GOTO_OPCODE(ip)                     @ jump to next instruction
726
727/* ------------------------------ */
728    .balign 64
729.L_OP_CONST_WIDE: /* 0x18 */
730/* File: armv5te/OP_CONST_WIDE.S */
731    /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
732    FETCH(r0, 1)                        @ r0<- bbbb (low)
733    FETCH(r1, 2)                        @ r1<- BBBB (low middle)
734    FETCH(r2, 3)                        @ r2<- hhhh (high middle)
735    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb (low word)
736    FETCH(r3, 4)                        @ r3<- HHHH (high)
737    mov     r9, rINST, lsr #8           @ r9<- AA
738    orr     r1, r2, r3, lsl #16         @ r1<- HHHHhhhh (high word)
739    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
740    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
741    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
742    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
743    GOTO_OPCODE(ip)                     @ jump to next instruction
744
745/* ------------------------------ */
746    .balign 64
747.L_OP_CONST_WIDE_HIGH16: /* 0x19 */
748/* File: armv5te/OP_CONST_WIDE_HIGH16.S */
749    /* const-wide/high16 vAA, #+BBBB000000000000 */
750    FETCH(r1, 1)                        @ r1<- 0000BBBB (zero-extended)
751    mov     r3, rINST, lsr #8           @ r3<- AA
752    mov     r0, #0                      @ r0<- 00000000
753    mov     r1, r1, lsl #16             @ r1<- BBBB0000
754    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
755    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
756    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
757    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
758    GOTO_OPCODE(ip)                     @ jump to next instruction
759
760/* ------------------------------ */
761    .balign 64
762.L_OP_CONST_STRING: /* 0x1a */
763/* File: armv5te/OP_CONST_STRING.S */
764    /* const/string vAA, String@BBBB */
765    FETCH(r1, 1)                        @ r1<- BBBB
766    ldr     r2, [rSELF, #offThread_methodClassDex]  @ r2<- self->methodClassDex
767    mov     r9, rINST, lsr #8           @ r9<- AA
768    ldr     r2, [r2, #offDvmDex_pResStrings]   @ r2<- dvmDex->pResStrings
769    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResStrings[BBBB]
770    cmp     r0, #0                      @ not yet resolved?
771    beq     .LOP_CONST_STRING_resolve
772    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
773    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
774    SET_VREG(r0, r9)                    @ vAA<- r0
775    GOTO_OPCODE(ip)                     @ jump to next instruction
776
777/* ------------------------------ */
778    .balign 64
779.L_OP_CONST_STRING_JUMBO: /* 0x1b */
780/* File: armv5te/OP_CONST_STRING_JUMBO.S */
781    /* const/string vAA, String@BBBBBBBB */
782    FETCH(r0, 1)                        @ r0<- bbbb (low)
783    FETCH(r1, 2)                        @ r1<- BBBB (high)
784    ldr     r2, [rSELF, #offThread_methodClassDex]  @ r2<- self->methodClassDex
785    mov     r9, rINST, lsr #8           @ r9<- AA
786    ldr     r2, [r2, #offDvmDex_pResStrings]   @ r2<- dvmDex->pResStrings
787    orr     r1, r0, r1, lsl #16         @ r1<- BBBBbbbb
788    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResStrings[BBBB]
789    cmp     r0, #0
790    beq     .LOP_CONST_STRING_JUMBO_resolve
791    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
792    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
793    SET_VREG(r0, r9)                    @ vAA<- r0
794    GOTO_OPCODE(ip)                     @ jump to next instruction
795
796/* ------------------------------ */
797    .balign 64
798.L_OP_CONST_CLASS: /* 0x1c */
799/* File: armv5te/OP_CONST_CLASS.S */
800    /* const/class vAA, Class@BBBB */
801    FETCH(r1, 1)                        @ r1<- BBBB
802    ldr     r2, [rSELF, #offThread_methodClassDex]  @ r2<- self->methodClassDex
803    mov     r9, rINST, lsr #8           @ r9<- AA
804    ldr     r2, [r2, #offDvmDex_pResClasses]   @ r2<- dvmDex->pResClasses
805    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResClasses[BBBB]
806    cmp     r0, #0                      @ not yet resolved?
807    beq     .LOP_CONST_CLASS_resolve
808    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
809    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
810    SET_VREG(r0, r9)                    @ vAA<- r0
811    GOTO_OPCODE(ip)                     @ jump to next instruction
812
813/* ------------------------------ */
814    .balign 64
815.L_OP_MONITOR_ENTER: /* 0x1d */
816/* File: armv5te/OP_MONITOR_ENTER.S */
817    /*
818     * Synchronize on an object.
819     */
820    /* monitor-enter vAA */
821    mov     r2, rINST, lsr #8           @ r2<- AA
822    GET_VREG(r1, r2)                    @ r1<- vAA (object)
823    mov     r0, rSELF                   @ r0<- self
824    cmp     r1, #0                      @ null object?
825    EXPORT_PC()                         @ need for precise GC
826    beq     common_errNullObject        @ null object, throw an exception
827    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
828    bl      dvmLockObject               @ call(self, obj)
829    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
830    GOTO_OPCODE(ip)                     @ jump to next instruction
831
832/* ------------------------------ */
833    .balign 64
834.L_OP_MONITOR_EXIT: /* 0x1e */
835/* File: armv5te/OP_MONITOR_EXIT.S */
836    /*
837     * Unlock an object.
838     *
839     * Exceptions that occur when unlocking a monitor need to appear as
840     * if they happened at the following instruction.  See the Dalvik
841     * instruction spec.
842     */
843    /* monitor-exit vAA */
844    mov     r2, rINST, lsr #8           @ r2<- AA
845    EXPORT_PC()                         @ before fetch: export the PC
846    GET_VREG(r1, r2)                    @ r1<- vAA (object)
847    cmp     r1, #0                      @ null object?
848    beq     1f                          @ yes
849    mov     r0, rSELF                   @ r0<- self
850    bl      dvmUnlockObject             @ r0<- success for unlock(self, obj)
851    cmp     r0, #0                      @ failed?
852    FETCH_ADVANCE_INST(1)               @ before throw: advance rPC, load rINST
853    beq     common_exceptionThrown      @ yes, exception is pending
854    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
855    GOTO_OPCODE(ip)                     @ jump to next instruction
8561:
857    FETCH_ADVANCE_INST(1)               @ advance before throw
858    b      common_errNullObject
859
860/* ------------------------------ */
861    .balign 64
862.L_OP_CHECK_CAST: /* 0x1f */
863/* File: armv5te/OP_CHECK_CAST.S */
864    /*
865     * Check to see if a cast from one class to another is allowed.
866     */
867    /* check-cast vAA, class@BBBB */
868    mov     r3, rINST, lsr #8           @ r3<- AA
869    FETCH(r2, 1)                        @ r2<- BBBB
870    GET_VREG(r9, r3)                    @ r9<- object
871    ldr     r0, [rSELF, #offThread_methodClassDex]    @ r0<- pDvmDex
872    cmp     r9, #0                      @ is object null?
873    ldr     r0, [r0, #offDvmDex_pResClasses]    @ r0<- pDvmDex->pResClasses
874    beq     .LOP_CHECK_CAST_okay            @ null obj, cast always succeeds
875    ldr     r1, [r0, r2, lsl #2]        @ r1<- resolved class
876    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
877    cmp     r1, #0                      @ have we resolved this before?
878    beq     .LOP_CHECK_CAST_resolve         @ not resolved, do it now
879.LOP_CHECK_CAST_resolved:
880    cmp     r0, r1                      @ same class (trivial success)?
881    bne     .LOP_CHECK_CAST_fullcheck       @ no, do full check
882.LOP_CHECK_CAST_okay:
883    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
884    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
885    GOTO_OPCODE(ip)                     @ jump to next instruction
886
887/* ------------------------------ */
888    .balign 64
889.L_OP_INSTANCE_OF: /* 0x20 */
890/* File: armv5te/OP_INSTANCE_OF.S */
891    /*
892     * Check to see if an object reference is an instance of a class.
893     *
894     * Most common situation is a non-null object, being compared against
895     * an already-resolved class.
896     */
897    /* instance-of vA, vB, class@CCCC */
898    mov     r3, rINST, lsr #12          @ r3<- B
899    mov     r9, rINST, lsr #8           @ r9<- A+
900    GET_VREG(r0, r3)                    @ r0<- vB (object)
901    and     r9, r9, #15                 @ r9<- A
902    cmp     r0, #0                      @ is object null?
903    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- pDvmDex
904    beq     .LOP_INSTANCE_OF_store           @ null obj, not an instance, store r0
905    FETCH(r3, 1)                        @ r3<- CCCC
906    ldr     r2, [r2, #offDvmDex_pResClasses]    @ r2<- pDvmDex->pResClasses
907    ldr     r1, [r2, r3, lsl #2]        @ r1<- resolved class
908    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
909    cmp     r1, #0                      @ have we resolved this before?
910    beq     .LOP_INSTANCE_OF_resolve         @ not resolved, do it now
911.LOP_INSTANCE_OF_resolved: @ r0=obj->clazz, r1=resolved class
912    cmp     r0, r1                      @ same class (trivial success)?
913    beq     .LOP_INSTANCE_OF_trivial         @ yes, trivial finish
914    b       .LOP_INSTANCE_OF_fullcheck       @ no, do full check
915
916/* ------------------------------ */
917    .balign 64
918.L_OP_ARRAY_LENGTH: /* 0x21 */
919/* File: armv6t2/OP_ARRAY_LENGTH.S */
920    /*
921     * Return the length of an array.
922     */
923    mov     r1, rINST, lsr #12          @ r1<- B
924    ubfx    r2, rINST, #8, #4           @ r2<- A
925    GET_VREG(r0, r1)                    @ r0<- vB (object ref)
926    cmp     r0, #0                      @ is object null?
927    beq     common_errNullObject        @ yup, fail
928    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
929    ldr     r3, [r0, #offArrayObject_length]    @ r3<- array length
930    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
931    SET_VREG(r3, r2)                    @ vB<- length
932    GOTO_OPCODE(ip)                     @ jump to next instruction
933
934/* ------------------------------ */
935    .balign 64
936.L_OP_NEW_INSTANCE: /* 0x22 */
937/* File: armv5te/OP_NEW_INSTANCE.S */
938    /*
939     * Create a new instance of a class.
940     */
941    /* new-instance vAA, class@BBBB */
942    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
943    FETCH(r1, 1)                        @ r1<- BBBB
944    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
945    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
946#if defined(WITH_JIT)
947    add     r10, r3, r1, lsl #2         @ r10<- &resolved_class
948#endif
949    EXPORT_PC()                         @ req'd for init, resolve, alloc
950    cmp     r0, #0                      @ already resolved?
951    beq     .LOP_NEW_INSTANCE_resolve         @ no, resolve it now
952.LOP_NEW_INSTANCE_resolved:   @ r0=class
953    ldrb    r1, [r0, #offClassObject_status]    @ r1<- ClassStatus enum
954    cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
955    bne     .LOP_NEW_INSTANCE_needinit        @ no, init class now
956.LOP_NEW_INSTANCE_initialized: @ r0=class
957    mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
958    bl      dvmAllocObject              @ r0<- new object
959    b       .LOP_NEW_INSTANCE_finish          @ continue
960
961/* ------------------------------ */
962    .balign 64
963.L_OP_NEW_ARRAY: /* 0x23 */
964/* File: armv5te/OP_NEW_ARRAY.S */
965    /*
966     * Allocate an array of objects, specified with the array class
967     * and a count.
968     *
969     * The verifier guarantees that this is an array class, so we don't
970     * check for it here.
971     */
972    /* new-array vA, vB, class@CCCC */
973    mov     r0, rINST, lsr #12          @ r0<- B
974    FETCH(r2, 1)                        @ r2<- CCCC
975    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
976    GET_VREG(r1, r0)                    @ r1<- vB (array length)
977    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
978    cmp     r1, #0                      @ check length
979    ldr     r0, [r3, r2, lsl #2]        @ r0<- resolved class
980    bmi     common_errNegativeArraySize @ negative length, bail - len in r1
981    cmp     r0, #0                      @ already resolved?
982    EXPORT_PC()                         @ req'd for resolve, alloc
983    bne     .LOP_NEW_ARRAY_finish          @ resolved, continue
984    b       .LOP_NEW_ARRAY_resolve         @ do resolve now
985
986/* ------------------------------ */
987    .balign 64
988.L_OP_FILLED_NEW_ARRAY: /* 0x24 */
989/* File: armv5te/OP_FILLED_NEW_ARRAY.S */
990    /*
991     * Create a new array with elements filled from registers.
992     *
993     * for: filled-new-array, filled-new-array/range
994     */
995    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
996    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
997    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
998    FETCH(r1, 1)                        @ r1<- BBBB
999    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1000    EXPORT_PC()                         @ need for resolve and alloc
1001    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
1002    mov     r10, rINST, lsr #8          @ r10<- AA or BA
1003    cmp     r0, #0                      @ already resolved?
1004    bne     .LOP_FILLED_NEW_ARRAY_continue        @ yes, continue on
10058:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
1006    mov     r2, #0                      @ r2<- false
1007    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
1008    bl      dvmResolveClass             @ r0<- call(clazz, ref)
1009    cmp     r0, #0                      @ got null?
1010    beq     common_exceptionThrown      @ yes, handle exception
1011    b       .LOP_FILLED_NEW_ARRAY_continue
1012
1013/* ------------------------------ */
1014    .balign 64
1015.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
1016/* File: armv5te/OP_FILLED_NEW_ARRAY_RANGE.S */
1017/* File: armv5te/OP_FILLED_NEW_ARRAY.S */
1018    /*
1019     * Create a new array with elements filled from registers.
1020     *
1021     * for: filled-new-array, filled-new-array/range
1022     */
1023    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1024    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1025    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
1026    FETCH(r1, 1)                        @ r1<- BBBB
1027    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1028    EXPORT_PC()                         @ need for resolve and alloc
1029    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
1030    mov     r10, rINST, lsr #8          @ r10<- AA or BA
1031    cmp     r0, #0                      @ already resolved?
1032    bne     .LOP_FILLED_NEW_ARRAY_RANGE_continue        @ yes, continue on
10338:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
1034    mov     r2, #0                      @ r2<- false
1035    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
1036    bl      dvmResolveClass             @ r0<- call(clazz, ref)
1037    cmp     r0, #0                      @ got null?
1038    beq     common_exceptionThrown      @ yes, handle exception
1039    b       .LOP_FILLED_NEW_ARRAY_RANGE_continue
1040
1041
1042/* ------------------------------ */
1043    .balign 64
1044.L_OP_FILL_ARRAY_DATA: /* 0x26 */
1045/* File: armv5te/OP_FILL_ARRAY_DATA.S */
1046    /* fill-array-data vAA, +BBBBBBBB */
1047    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1048    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1049    mov     r3, rINST, lsr #8           @ r3<- AA
1050    orr     r1, r0, r1, lsl #16         @ r1<- BBBBbbbb
1051    GET_VREG(r0, r3)                    @ r0<- vAA (array object)
1052    add     r1, rPC, r1, lsl #1         @ r1<- PC + BBBBbbbb*2 (array data off.)
1053    EXPORT_PC();
1054    bl      dvmInterpHandleFillArrayData@ fill the array with predefined data
1055    cmp     r0, #0                      @ 0 means an exception is thrown
1056    beq     common_exceptionThrown      @ has exception
1057    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
1058    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1059    GOTO_OPCODE(ip)                     @ jump to next instruction
1060
1061/* ------------------------------ */
1062    .balign 64
1063.L_OP_THROW: /* 0x27 */
1064/* File: armv5te/OP_THROW.S */
1065    /*
1066     * Throw an exception object in the current thread.
1067     */
1068    /* throw vAA */
1069    mov     r2, rINST, lsr #8           @ r2<- AA
1070    GET_VREG(r1, r2)                    @ r1<- vAA (exception object)
1071    EXPORT_PC()                         @ exception handler can throw
1072    cmp     r1, #0                      @ null object?
1073    beq     common_errNullObject        @ yes, throw an NPE instead
1074    @ bypass dvmSetException, just store it
1075    str     r1, [rSELF, #offThread_exception]  @ thread->exception<- obj
1076    b       common_exceptionThrown
1077
1078/* ------------------------------ */
1079    .balign 64
1080.L_OP_GOTO: /* 0x28 */
1081/* File: armv5te/OP_GOTO.S */
1082    /*
1083     * Unconditional branch, 8-bit offset.
1084     *
1085     * The branch distance is a signed code-unit offset, which we need to
1086     * double to get a byte offset.
1087     */
1088    /* goto +AA */
1089    /* tuning: use sbfx for 6t2+ targets */
1090    mov     r0, rINST, lsl #16          @ r0<- AAxx0000
1091    movs    r1, r0, asr #24             @ r1<- ssssssAA (sign-extended)
1092    add     r2, r1, r1                  @ r2<- byte offset, set flags
1093       @ If backwards branch refresh rIBASE
1094    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1095    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1096#if defined(WITH_JIT)
1097    ldr     r0, [rSELF, #offThread_pJitProfTable]
1098    bmi     common_testUpdateProfile    @ (r0) check for trace hotness
1099#endif
1100    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1101    GOTO_OPCODE(ip)                     @ jump to next instruction
1102
1103/* ------------------------------ */
1104    .balign 64
1105.L_OP_GOTO_16: /* 0x29 */
1106/* File: armv5te/OP_GOTO_16.S */
1107    /*
1108     * Unconditional branch, 16-bit offset.
1109     *
1110     * The branch distance is a signed code-unit offset, which we need to
1111     * double to get a byte offset.
1112     */
1113    /* goto/16 +AAAA */
1114    FETCH_S(r0, 1)                      @ r0<- ssssAAAA (sign-extended)
1115    adds    r1, r0, r0                  @ r1<- byte offset, flags set
1116    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1117    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1118#if defined(WITH_JIT)
1119    ldr     r0, [rSELF, #offThread_pJitProfTable]
1120    bmi     common_testUpdateProfile    @ (r0) hot trace head?
1121#endif
1122    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1123    GOTO_OPCODE(ip)                     @ jump to next instruction
1124
1125/* ------------------------------ */
1126    .balign 64
1127.L_OP_GOTO_32: /* 0x2a */
1128/* File: armv5te/OP_GOTO_32.S */
1129    /*
1130     * Unconditional branch, 32-bit offset.
1131     *
1132     * The branch distance is a signed code-unit offset, which we need to
1133     * double to get a byte offset.
1134     *
1135     * Unlike most opcodes, this one is allowed to branch to itself, so
1136     * our "backward branch" test must be "<=0" instead of "<0".  Because
1137     * we need the V bit set, we'll use an adds to convert from Dalvik
1138     * offset to byte offset.
1139     */
1140    /* goto/32 +AAAAAAAA */
1141    FETCH(r0, 1)                        @ r0<- aaaa (lo)
1142    FETCH(r1, 2)                        @ r1<- AAAA (hi)
1143    orr     r0, r0, r1, lsl #16         @ r0<- AAAAaaaa
1144    adds    r1, r0, r0                  @ r1<- byte offset
1145#if defined(WITH_JIT)
1146    ldr     r0, [rSELF, #offThread_pJitProfTable]
1147    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1148    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1149    ble     common_testUpdateProfile    @ (r0) hot trace head?
1150#else
1151    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1152    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1153#endif
1154    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1155    GOTO_OPCODE(ip)                     @ jump to next instruction
1156
1157/* ------------------------------ */
1158    .balign 64
1159.L_OP_PACKED_SWITCH: /* 0x2b */
1160/* File: armv5te/OP_PACKED_SWITCH.S */
1161    /*
1162     * Handle a packed-switch or sparse-switch instruction.  In both cases
1163     * we decode it and hand it off to a helper function.
1164     *
1165     * We don't really expect backward branches in a switch statement, but
1166     * they're perfectly legal, so we check for them here.
1167     *
1168     * When the JIT is present, all targets are considered treated as
1169     * a potential trace heads regardless of branch direction.
1170     *
1171     * for: packed-switch, sparse-switch
1172     */
1173    /* op vAA, +BBBB */
1174    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1175    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1176    mov     r3, rINST, lsr #8           @ r3<- AA
1177    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
1178    GET_VREG(r1, r3)                    @ r1<- vAA
1179    add     r0, rPC, r0, lsl #1         @ r0<- PC + BBBBbbbb*2
1180    bl      dvmInterpHandlePackedSwitch                       @ r0<- code-unit branch offset
1181    adds    r1, r0, r0                  @ r1<- byte offset; clear V
1182#if defined(WITH_JIT)
1183    ldr     r0, [rSELF, #offThread_pJitProfTable]
1184    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1185    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1186    cmp     r0, #0
1187    bne     common_updateProfile
1188#else
1189    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1190    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1191#endif
1192    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1193    GOTO_OPCODE(ip)                     @ jump to next instruction
1194
1195/* ------------------------------ */
1196    .balign 64
1197.L_OP_SPARSE_SWITCH: /* 0x2c */
1198/* File: armv5te/OP_SPARSE_SWITCH.S */
1199/* File: armv5te/OP_PACKED_SWITCH.S */
1200    /*
1201     * Handle a packed-switch or sparse-switch instruction.  In both cases
1202     * we decode it and hand it off to a helper function.
1203     *
1204     * We don't really expect backward branches in a switch statement, but
1205     * they're perfectly legal, so we check for them here.
1206     *
1207     * When the JIT is present, all targets are considered treated as
1208     * a potential trace heads regardless of branch direction.
1209     *
1210     * for: packed-switch, sparse-switch
1211     */
1212    /* op vAA, +BBBB */
1213    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1214    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1215    mov     r3, rINST, lsr #8           @ r3<- AA
1216    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
1217    GET_VREG(r1, r3)                    @ r1<- vAA
1218    add     r0, rPC, r0, lsl #1         @ r0<- PC + BBBBbbbb*2
1219    bl      dvmInterpHandleSparseSwitch                       @ r0<- code-unit branch offset
1220    adds    r1, r0, r0                  @ r1<- byte offset; clear V
1221#if defined(WITH_JIT)
1222    ldr     r0, [rSELF, #offThread_pJitProfTable]
1223    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1224    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1225    cmp     r0, #0
1226    bne     common_updateProfile
1227#else
1228    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1229    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1230#endif
1231    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1232    GOTO_OPCODE(ip)                     @ jump to next instruction
1233
1234
1235/* ------------------------------ */
1236    .balign 64
1237.L_OP_CMPL_FLOAT: /* 0x2d */
1238/* File: arm-vfp/OP_CMPL_FLOAT.S */
1239    /*
1240     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1241     * destination register based on the results of the comparison.
1242     *
1243     * int compare(x, y) {
1244     *     if (x == y) {
1245     *         return 0;
1246     *     } else if (x > y) {
1247     *         return 1;
1248     *     } else if (x < y) {
1249     *         return -1;
1250     *     } else {
1251     *         return -1;
1252     *     }
1253     * }
1254     */
1255    /* op vAA, vBB, vCC */
1256    FETCH(r0, 1)                        @ r0<- CCBB
1257    mov     r9, rINST, lsr #8           @ r9<- AA
1258    and     r2, r0, #255                @ r2<- BB
1259    mov     r3, r0, lsr #8              @ r3<- CC
1260    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1261    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1262    flds    s0, [r2]                    @ s0<- vBB
1263    flds    s1, [r3]                    @ s1<- vCC
1264    fcmpes  s0, s1                      @ compare (vBB, vCC)
1265    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1266    mvn     r0, #0                      @ r0<- -1 (default)
1267    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1268    fmstat                              @ export status flags
1269    movgt   r0, #1                      @ (greater than) r1<- 1
1270    moveq   r0, #0                      @ (equal) r1<- 0
1271    b       .LOP_CMPL_FLOAT_finish          @ argh
1272
1273
1274/* ------------------------------ */
1275    .balign 64
1276.L_OP_CMPG_FLOAT: /* 0x2e */
1277/* File: arm-vfp/OP_CMPG_FLOAT.S */
1278    /*
1279     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1280     * destination register based on the results of the comparison.
1281     *
1282     * int compare(x, y) {
1283     *     if (x == y) {
1284     *         return 0;
1285     *     } else if (x < y) {
1286     *         return -1;
1287     *     } else if (x > y) {
1288     *         return 1;
1289     *     } else {
1290     *         return 1;
1291     *     }
1292     * }
1293     */
1294    /* op vAA, vBB, vCC */
1295    FETCH(r0, 1)                        @ r0<- CCBB
1296    mov     r9, rINST, lsr #8           @ r9<- AA
1297    and     r2, r0, #255                @ r2<- BB
1298    mov     r3, r0, lsr #8              @ r3<- CC
1299    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1300    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1301    flds    s0, [r2]                    @ s0<- vBB
1302    flds    s1, [r3]                    @ s1<- vCC
1303    fcmpes  s0, s1                      @ compare (vBB, vCC)
1304    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1305    mov     r0, #1                      @ r0<- 1 (default)
1306    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1307    fmstat                              @ export status flags
1308    mvnmi   r0, #0                      @ (less than) r1<- -1
1309    moveq   r0, #0                      @ (equal) r1<- 0
1310    b       .LOP_CMPG_FLOAT_finish          @ argh
1311
1312
1313/* ------------------------------ */
1314    .balign 64
1315.L_OP_CMPL_DOUBLE: /* 0x2f */
1316/* File: arm-vfp/OP_CMPL_DOUBLE.S */
1317    /*
1318     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1319     * destination register based on the results of the comparison.
1320     *
1321     * int compare(x, y) {
1322     *     if (x == y) {
1323     *         return 0;
1324     *     } else if (x > y) {
1325     *         return 1;
1326     *     } else if (x < y) {
1327     *         return -1;
1328     *     } else {
1329     *         return -1;
1330     *     }
1331     * }
1332     */
1333    /* op vAA, vBB, vCC */
1334    FETCH(r0, 1)                        @ r0<- CCBB
1335    mov     r9, rINST, lsr #8           @ r9<- AA
1336    and     r2, r0, #255                @ r2<- BB
1337    mov     r3, r0, lsr #8              @ r3<- CC
1338    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1339    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1340    fldd    d0, [r2]                    @ d0<- vBB
1341    fldd    d1, [r3]                    @ d1<- vCC
1342    fcmped  d0, d1                      @ compare (vBB, vCC)
1343    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1344    mvn     r0, #0                      @ r0<- -1 (default)
1345    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1346    fmstat                              @ export status flags
1347    movgt   r0, #1                      @ (greater than) r1<- 1
1348    moveq   r0, #0                      @ (equal) r1<- 0
1349    b       .LOP_CMPL_DOUBLE_finish          @ argh
1350
1351
1352/* ------------------------------ */
1353    .balign 64
1354.L_OP_CMPG_DOUBLE: /* 0x30 */
1355/* File: arm-vfp/OP_CMPG_DOUBLE.S */
1356    /*
1357     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1358     * destination register based on the results of the comparison.
1359     *
1360     * int compare(x, y) {
1361     *     if (x == y) {
1362     *         return 0;
1363     *     } else if (x < y) {
1364     *         return -1;
1365     *     } else if (x > y) {
1366     *         return 1;
1367     *     } else {
1368     *         return 1;
1369     *     }
1370     * }
1371     */
1372    /* op vAA, vBB, vCC */
1373    FETCH(r0, 1)                        @ r0<- CCBB
1374    mov     r9, rINST, lsr #8           @ r9<- AA
1375    and     r2, r0, #255                @ r2<- BB
1376    mov     r3, r0, lsr #8              @ r3<- CC
1377    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
1378    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
1379    fldd    d0, [r2]                    @ d0<- vBB
1380    fldd    d1, [r3]                    @ d1<- vCC
1381    fcmped  d0, d1                      @ compare (vBB, vCC)
1382    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1383    mov     r0, #1                      @ r0<- 1 (default)
1384    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1385    fmstat                              @ export status flags
1386    mvnmi   r0, #0                      @ (less than) r1<- -1
1387    moveq   r0, #0                      @ (equal) r1<- 0
1388    b       .LOP_CMPG_DOUBLE_finish          @ argh
1389
1390
1391/* ------------------------------ */
1392    .balign 64
1393.L_OP_CMP_LONG: /* 0x31 */
1394/* File: armv5te/OP_CMP_LONG.S */
1395    /*
1396     * Compare two 64-bit values.  Puts 0, 1, or -1 into the destination
1397     * register based on the results of the comparison.
1398     *
1399     * We load the full values with LDM, but in practice many values could
1400     * be resolved by only looking at the high word.  This could be made
1401     * faster or slower by splitting the LDM into a pair of LDRs.
1402     *
1403     * If we just wanted to set condition flags, we could do this:
1404     *  subs    ip, r0, r2
1405     *  sbcs    ip, r1, r3
1406     *  subeqs  ip, r0, r2
1407     * Leaving { <0, 0, >0 } in ip.  However, we have to set it to a specific
1408     * integer value, which we can do with 2 conditional mov/mvn instructions
1409     * (set 1, set -1; if they're equal we already have 0 in ip), giving
1410     * us a constant 5-cycle path plus a branch at the end to the
1411     * instruction epilogue code.  The multi-compare approach below needs
1412     * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch
1413     * in the worst case (the 64-bit values are equal).
1414     */
1415    /* cmp-long vAA, vBB, vCC */
1416    FETCH(r0, 1)                        @ r0<- CCBB
1417    mov     r9, rINST, lsr #8           @ r9<- AA
1418    and     r2, r0, #255                @ r2<- BB
1419    mov     r3, r0, lsr #8              @ r3<- CC
1420    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
1421    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
1422    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
1423    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
1424    cmp     r1, r3                      @ compare (vBB+1, vCC+1)
1425    blt     .LOP_CMP_LONG_less            @ signed compare on high part
1426    bgt     .LOP_CMP_LONG_greater
1427    subs    r1, r0, r2                  @ r1<- r0 - r2
1428    bhi     .LOP_CMP_LONG_greater         @ unsigned compare on low part
1429    bne     .LOP_CMP_LONG_less
1430    b       .LOP_CMP_LONG_finish          @ equal; r1 already holds 0
1431
1432/* ------------------------------ */
1433    .balign 64
1434.L_OP_IF_EQ: /* 0x32 */
1435/* File: armv6t2/OP_IF_EQ.S */
1436/* File: armv6t2/bincmp.S */
1437    /*
1438     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1439     * fragment that specifies the *reverse* comparison to perform, e.g.
1440     * for "if-le" you would use "gt".
1441     *
1442     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1443     */
1444    /* if-cmp vA, vB, +CCCC */
1445    mov     r1, rINST, lsr #12          @ r1<- B
1446    ubfx    r0, rINST, #8, #4           @ r0<- A
1447    GET_VREG(r3, r1)                    @ r3<- vB
1448    GET_VREG(r2, r0)                    @ r2<- vA
1449    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1450    cmp     r2, r3                      @ compare (vA, vB)
1451    movne r1, #2                 @ r1<- BYTE branch dist for not-taken
1452    adds    r2, r1, r1                  @ convert to bytes, check sign
1453    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1454#if defined(WITH_JIT)
1455    ldr     r0, [rSELF, #offThread_pJitProfTable]
1456    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1457    cmp     r0, #0
1458    bne     common_updateProfile
1459#else
1460    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1461#endif
1462    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1463    GOTO_OPCODE(ip)                     @ jump to next instruction
1464
1465
1466/* ------------------------------ */
1467    .balign 64
1468.L_OP_IF_NE: /* 0x33 */
1469/* File: armv6t2/OP_IF_NE.S */
1470/* File: armv6t2/bincmp.S */
1471    /*
1472     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1473     * fragment that specifies the *reverse* comparison to perform, e.g.
1474     * for "if-le" you would use "gt".
1475     *
1476     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1477     */
1478    /* if-cmp vA, vB, +CCCC */
1479    mov     r1, rINST, lsr #12          @ r1<- B
1480    ubfx    r0, rINST, #8, #4           @ r0<- A
1481    GET_VREG(r3, r1)                    @ r3<- vB
1482    GET_VREG(r2, r0)                    @ r2<- vA
1483    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1484    cmp     r2, r3                      @ compare (vA, vB)
1485    moveq r1, #2                 @ r1<- BYTE branch dist for not-taken
1486    adds    r2, r1, r1                  @ convert to bytes, check sign
1487    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1488#if defined(WITH_JIT)
1489    ldr     r0, [rSELF, #offThread_pJitProfTable]
1490    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1491    cmp     r0, #0
1492    bne     common_updateProfile
1493#else
1494    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1495#endif
1496    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1497    GOTO_OPCODE(ip)                     @ jump to next instruction
1498
1499
1500/* ------------------------------ */
1501    .balign 64
1502.L_OP_IF_LT: /* 0x34 */
1503/* File: armv6t2/OP_IF_LT.S */
1504/* File: armv6t2/bincmp.S */
1505    /*
1506     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1507     * fragment that specifies the *reverse* comparison to perform, e.g.
1508     * for "if-le" you would use "gt".
1509     *
1510     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1511     */
1512    /* if-cmp vA, vB, +CCCC */
1513    mov     r1, rINST, lsr #12          @ r1<- B
1514    ubfx    r0, rINST, #8, #4           @ r0<- A
1515    GET_VREG(r3, r1)                    @ r3<- vB
1516    GET_VREG(r2, r0)                    @ r2<- vA
1517    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1518    cmp     r2, r3                      @ compare (vA, vB)
1519    movge r1, #2                 @ r1<- BYTE branch dist for not-taken
1520    adds    r2, r1, r1                  @ convert to bytes, check sign
1521    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1522#if defined(WITH_JIT)
1523    ldr     r0, [rSELF, #offThread_pJitProfTable]
1524    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1525    cmp     r0, #0
1526    bne     common_updateProfile
1527#else
1528    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1529#endif
1530    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1531    GOTO_OPCODE(ip)                     @ jump to next instruction
1532
1533
1534/* ------------------------------ */
1535    .balign 64
1536.L_OP_IF_GE: /* 0x35 */
1537/* File: armv6t2/OP_IF_GE.S */
1538/* File: armv6t2/bincmp.S */
1539    /*
1540     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1541     * fragment that specifies the *reverse* comparison to perform, e.g.
1542     * for "if-le" you would use "gt".
1543     *
1544     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1545     */
1546    /* if-cmp vA, vB, +CCCC */
1547    mov     r1, rINST, lsr #12          @ r1<- B
1548    ubfx    r0, rINST, #8, #4           @ r0<- A
1549    GET_VREG(r3, r1)                    @ r3<- vB
1550    GET_VREG(r2, r0)                    @ r2<- vA
1551    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1552    cmp     r2, r3                      @ compare (vA, vB)
1553    movlt r1, #2                 @ r1<- BYTE branch dist for not-taken
1554    adds    r2, r1, r1                  @ convert to bytes, check sign
1555    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1556#if defined(WITH_JIT)
1557    ldr     r0, [rSELF, #offThread_pJitProfTable]
1558    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1559    cmp     r0, #0
1560    bne     common_updateProfile
1561#else
1562    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1563#endif
1564    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1565    GOTO_OPCODE(ip)                     @ jump to next instruction
1566
1567
1568/* ------------------------------ */
1569    .balign 64
1570.L_OP_IF_GT: /* 0x36 */
1571/* File: armv6t2/OP_IF_GT.S */
1572/* File: armv6t2/bincmp.S */
1573    /*
1574     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1575     * fragment that specifies the *reverse* comparison to perform, e.g.
1576     * for "if-le" you would use "gt".
1577     *
1578     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1579     */
1580    /* if-cmp vA, vB, +CCCC */
1581    mov     r1, rINST, lsr #12          @ r1<- B
1582    ubfx    r0, rINST, #8, #4           @ r0<- A
1583    GET_VREG(r3, r1)                    @ r3<- vB
1584    GET_VREG(r2, r0)                    @ r2<- vA
1585    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1586    cmp     r2, r3                      @ compare (vA, vB)
1587    movle r1, #2                 @ r1<- BYTE branch dist for not-taken
1588    adds    r2, r1, r1                  @ convert to bytes, check sign
1589    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1590#if defined(WITH_JIT)
1591    ldr     r0, [rSELF, #offThread_pJitProfTable]
1592    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1593    cmp     r0, #0
1594    bne     common_updateProfile
1595#else
1596    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1597#endif
1598    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1599    GOTO_OPCODE(ip)                     @ jump to next instruction
1600
1601
1602/* ------------------------------ */
1603    .balign 64
1604.L_OP_IF_LE: /* 0x37 */
1605/* File: armv6t2/OP_IF_LE.S */
1606/* File: armv6t2/bincmp.S */
1607    /*
1608     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1609     * fragment that specifies the *reverse* comparison to perform, e.g.
1610     * for "if-le" you would use "gt".
1611     *
1612     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1613     */
1614    /* if-cmp vA, vB, +CCCC */
1615    mov     r1, rINST, lsr #12          @ r1<- B
1616    ubfx    r0, rINST, #8, #4           @ r0<- A
1617    GET_VREG(r3, r1)                    @ r3<- vB
1618    GET_VREG(r2, r0)                    @ r2<- vA
1619    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1620    cmp     r2, r3                      @ compare (vA, vB)
1621    movgt r1, #2                 @ r1<- BYTE branch dist for not-taken
1622    adds    r2, r1, r1                  @ convert to bytes, check sign
1623    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1624#if defined(WITH_JIT)
1625    ldr     r0, [rSELF, #offThread_pJitProfTable]
1626    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1627    cmp     r0, #0
1628    bne     common_updateProfile
1629#else
1630    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1631#endif
1632    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1633    GOTO_OPCODE(ip)                     @ jump to next instruction
1634
1635
1636/* ------------------------------ */
1637    .balign 64
1638.L_OP_IF_EQZ: /* 0x38 */
1639/* File: armv5te/OP_IF_EQZ.S */
1640/* File: armv5te/zcmp.S */
1641    /*
1642     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1643     * fragment that specifies the *reverse* comparison to perform, e.g.
1644     * for "if-le" you would use "gt".
1645     *
1646     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1647     */
1648    /* if-cmp vAA, +BBBB */
1649    mov     r0, rINST, lsr #8           @ r0<- AA
1650    GET_VREG(r2, r0)                    @ r2<- vAA
1651    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1652    cmp     r2, #0                      @ compare (vA, 0)
1653    movne r1, #2                 @ r1<- inst branch dist for not-taken
1654    adds    r1, r1, r1                  @ convert to bytes & set flags
1655    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1656#if defined(WITH_JIT)
1657    ldr     r0, [rSELF, #offThread_pJitProfTable]
1658    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1659    cmp     r0,#0
1660    bne     common_updateProfile        @ test for JIT off at target
1661#else
1662    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1663#endif
1664    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1665    GOTO_OPCODE(ip)                     @ jump to next instruction
1666
1667
1668/* ------------------------------ */
1669    .balign 64
1670.L_OP_IF_NEZ: /* 0x39 */
1671/* File: armv5te/OP_IF_NEZ.S */
1672/* File: armv5te/zcmp.S */
1673    /*
1674     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1675     * fragment that specifies the *reverse* comparison to perform, e.g.
1676     * for "if-le" you would use "gt".
1677     *
1678     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1679     */
1680    /* if-cmp vAA, +BBBB */
1681    mov     r0, rINST, lsr #8           @ r0<- AA
1682    GET_VREG(r2, r0)                    @ r2<- vAA
1683    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1684    cmp     r2, #0                      @ compare (vA, 0)
1685    moveq r1, #2                 @ r1<- inst branch dist for not-taken
1686    adds    r1, r1, r1                  @ convert to bytes & set flags
1687    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1688#if defined(WITH_JIT)
1689    ldr     r0, [rSELF, #offThread_pJitProfTable]
1690    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1691    cmp     r0,#0
1692    bne     common_updateProfile        @ test for JIT off at target
1693#else
1694    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1695#endif
1696    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1697    GOTO_OPCODE(ip)                     @ jump to next instruction
1698
1699
1700/* ------------------------------ */
1701    .balign 64
1702.L_OP_IF_LTZ: /* 0x3a */
1703/* File: armv5te/OP_IF_LTZ.S */
1704/* File: armv5te/zcmp.S */
1705    /*
1706     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1707     * fragment that specifies the *reverse* comparison to perform, e.g.
1708     * for "if-le" you would use "gt".
1709     *
1710     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1711     */
1712    /* if-cmp vAA, +BBBB */
1713    mov     r0, rINST, lsr #8           @ r0<- AA
1714    GET_VREG(r2, r0)                    @ r2<- vAA
1715    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1716    cmp     r2, #0                      @ compare (vA, 0)
1717    movge r1, #2                 @ r1<- inst branch dist for not-taken
1718    adds    r1, r1, r1                  @ convert to bytes & set flags
1719    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1720#if defined(WITH_JIT)
1721    ldr     r0, [rSELF, #offThread_pJitProfTable]
1722    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1723    cmp     r0,#0
1724    bne     common_updateProfile        @ test for JIT off at target
1725#else
1726    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1727#endif
1728    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1729    GOTO_OPCODE(ip)                     @ jump to next instruction
1730
1731
1732/* ------------------------------ */
1733    .balign 64
1734.L_OP_IF_GEZ: /* 0x3b */
1735/* File: armv5te/OP_IF_GEZ.S */
1736/* File: armv5te/zcmp.S */
1737    /*
1738     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1739     * fragment that specifies the *reverse* comparison to perform, e.g.
1740     * for "if-le" you would use "gt".
1741     *
1742     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1743     */
1744    /* if-cmp vAA, +BBBB */
1745    mov     r0, rINST, lsr #8           @ r0<- AA
1746    GET_VREG(r2, r0)                    @ r2<- vAA
1747    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1748    cmp     r2, #0                      @ compare (vA, 0)
1749    movlt r1, #2                 @ r1<- inst branch dist for not-taken
1750    adds    r1, r1, r1                  @ convert to bytes & set flags
1751    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1752#if defined(WITH_JIT)
1753    ldr     r0, [rSELF, #offThread_pJitProfTable]
1754    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1755    cmp     r0,#0
1756    bne     common_updateProfile        @ test for JIT off at target
1757#else
1758    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1759#endif
1760    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1761    GOTO_OPCODE(ip)                     @ jump to next instruction
1762
1763
1764/* ------------------------------ */
1765    .balign 64
1766.L_OP_IF_GTZ: /* 0x3c */
1767/* File: armv5te/OP_IF_GTZ.S */
1768/* File: armv5te/zcmp.S */
1769    /*
1770     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1771     * fragment that specifies the *reverse* comparison to perform, e.g.
1772     * for "if-le" you would use "gt".
1773     *
1774     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1775     */
1776    /* if-cmp vAA, +BBBB */
1777    mov     r0, rINST, lsr #8           @ r0<- AA
1778    GET_VREG(r2, r0)                    @ r2<- vAA
1779    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1780    cmp     r2, #0                      @ compare (vA, 0)
1781    movle r1, #2                 @ r1<- inst branch dist for not-taken
1782    adds    r1, r1, r1                  @ convert to bytes & set flags
1783    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1784#if defined(WITH_JIT)
1785    ldr     r0, [rSELF, #offThread_pJitProfTable]
1786    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1787    cmp     r0,#0
1788    bne     common_updateProfile        @ test for JIT off at target
1789#else
1790    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1791#endif
1792    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1793    GOTO_OPCODE(ip)                     @ jump to next instruction
1794
1795
1796/* ------------------------------ */
1797    .balign 64
1798.L_OP_IF_LEZ: /* 0x3d */
1799/* File: armv5te/OP_IF_LEZ.S */
1800/* File: armv5te/zcmp.S */
1801    /*
1802     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1803     * fragment that specifies the *reverse* comparison to perform, e.g.
1804     * for "if-le" you would use "gt".
1805     *
1806     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1807     */
1808    /* if-cmp vAA, +BBBB */
1809    mov     r0, rINST, lsr #8           @ r0<- AA
1810    GET_VREG(r2, r0)                    @ r2<- vAA
1811    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1812    cmp     r2, #0                      @ compare (vA, 0)
1813    movgt r1, #2                 @ r1<- inst branch dist for not-taken
1814    adds    r1, r1, r1                  @ convert to bytes & set flags
1815    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1816#if defined(WITH_JIT)
1817    ldr     r0, [rSELF, #offThread_pJitProfTable]
1818    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1819    cmp     r0,#0
1820    bne     common_updateProfile        @ test for JIT off at target
1821#else
1822    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1823#endif
1824    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1825    GOTO_OPCODE(ip)                     @ jump to next instruction
1826
1827
1828/* ------------------------------ */
1829    .balign 64
1830.L_OP_UNUSED_3E: /* 0x3e */
1831/* File: armv5te/OP_UNUSED_3E.S */
1832/* File: armv5te/unused.S */
1833    bl      common_abort
1834
1835
1836/* ------------------------------ */
1837    .balign 64
1838.L_OP_UNUSED_3F: /* 0x3f */
1839/* File: armv5te/OP_UNUSED_3F.S */
1840/* File: armv5te/unused.S */
1841    bl      common_abort
1842
1843
1844/* ------------------------------ */
1845    .balign 64
1846.L_OP_UNUSED_40: /* 0x40 */
1847/* File: armv5te/OP_UNUSED_40.S */
1848/* File: armv5te/unused.S */
1849    bl      common_abort
1850
1851
1852/* ------------------------------ */
1853    .balign 64
1854.L_OP_UNUSED_41: /* 0x41 */
1855/* File: armv5te/OP_UNUSED_41.S */
1856/* File: armv5te/unused.S */
1857    bl      common_abort
1858
1859
1860/* ------------------------------ */
1861    .balign 64
1862.L_OP_UNUSED_42: /* 0x42 */
1863/* File: armv5te/OP_UNUSED_42.S */
1864/* File: armv5te/unused.S */
1865    bl      common_abort
1866
1867
1868/* ------------------------------ */
1869    .balign 64
1870.L_OP_UNUSED_43: /* 0x43 */
1871/* File: armv5te/OP_UNUSED_43.S */
1872/* File: armv5te/unused.S */
1873    bl      common_abort
1874
1875
1876/* ------------------------------ */
1877    .balign 64
1878.L_OP_AGET: /* 0x44 */
1879/* File: armv5te/OP_AGET.S */
1880    /*
1881     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1882     *
1883     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
1884     * instructions.  We use a pair of FETCH_Bs instead.
1885     *
1886     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1887     */
1888    /* op vAA, vBB, vCC */
1889    FETCH_B(r2, 1, 0)                   @ r2<- BB
1890    mov     r9, rINST, lsr #8           @ r9<- AA
1891    FETCH_B(r3, 1, 1)                   @ r3<- CC
1892    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1893    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1894    cmp     r0, #0                      @ null array object?
1895    beq     common_errNullObject        @ yes, bail
1896    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1897    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
1898    cmp     r1, r3                      @ compare unsigned index, length
1899    bcs     common_errArrayIndex        @ index >= length, bail
1900    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1901    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
1902    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1903    SET_VREG(r2, r9)                    @ vAA<- r2
1904    GOTO_OPCODE(ip)                     @ jump to next instruction
1905
1906/* ------------------------------ */
1907    .balign 64
1908.L_OP_AGET_WIDE: /* 0x45 */
1909/* File: armv5te/OP_AGET_WIDE.S */
1910    /*
1911     * Array get, 64 bits.  vAA <- vBB[vCC].
1912     *
1913     * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD.
1914     */
1915    /* aget-wide vAA, vBB, vCC */
1916    FETCH(r0, 1)                        @ r0<- CCBB
1917    mov     r9, rINST, lsr #8           @ r9<- AA
1918    and     r2, r0, #255                @ r2<- BB
1919    mov     r3, r0, lsr #8              @ r3<- CC
1920    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1921    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1922    cmp     r0, #0                      @ null array object?
1923    beq     common_errNullObject        @ yes, bail
1924    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1925    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
1926    cmp     r1, r3                      @ compare unsigned index, length
1927    bcc     .LOP_AGET_WIDE_finish          @ okay, continue below
1928    b       common_errArrayIndex        @ index >= length, bail
1929    @ May want to swap the order of these two branches depending on how the
1930    @ branch prediction (if any) handles conditional forward branches vs.
1931    @ unconditional forward branches.
1932
1933/* ------------------------------ */
1934    .balign 64
1935.L_OP_AGET_OBJECT: /* 0x46 */
1936/* File: armv5te/OP_AGET_OBJECT.S */
1937/* File: armv5te/OP_AGET.S */
1938    /*
1939     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1940     *
1941     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
1942     * instructions.  We use a pair of FETCH_Bs instead.
1943     *
1944     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1945     */
1946    /* op vAA, vBB, vCC */
1947    FETCH_B(r2, 1, 0)                   @ r2<- BB
1948    mov     r9, rINST, lsr #8           @ r9<- AA
1949    FETCH_B(r3, 1, 1)                   @ r3<- CC
1950    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1951    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1952    cmp     r0, #0                      @ null array object?
1953    beq     common_errNullObject        @ yes, bail
1954    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1955    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
1956    cmp     r1, r3                      @ compare unsigned index, length
1957    bcs     common_errArrayIndex        @ index >= length, bail
1958    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1959    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
1960    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1961    SET_VREG(r2, r9)                    @ vAA<- r2
1962    GOTO_OPCODE(ip)                     @ jump to next instruction
1963
1964
1965/* ------------------------------ */
1966    .balign 64
1967.L_OP_AGET_BOOLEAN: /* 0x47 */
1968/* File: armv5te/OP_AGET_BOOLEAN.S */
1969/* File: armv5te/OP_AGET.S */
1970    /*
1971     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1972     *
1973     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
1974     * instructions.  We use a pair of FETCH_Bs instead.
1975     *
1976     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1977     */
1978    /* op vAA, vBB, vCC */
1979    FETCH_B(r2, 1, 0)                   @ r2<- BB
1980    mov     r9, rINST, lsr #8           @ r9<- AA
1981    FETCH_B(r3, 1, 1)                   @ r3<- CC
1982    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1983    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1984    cmp     r0, #0                      @ null array object?
1985    beq     common_errNullObject        @ yes, bail
1986    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1987    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
1988    cmp     r1, r3                      @ compare unsigned index, length
1989    bcs     common_errArrayIndex        @ index >= length, bail
1990    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1991    ldrb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
1992    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1993    SET_VREG(r2, r9)                    @ vAA<- r2
1994    GOTO_OPCODE(ip)                     @ jump to next instruction
1995
1996
1997/* ------------------------------ */
1998    .balign 64
1999.L_OP_AGET_BYTE: /* 0x48 */
2000/* File: armv5te/OP_AGET_BYTE.S */
2001/* File: armv5te/OP_AGET.S */
2002    /*
2003     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2004     *
2005     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2006     * instructions.  We use a pair of FETCH_Bs instead.
2007     *
2008     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2009     */
2010    /* op vAA, vBB, vCC */
2011    FETCH_B(r2, 1, 0)                   @ r2<- BB
2012    mov     r9, rINST, lsr #8           @ r9<- AA
2013    FETCH_B(r3, 1, 1)                   @ r3<- CC
2014    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2015    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2016    cmp     r0, #0                      @ null array object?
2017    beq     common_errNullObject        @ yes, bail
2018    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2019    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2020    cmp     r1, r3                      @ compare unsigned index, length
2021    bcs     common_errArrayIndex        @ index >= length, bail
2022    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2023    ldrsb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2024    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2025    SET_VREG(r2, r9)                    @ vAA<- r2
2026    GOTO_OPCODE(ip)                     @ jump to next instruction
2027
2028
2029/* ------------------------------ */
2030    .balign 64
2031.L_OP_AGET_CHAR: /* 0x49 */
2032/* File: armv5te/OP_AGET_CHAR.S */
2033/* File: armv5te/OP_AGET.S */
2034    /*
2035     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2036     *
2037     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2038     * instructions.  We use a pair of FETCH_Bs instead.
2039     *
2040     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2041     */
2042    /* op vAA, vBB, vCC */
2043    FETCH_B(r2, 1, 0)                   @ r2<- BB
2044    mov     r9, rINST, lsr #8           @ r9<- AA
2045    FETCH_B(r3, 1, 1)                   @ r3<- CC
2046    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2047    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2048    cmp     r0, #0                      @ null array object?
2049    beq     common_errNullObject        @ yes, bail
2050    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2051    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2052    cmp     r1, r3                      @ compare unsigned index, length
2053    bcs     common_errArrayIndex        @ index >= length, bail
2054    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2055    ldrh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2056    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2057    SET_VREG(r2, r9)                    @ vAA<- r2
2058    GOTO_OPCODE(ip)                     @ jump to next instruction
2059
2060
2061/* ------------------------------ */
2062    .balign 64
2063.L_OP_AGET_SHORT: /* 0x4a */
2064/* File: armv5te/OP_AGET_SHORT.S */
2065/* File: armv5te/OP_AGET.S */
2066    /*
2067     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2068     *
2069     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2070     * instructions.  We use a pair of FETCH_Bs instead.
2071     *
2072     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2073     */
2074    /* op vAA, vBB, vCC */
2075    FETCH_B(r2, 1, 0)                   @ r2<- BB
2076    mov     r9, rINST, lsr #8           @ r9<- AA
2077    FETCH_B(r3, 1, 1)                   @ r3<- CC
2078    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2079    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2080    cmp     r0, #0                      @ null array object?
2081    beq     common_errNullObject        @ yes, bail
2082    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2083    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2084    cmp     r1, r3                      @ compare unsigned index, length
2085    bcs     common_errArrayIndex        @ index >= length, bail
2086    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2087    ldrsh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2088    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2089    SET_VREG(r2, r9)                    @ vAA<- r2
2090    GOTO_OPCODE(ip)                     @ jump to next instruction
2091
2092
2093/* ------------------------------ */
2094    .balign 64
2095.L_OP_APUT: /* 0x4b */
2096/* File: armv5te/OP_APUT.S */
2097    /*
2098     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2099     *
2100     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2101     * instructions.  We use a pair of FETCH_Bs instead.
2102     *
2103     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2104     */
2105    /* op vAA, vBB, vCC */
2106    FETCH_B(r2, 1, 0)                   @ r2<- BB
2107    mov     r9, rINST, lsr #8           @ r9<- AA
2108    FETCH_B(r3, 1, 1)                   @ r3<- CC
2109    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2110    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2111    cmp     r0, #0                      @ null array object?
2112    beq     common_errNullObject        @ yes, bail
2113    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2114    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
2115    cmp     r1, r3                      @ compare unsigned index, length
2116    bcs     common_errArrayIndex        @ index >= length, bail
2117    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2118    GET_VREG(r2, r9)                    @ r2<- vAA
2119    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2120    str  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2121    GOTO_OPCODE(ip)                     @ jump to next instruction
2122
2123/* ------------------------------ */
2124    .balign 64
2125.L_OP_APUT_WIDE: /* 0x4c */
2126/* File: armv5te/OP_APUT_WIDE.S */
2127    /*
2128     * Array put, 64 bits.  vBB[vCC] <- vAA.
2129     *
2130     * Arrays of long/double are 64-bit aligned, so it's okay to use STRD.
2131     */
2132    /* aput-wide vAA, vBB, vCC */
2133    FETCH(r0, 1)                        @ r0<- CCBB
2134    mov     r9, rINST, lsr #8           @ r9<- AA
2135    and     r2, r0, #255                @ r2<- BB
2136    mov     r3, r0, lsr #8              @ r3<- CC
2137    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2138    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2139    cmp     r0, #0                      @ null array object?
2140    beq     common_errNullObject        @ yes, bail
2141    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2142    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
2143    cmp     r1, r3                      @ compare unsigned index, length
2144    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2145    bcc     .LOP_APUT_WIDE_finish          @ okay, continue below
2146    b       common_errArrayIndex        @ index >= length, bail
2147    @ May want to swap the order of these two branches depending on how the
2148    @ branch prediction (if any) handles conditional forward branches vs.
2149    @ unconditional forward branches.
2150
2151/* ------------------------------ */
2152    .balign 64
2153.L_OP_APUT_OBJECT: /* 0x4d */
2154/* File: armv5te/OP_APUT_OBJECT.S */
2155    /*
2156     * Store an object into an array.  vBB[vCC] <- vAA.
2157     */
2158    /* op vAA, vBB, vCC */
2159    FETCH(r0, 1)                        @ r0<- CCBB
2160    mov     r9, rINST, lsr #8           @ r9<- AA
2161    and     r2, r0, #255                @ r2<- BB
2162    mov     r3, r0, lsr #8              @ r3<- CC
2163    GET_VREG(rINST, r2)                 @ rINST<- vBB (array object)
2164    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2165    cmp     rINST, #0                   @ null array object?
2166    GET_VREG(r9, r9)                    @ r9<- vAA
2167    beq     common_errNullObject        @ yes, bail
2168    ldr     r3, [rINST, #offArrayObject_length]   @ r3<- arrayObj->length
2169    add     r10, rINST, r1, lsl #2      @ r10<- arrayObj + index*width
2170    cmp     r1, r3                      @ compare unsigned index, length
2171    bcc     .LOP_APUT_OBJECT_finish          @ we're okay, continue on
2172    b       common_errArrayIndex        @ index >= length, bail
2173
2174
2175/* ------------------------------ */
2176    .balign 64
2177.L_OP_APUT_BOOLEAN: /* 0x4e */
2178/* File: armv5te/OP_APUT_BOOLEAN.S */
2179/* File: armv5te/OP_APUT.S */
2180    /*
2181     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2182     *
2183     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2184     * instructions.  We use a pair of FETCH_Bs instead.
2185     *
2186     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2187     */
2188    /* op vAA, vBB, vCC */
2189    FETCH_B(r2, 1, 0)                   @ r2<- BB
2190    mov     r9, rINST, lsr #8           @ r9<- AA
2191    FETCH_B(r3, 1, 1)                   @ r3<- CC
2192    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2193    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2194    cmp     r0, #0                      @ null array object?
2195    beq     common_errNullObject        @ yes, bail
2196    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2197    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2198    cmp     r1, r3                      @ compare unsigned index, length
2199    bcs     common_errArrayIndex        @ index >= length, bail
2200    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2201    GET_VREG(r2, r9)                    @ r2<- vAA
2202    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2203    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2204    GOTO_OPCODE(ip)                     @ jump to next instruction
2205
2206
2207/* ------------------------------ */
2208    .balign 64
2209.L_OP_APUT_BYTE: /* 0x4f */
2210/* File: armv5te/OP_APUT_BYTE.S */
2211/* File: armv5te/OP_APUT.S */
2212    /*
2213     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2214     *
2215     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2216     * instructions.  We use a pair of FETCH_Bs instead.
2217     *
2218     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2219     */
2220    /* op vAA, vBB, vCC */
2221    FETCH_B(r2, 1, 0)                   @ r2<- BB
2222    mov     r9, rINST, lsr #8           @ r9<- AA
2223    FETCH_B(r3, 1, 1)                   @ r3<- CC
2224    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2225    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2226    cmp     r0, #0                      @ null array object?
2227    beq     common_errNullObject        @ yes, bail
2228    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2229    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2230    cmp     r1, r3                      @ compare unsigned index, length
2231    bcs     common_errArrayIndex        @ index >= length, bail
2232    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2233    GET_VREG(r2, r9)                    @ r2<- vAA
2234    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2235    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2236    GOTO_OPCODE(ip)                     @ jump to next instruction
2237
2238
2239/* ------------------------------ */
2240    .balign 64
2241.L_OP_APUT_CHAR: /* 0x50 */
2242/* File: armv5te/OP_APUT_CHAR.S */
2243/* File: armv5te/OP_APUT.S */
2244    /*
2245     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2246     *
2247     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2248     * instructions.  We use a pair of FETCH_Bs instead.
2249     *
2250     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2251     */
2252    /* op vAA, vBB, vCC */
2253    FETCH_B(r2, 1, 0)                   @ r2<- BB
2254    mov     r9, rINST, lsr #8           @ r9<- AA
2255    FETCH_B(r3, 1, 1)                   @ r3<- CC
2256    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2257    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2258    cmp     r0, #0                      @ null array object?
2259    beq     common_errNullObject        @ yes, bail
2260    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2261    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2262    cmp     r1, r3                      @ compare unsigned index, length
2263    bcs     common_errArrayIndex        @ index >= length, bail
2264    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2265    GET_VREG(r2, r9)                    @ r2<- vAA
2266    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2267    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2268    GOTO_OPCODE(ip)                     @ jump to next instruction
2269
2270
2271/* ------------------------------ */
2272    .balign 64
2273.L_OP_APUT_SHORT: /* 0x51 */
2274/* File: armv5te/OP_APUT_SHORT.S */
2275/* File: armv5te/OP_APUT.S */
2276    /*
2277     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2278     *
2279     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2280     * instructions.  We use a pair of FETCH_Bs instead.
2281     *
2282     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2283     */
2284    /* op vAA, vBB, vCC */
2285    FETCH_B(r2, 1, 0)                   @ r2<- BB
2286    mov     r9, rINST, lsr #8           @ r9<- AA
2287    FETCH_B(r3, 1, 1)                   @ r3<- CC
2288    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2289    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2290    cmp     r0, #0                      @ null array object?
2291    beq     common_errNullObject        @ yes, bail
2292    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2293    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2294    cmp     r1, r3                      @ compare unsigned index, length
2295    bcs     common_errArrayIndex        @ index >= length, bail
2296    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2297    GET_VREG(r2, r9)                    @ r2<- vAA
2298    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2299    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2300    GOTO_OPCODE(ip)                     @ jump to next instruction
2301
2302
2303/* ------------------------------ */
2304    .balign 64
2305.L_OP_IGET: /* 0x52 */
2306/* File: armv6t2/OP_IGET.S */
2307    /*
2308     * General 32-bit instance field get.
2309     *
2310     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2311     */
2312    /* op vA, vB, field@CCCC */
2313    mov     r0, rINST, lsr #12          @ r0<- B
2314    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2315    FETCH(r1, 1)                        @ r1<- field ref CCCC
2316    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2317    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2318    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2319    cmp     r0, #0                      @ is resolved entry null?
2320    bne     .LOP_IGET_finish          @ no, already resolved
23218:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2322    EXPORT_PC()                         @ resolve() could throw
2323    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2324    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2325    cmp     r0, #0
2326    bne     .LOP_IGET_finish
2327    b       common_exceptionThrown
2328
2329/* ------------------------------ */
2330    .balign 64
2331.L_OP_IGET_WIDE: /* 0x53 */
2332/* File: armv6t2/OP_IGET_WIDE.S */
2333    /*
2334     * Wide 32-bit instance field get.
2335     */
2336    /* iget-wide vA, vB, field@CCCC */
2337    mov     r0, rINST, lsr #12          @ r0<- B
2338    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2339    FETCH(r1, 1)                        @ r1<- field ref CCCC
2340    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
2341    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2342    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2343    cmp     r0, #0                      @ is resolved entry null?
2344    bne     .LOP_IGET_WIDE_finish          @ no, already resolved
23458:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
2346    EXPORT_PC()                         @ resolve() could throw
2347    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2348    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2349    cmp     r0, #0
2350    bne     .LOP_IGET_WIDE_finish
2351    b       common_exceptionThrown
2352
2353/* ------------------------------ */
2354    .balign 64
2355.L_OP_IGET_OBJECT: /* 0x54 */
2356/* File: armv5te/OP_IGET_OBJECT.S */
2357/* File: armv5te/OP_IGET.S */
2358    /*
2359     * General 32-bit instance field get.
2360     *
2361     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2362     */
2363    /* op vA, vB, field@CCCC */
2364    mov     r0, rINST, lsr #12          @ r0<- B
2365    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2366    FETCH(r1, 1)                        @ r1<- field ref CCCC
2367    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2368    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2369    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2370    cmp     r0, #0                      @ is resolved entry null?
2371    bne     .LOP_IGET_OBJECT_finish          @ no, already resolved
23728:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2373    EXPORT_PC()                         @ resolve() could throw
2374    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2375    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2376    cmp     r0, #0
2377    bne     .LOP_IGET_OBJECT_finish
2378    b       common_exceptionThrown
2379
2380
2381/* ------------------------------ */
2382    .balign 64
2383.L_OP_IGET_BOOLEAN: /* 0x55 */
2384/* File: armv5te/OP_IGET_BOOLEAN.S */
2385@include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" }
2386/* File: armv5te/OP_IGET.S */
2387    /*
2388     * General 32-bit instance field get.
2389     *
2390     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2391     */
2392    /* op vA, vB, field@CCCC */
2393    mov     r0, rINST, lsr #12          @ r0<- B
2394    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2395    FETCH(r1, 1)                        @ r1<- field ref CCCC
2396    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2397    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2398    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2399    cmp     r0, #0                      @ is resolved entry null?
2400    bne     .LOP_IGET_BOOLEAN_finish          @ no, already resolved
24018:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2402    EXPORT_PC()                         @ resolve() could throw
2403    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2404    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2405    cmp     r0, #0
2406    bne     .LOP_IGET_BOOLEAN_finish
2407    b       common_exceptionThrown
2408
2409
2410/* ------------------------------ */
2411    .balign 64
2412.L_OP_IGET_BYTE: /* 0x56 */
2413/* File: armv5te/OP_IGET_BYTE.S */
2414@include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" }
2415/* File: armv5te/OP_IGET.S */
2416    /*
2417     * General 32-bit instance field get.
2418     *
2419     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2420     */
2421    /* op vA, vB, field@CCCC */
2422    mov     r0, rINST, lsr #12          @ r0<- B
2423    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2424    FETCH(r1, 1)                        @ r1<- field ref CCCC
2425    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2426    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2427    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2428    cmp     r0, #0                      @ is resolved entry null?
2429    bne     .LOP_IGET_BYTE_finish          @ no, already resolved
24308:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2431    EXPORT_PC()                         @ resolve() could throw
2432    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2433    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2434    cmp     r0, #0
2435    bne     .LOP_IGET_BYTE_finish
2436    b       common_exceptionThrown
2437
2438
2439/* ------------------------------ */
2440    .balign 64
2441.L_OP_IGET_CHAR: /* 0x57 */
2442/* File: armv5te/OP_IGET_CHAR.S */
2443@include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" }
2444/* File: armv5te/OP_IGET.S */
2445    /*
2446     * General 32-bit instance field get.
2447     *
2448     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2449     */
2450    /* op vA, vB, field@CCCC */
2451    mov     r0, rINST, lsr #12          @ r0<- B
2452    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2453    FETCH(r1, 1)                        @ r1<- field ref CCCC
2454    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2455    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2456    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2457    cmp     r0, #0                      @ is resolved entry null?
2458    bne     .LOP_IGET_CHAR_finish          @ no, already resolved
24598:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2460    EXPORT_PC()                         @ resolve() could throw
2461    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2462    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2463    cmp     r0, #0
2464    bne     .LOP_IGET_CHAR_finish
2465    b       common_exceptionThrown
2466
2467
2468/* ------------------------------ */
2469    .balign 64
2470.L_OP_IGET_SHORT: /* 0x58 */
2471/* File: armv5te/OP_IGET_SHORT.S */
2472@include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" }
2473/* File: armv5te/OP_IGET.S */
2474    /*
2475     * General 32-bit instance field get.
2476     *
2477     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2478     */
2479    /* op vA, vB, field@CCCC */
2480    mov     r0, rINST, lsr #12          @ r0<- B
2481    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2482    FETCH(r1, 1)                        @ r1<- field ref CCCC
2483    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2484    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2485    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2486    cmp     r0, #0                      @ is resolved entry null?
2487    bne     .LOP_IGET_SHORT_finish          @ no, already resolved
24888:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2489    EXPORT_PC()                         @ resolve() could throw
2490    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2491    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2492    cmp     r0, #0
2493    bne     .LOP_IGET_SHORT_finish
2494    b       common_exceptionThrown
2495
2496
2497/* ------------------------------ */
2498    .balign 64
2499.L_OP_IPUT: /* 0x59 */
2500/* File: armv6t2/OP_IPUT.S */
2501    /*
2502     * General 32-bit instance field put.
2503     *
2504     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
2505     */
2506    /* op vA, vB, field@CCCC */
2507    mov     r0, rINST, lsr #12          @ r0<- B
2508    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2509    FETCH(r1, 1)                        @ r1<- field ref CCCC
2510    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2511    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2512    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2513    cmp     r0, #0                      @ is resolved entry null?
2514    bne     .LOP_IPUT_finish          @ no, already resolved
25158:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2516    EXPORT_PC()                         @ resolve() could throw
2517    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2518    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2519    cmp     r0, #0                      @ success?
2520    bne     .LOP_IPUT_finish          @ yes, finish up
2521    b       common_exceptionThrown
2522
2523/* ------------------------------ */
2524    .balign 64
2525.L_OP_IPUT_WIDE: /* 0x5a */
2526/* File: armv6t2/OP_IPUT_WIDE.S */
2527    /* iput-wide vA, vB, field@CCCC */
2528    mov     r0, rINST, lsr #12          @ r0<- B
2529    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2530    FETCH(r1, 1)                        @ r1<- field ref CCCC
2531    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
2532    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2533    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2534    cmp     r0, #0                      @ is resolved entry null?
2535    bne     .LOP_IPUT_WIDE_finish          @ no, already resolved
25368:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
2537    EXPORT_PC()                         @ resolve() could throw
2538    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2539    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2540    cmp     r0, #0                      @ success?
2541    bne     .LOP_IPUT_WIDE_finish          @ yes, finish up
2542    b       common_exceptionThrown
2543
2544/* ------------------------------ */
2545    .balign 64
2546.L_OP_IPUT_OBJECT: /* 0x5b */
2547/* File: armv5te/OP_IPUT_OBJECT.S */
2548    /*
2549     * 32-bit instance field put.
2550     *
2551     * for: iput-object, iput-object-volatile
2552     */
2553    /* op vA, vB, field@CCCC */
2554    mov     r0, rINST, lsr #12          @ r0<- B
2555    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2556    FETCH(r1, 1)                        @ r1<- field ref CCCC
2557    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2558    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2559    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2560    cmp     r0, #0                      @ is resolved entry null?
2561    bne     .LOP_IPUT_OBJECT_finish          @ no, already resolved
25628:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2563    EXPORT_PC()                         @ resolve() could throw
2564    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2565    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2566    cmp     r0, #0                      @ success?
2567    bne     .LOP_IPUT_OBJECT_finish          @ yes, finish up
2568    b       common_exceptionThrown
2569
2570/* ------------------------------ */
2571    .balign 64
2572.L_OP_IPUT_BOOLEAN: /* 0x5c */
2573/* File: armv5te/OP_IPUT_BOOLEAN.S */
2574@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" }
2575/* File: armv5te/OP_IPUT.S */
2576    /*
2577     * General 32-bit instance field put.
2578     *
2579     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2580     */
2581    /* op vA, vB, field@CCCC */
2582    mov     r0, rINST, lsr #12          @ r0<- B
2583    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2584    FETCH(r1, 1)                        @ r1<- field ref CCCC
2585    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2586    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2587    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2588    cmp     r0, #0                      @ is resolved entry null?
2589    bne     .LOP_IPUT_BOOLEAN_finish          @ no, already resolved
25908:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2591    EXPORT_PC()                         @ resolve() could throw
2592    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2593    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2594    cmp     r0, #0                      @ success?
2595    bne     .LOP_IPUT_BOOLEAN_finish          @ yes, finish up
2596    b       common_exceptionThrown
2597
2598
2599/* ------------------------------ */
2600    .balign 64
2601.L_OP_IPUT_BYTE: /* 0x5d */
2602/* File: armv5te/OP_IPUT_BYTE.S */
2603@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" }
2604/* File: armv5te/OP_IPUT.S */
2605    /*
2606     * General 32-bit instance field put.
2607     *
2608     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2609     */
2610    /* op vA, vB, field@CCCC */
2611    mov     r0, rINST, lsr #12          @ r0<- B
2612    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2613    FETCH(r1, 1)                        @ r1<- field ref CCCC
2614    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2615    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2616    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2617    cmp     r0, #0                      @ is resolved entry null?
2618    bne     .LOP_IPUT_BYTE_finish          @ no, already resolved
26198:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2620    EXPORT_PC()                         @ resolve() could throw
2621    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2622    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2623    cmp     r0, #0                      @ success?
2624    bne     .LOP_IPUT_BYTE_finish          @ yes, finish up
2625    b       common_exceptionThrown
2626
2627
2628/* ------------------------------ */
2629    .balign 64
2630.L_OP_IPUT_CHAR: /* 0x5e */
2631/* File: armv5te/OP_IPUT_CHAR.S */
2632@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" }
2633/* File: armv5te/OP_IPUT.S */
2634    /*
2635     * General 32-bit instance field put.
2636     *
2637     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2638     */
2639    /* op vA, vB, field@CCCC */
2640    mov     r0, rINST, lsr #12          @ r0<- B
2641    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2642    FETCH(r1, 1)                        @ r1<- field ref CCCC
2643    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2644    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2645    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2646    cmp     r0, #0                      @ is resolved entry null?
2647    bne     .LOP_IPUT_CHAR_finish          @ no, already resolved
26488:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2649    EXPORT_PC()                         @ resolve() could throw
2650    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2651    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2652    cmp     r0, #0                      @ success?
2653    bne     .LOP_IPUT_CHAR_finish          @ yes, finish up
2654    b       common_exceptionThrown
2655
2656
2657/* ------------------------------ */
2658    .balign 64
2659.L_OP_IPUT_SHORT: /* 0x5f */
2660/* File: armv5te/OP_IPUT_SHORT.S */
2661@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" }
2662/* File: armv5te/OP_IPUT.S */
2663    /*
2664     * General 32-bit instance field put.
2665     *
2666     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2667     */
2668    /* op vA, vB, field@CCCC */
2669    mov     r0, rINST, lsr #12          @ r0<- B
2670    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2671    FETCH(r1, 1)                        @ r1<- field ref CCCC
2672    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2673    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2674    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2675    cmp     r0, #0                      @ is resolved entry null?
2676    bne     .LOP_IPUT_SHORT_finish          @ no, already resolved
26778:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2678    EXPORT_PC()                         @ resolve() could throw
2679    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2680    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2681    cmp     r0, #0                      @ success?
2682    bne     .LOP_IPUT_SHORT_finish          @ yes, finish up
2683    b       common_exceptionThrown
2684
2685
2686/* ------------------------------ */
2687    .balign 64
2688.L_OP_SGET: /* 0x60 */
2689/* File: armv5te/OP_SGET.S */
2690    /*
2691     * General 32-bit SGET handler.
2692     *
2693     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2694     */
2695    /* op vAA, field@BBBB */
2696    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2697    FETCH(r1, 1)                        @ r1<- field ref BBBB
2698    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2699    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2700    cmp     r0, #0                      @ is resolved entry null?
2701    beq     .LOP_SGET_resolve         @ yes, do resolve
2702.LOP_SGET_finish: @ field ptr in r0
2703    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2704    @ no-op                             @ acquiring load
2705    mov     r2, rINST, lsr #8           @ r2<- AA
2706    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2707    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2708    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2709    GOTO_OPCODE(ip)                     @ jump to next instruction
2710
2711/* ------------------------------ */
2712    .balign 64
2713.L_OP_SGET_WIDE: /* 0x61 */
2714/* File: armv5te/OP_SGET_WIDE.S */
2715    /*
2716     * 64-bit SGET handler.
2717     */
2718    /* sget-wide vAA, field@BBBB */
2719    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2720    FETCH(r1, 1)                        @ r1<- field ref BBBB
2721    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2722    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2723    cmp     r0, #0                      @ is resolved entry null?
2724    beq     .LOP_SGET_WIDE_resolve         @ yes, do resolve
2725.LOP_SGET_WIDE_finish:
2726    mov     r9, rINST, lsr #8           @ r9<- AA
2727    .if 0
2728    add     r0, r0, #offStaticField_value @ r0<- pointer to data
2729    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
2730    .else
2731    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
2732    .endif
2733    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2734    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2735    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
2736    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2737    GOTO_OPCODE(ip)                     @ jump to next instruction
2738
2739/* ------------------------------ */
2740    .balign 64
2741.L_OP_SGET_OBJECT: /* 0x62 */
2742/* File: armv5te/OP_SGET_OBJECT.S */
2743/* File: armv5te/OP_SGET.S */
2744    /*
2745     * General 32-bit SGET handler.
2746     *
2747     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2748     */
2749    /* op vAA, field@BBBB */
2750    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2751    FETCH(r1, 1)                        @ r1<- field ref BBBB
2752    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2753    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2754    cmp     r0, #0                      @ is resolved entry null?
2755    beq     .LOP_SGET_OBJECT_resolve         @ yes, do resolve
2756.LOP_SGET_OBJECT_finish: @ field ptr in r0
2757    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2758    @ no-op                             @ acquiring load
2759    mov     r2, rINST, lsr #8           @ r2<- AA
2760    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2761    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2762    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2763    GOTO_OPCODE(ip)                     @ jump to next instruction
2764
2765
2766/* ------------------------------ */
2767    .balign 64
2768.L_OP_SGET_BOOLEAN: /* 0x63 */
2769/* File: armv5te/OP_SGET_BOOLEAN.S */
2770/* File: armv5te/OP_SGET.S */
2771    /*
2772     * General 32-bit SGET handler.
2773     *
2774     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2775     */
2776    /* op vAA, field@BBBB */
2777    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2778    FETCH(r1, 1)                        @ r1<- field ref BBBB
2779    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2780    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2781    cmp     r0, #0                      @ is resolved entry null?
2782    beq     .LOP_SGET_BOOLEAN_resolve         @ yes, do resolve
2783.LOP_SGET_BOOLEAN_finish: @ field ptr in r0
2784    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2785    @ no-op                             @ acquiring load
2786    mov     r2, rINST, lsr #8           @ r2<- AA
2787    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2788    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2789    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2790    GOTO_OPCODE(ip)                     @ jump to next instruction
2791
2792
2793/* ------------------------------ */
2794    .balign 64
2795.L_OP_SGET_BYTE: /* 0x64 */
2796/* File: armv5te/OP_SGET_BYTE.S */
2797/* File: armv5te/OP_SGET.S */
2798    /*
2799     * General 32-bit SGET handler.
2800     *
2801     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2802     */
2803    /* op vAA, field@BBBB */
2804    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2805    FETCH(r1, 1)                        @ r1<- field ref BBBB
2806    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2807    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2808    cmp     r0, #0                      @ is resolved entry null?
2809    beq     .LOP_SGET_BYTE_resolve         @ yes, do resolve
2810.LOP_SGET_BYTE_finish: @ field ptr in r0
2811    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2812    @ no-op                             @ acquiring load
2813    mov     r2, rINST, lsr #8           @ r2<- AA
2814    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2815    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2816    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2817    GOTO_OPCODE(ip)                     @ jump to next instruction
2818
2819
2820/* ------------------------------ */
2821    .balign 64
2822.L_OP_SGET_CHAR: /* 0x65 */
2823/* File: armv5te/OP_SGET_CHAR.S */
2824/* File: armv5te/OP_SGET.S */
2825    /*
2826     * General 32-bit SGET handler.
2827     *
2828     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2829     */
2830    /* op vAA, field@BBBB */
2831    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2832    FETCH(r1, 1)                        @ r1<- field ref BBBB
2833    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2834    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2835    cmp     r0, #0                      @ is resolved entry null?
2836    beq     .LOP_SGET_CHAR_resolve         @ yes, do resolve
2837.LOP_SGET_CHAR_finish: @ field ptr in r0
2838    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2839    @ no-op                             @ acquiring load
2840    mov     r2, rINST, lsr #8           @ r2<- AA
2841    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2842    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2843    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2844    GOTO_OPCODE(ip)                     @ jump to next instruction
2845
2846
2847/* ------------------------------ */
2848    .balign 64
2849.L_OP_SGET_SHORT: /* 0x66 */
2850/* File: armv5te/OP_SGET_SHORT.S */
2851/* File: armv5te/OP_SGET.S */
2852    /*
2853     * General 32-bit SGET handler.
2854     *
2855     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2856     */
2857    /* op vAA, field@BBBB */
2858    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2859    FETCH(r1, 1)                        @ r1<- field ref BBBB
2860    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2861    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2862    cmp     r0, #0                      @ is resolved entry null?
2863    beq     .LOP_SGET_SHORT_resolve         @ yes, do resolve
2864.LOP_SGET_SHORT_finish: @ field ptr in r0
2865    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2866    @ no-op                             @ acquiring load
2867    mov     r2, rINST, lsr #8           @ r2<- AA
2868    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2869    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2870    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2871    GOTO_OPCODE(ip)                     @ jump to next instruction
2872
2873
2874/* ------------------------------ */
2875    .balign 64
2876.L_OP_SPUT: /* 0x67 */
2877/* File: armv5te/OP_SPUT.S */
2878    /*
2879     * General 32-bit SPUT handler.
2880     *
2881     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2882     */
2883    /* op vAA, field@BBBB */
2884    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2885    FETCH(r1, 1)                        @ r1<- field ref BBBB
2886    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2887    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
2888    cmp     r0, #0                      @ is resolved entry null?
2889    beq     .LOP_SPUT_resolve         @ yes, do resolve
2890.LOP_SPUT_finish:   @ field ptr in r0
2891    mov     r2, rINST, lsr #8           @ r2<- AA
2892    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2893    GET_VREG(r1, r2)                    @ r1<- fp[AA]
2894    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2895    @ no-op                        @ releasing store
2896    str     r1, [r0, #offStaticField_value] @ field<- vAA
2897    @ no-op
2898    GOTO_OPCODE(ip)                     @ jump to next instruction
2899
2900/* ------------------------------ */
2901    .balign 64
2902.L_OP_SPUT_WIDE: /* 0x68 */
2903/* File: armv5te/OP_SPUT_WIDE.S */
2904    /*
2905     * 64-bit SPUT handler.
2906     */
2907    /* sput-wide vAA, field@BBBB */
2908    ldr     r0, [rSELF, #offThread_methodClassDex]  @ r0<- DvmDex
2909    FETCH(r1, 1)                        @ r1<- field ref BBBB
2910    ldr     r10, [r0, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2911    mov     r9, rINST, lsr #8           @ r9<- AA
2912    ldr     r2, [r10, r1, lsl #2]        @ r2<- resolved StaticField ptr
2913    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2914    cmp     r2, #0                      @ is resolved entry null?
2915    beq     .LOP_SPUT_WIDE_resolve         @ yes, do resolve
2916.LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9
2917    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2918    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
2919    GET_INST_OPCODE(r10)                @ extract opcode from rINST
2920    .if 0
2921    add     r2, r2, #offStaticField_value @ r2<- pointer to data
2922    bl      dvmQuasiAtomicSwap64Sync    @ stores r0/r1 into addr r2
2923    .else
2924    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
2925    .endif
2926    GOTO_OPCODE(r10)                    @ jump to next instruction
2927
2928/* ------------------------------ */
2929    .balign 64
2930.L_OP_SPUT_OBJECT: /* 0x69 */
2931/* File: armv5te/OP_SPUT_OBJECT.S */
2932    /*
2933     * 32-bit SPUT handler for objects
2934     *
2935     * for: sput-object, sput-object-volatile
2936     */
2937    /* op vAA, field@BBBB */
2938    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2939    FETCH(r1, 1)                        @ r1<- field ref BBBB
2940    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2941    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
2942    cmp     r0, #0                      @ is resolved entry null?
2943    beq     .LOP_SPUT_OBJECT_resolve         @ yes, do resolve
2944.LOP_SPUT_OBJECT_finish:   @ field ptr in r0
2945    mov     r2, rINST, lsr #8           @ r2<- AA
2946    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2947    GET_VREG(r1, r2)                    @ r1<- fp[AA]
2948    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
2949    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
2950    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2951    @ no-op                         @ releasing store
2952    b       .LOP_SPUT_OBJECT_end
2953
2954/* ------------------------------ */
2955    .balign 64
2956.L_OP_SPUT_BOOLEAN: /* 0x6a */
2957/* File: armv5te/OP_SPUT_BOOLEAN.S */
2958/* File: armv5te/OP_SPUT.S */
2959    /*
2960     * General 32-bit SPUT handler.
2961     *
2962     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2963     */
2964    /* op vAA, field@BBBB */
2965    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2966    FETCH(r1, 1)                        @ r1<- field ref BBBB
2967    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2968    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
2969    cmp     r0, #0                      @ is resolved entry null?
2970    beq     .LOP_SPUT_BOOLEAN_resolve         @ yes, do resolve
2971.LOP_SPUT_BOOLEAN_finish:   @ field ptr in r0
2972    mov     r2, rINST, lsr #8           @ r2<- AA
2973    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2974    GET_VREG(r1, r2)                    @ r1<- fp[AA]
2975    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2976    @ no-op                        @ releasing store
2977    str     r1, [r0, #offStaticField_value] @ field<- vAA
2978    @ no-op
2979    GOTO_OPCODE(ip)                     @ jump to next instruction
2980
2981
2982/* ------------------------------ */
2983    .balign 64
2984.L_OP_SPUT_BYTE: /* 0x6b */
2985/* File: armv5te/OP_SPUT_BYTE.S */
2986/* File: armv5te/OP_SPUT.S */
2987    /*
2988     * General 32-bit SPUT handler.
2989     *
2990     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2991     */
2992    /* op vAA, field@BBBB */
2993    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2994    FETCH(r1, 1)                        @ r1<- field ref BBBB
2995    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2996    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
2997    cmp     r0, #0                      @ is resolved entry null?
2998    beq     .LOP_SPUT_BYTE_resolve         @ yes, do resolve
2999.LOP_SPUT_BYTE_finish:   @ field ptr in r0
3000    mov     r2, rINST, lsr #8           @ r2<- AA
3001    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3002    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3003    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3004    @ no-op                        @ releasing store
3005    str     r1, [r0, #offStaticField_value] @ field<- vAA
3006    @ no-op
3007    GOTO_OPCODE(ip)                     @ jump to next instruction
3008
3009
3010/* ------------------------------ */
3011    .balign 64
3012.L_OP_SPUT_CHAR: /* 0x6c */
3013/* File: armv5te/OP_SPUT_CHAR.S */
3014/* File: armv5te/OP_SPUT.S */
3015    /*
3016     * General 32-bit SPUT handler.
3017     *
3018     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3019     */
3020    /* op vAA, field@BBBB */
3021    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
3022    FETCH(r1, 1)                        @ r1<- field ref BBBB
3023    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
3024    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
3025    cmp     r0, #0                      @ is resolved entry null?
3026    beq     .LOP_SPUT_CHAR_resolve         @ yes, do resolve
3027.LOP_SPUT_CHAR_finish:   @ field ptr in r0
3028    mov     r2, rINST, lsr #8           @ r2<- AA
3029    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3030    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3031    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3032    @ no-op                        @ releasing store
3033    str     r1, [r0, #offStaticField_value] @ field<- vAA
3034    @ no-op
3035    GOTO_OPCODE(ip)                     @ jump to next instruction
3036
3037
3038/* ------------------------------ */
3039    .balign 64
3040.L_OP_SPUT_SHORT: /* 0x6d */
3041/* File: armv5te/OP_SPUT_SHORT.S */
3042/* File: armv5te/OP_SPUT.S */
3043    /*
3044     * General 32-bit SPUT handler.
3045     *
3046     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3047     */
3048    /* op vAA, field@BBBB */
3049    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
3050    FETCH(r1, 1)                        @ r1<- field ref BBBB
3051    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
3052    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
3053    cmp     r0, #0                      @ is resolved entry null?
3054    beq     .LOP_SPUT_SHORT_resolve         @ yes, do resolve
3055.LOP_SPUT_SHORT_finish:   @ field ptr in r0
3056    mov     r2, rINST, lsr #8           @ r2<- AA
3057    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3058    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3059    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3060    @ no-op                        @ releasing store
3061    str     r1, [r0, #offStaticField_value] @ field<- vAA
3062    @ no-op
3063    GOTO_OPCODE(ip)                     @ jump to next instruction
3064
3065
3066/* ------------------------------ */
3067    .balign 64
3068.L_OP_INVOKE_VIRTUAL: /* 0x6e */
3069/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3070    /*
3071     * Handle a virtual method call.
3072     *
3073     * for: invoke-virtual, invoke-virtual/range
3074     */
3075    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3076    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3077    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3078    FETCH(r1, 1)                        @ r1<- BBBB
3079    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3080    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3081    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3082    .if     (!0)
3083    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3084    .endif
3085    cmp     r0, #0                      @ already resolved?
3086    EXPORT_PC()                         @ must export for invoke
3087    bne     .LOP_INVOKE_VIRTUAL_continue        @ yes, continue on
3088    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
3089    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3090    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3091    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3092    cmp     r0, #0                      @ got null?
3093    bne     .LOP_INVOKE_VIRTUAL_continue        @ no, continue
3094    b       common_exceptionThrown      @ yes, handle exception
3095
3096/* ------------------------------ */
3097    .balign 64
3098.L_OP_INVOKE_SUPER: /* 0x6f */
3099/* File: armv5te/OP_INVOKE_SUPER.S */
3100    /*
3101     * Handle a "super" method call.
3102     *
3103     * for: invoke-super, invoke-super/range
3104     */
3105    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3106    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3107    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3108    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3109    .if     (!0)
3110    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3111    .endif
3112    FETCH(r1, 1)                        @ r1<- BBBB
3113    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3114    GET_VREG(r9, r10)                   @ r9<- "this" ptr
3115    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3116    cmp     r9, #0                      @ null "this"?
3117    ldr     r10, [rSELF, #offThread_method] @ r10<- current method
3118    beq     common_errNullObject        @ null "this", throw exception
3119    cmp     r0, #0                      @ already resolved?
3120    ldr     r10, [r10, #offMethod_clazz]  @ r10<- method->clazz
3121    EXPORT_PC()                         @ must export for invoke
3122    bne     .LOP_INVOKE_SUPER_continue        @ resolved, continue on
3123    b       .LOP_INVOKE_SUPER_resolve         @ do resolve now
3124
3125/* ------------------------------ */
3126    .balign 64
3127.L_OP_INVOKE_DIRECT: /* 0x70 */
3128/* File: armv5te/OP_INVOKE_DIRECT.S */
3129    /*
3130     * Handle a direct method call.
3131     *
3132     * (We could defer the "is 'this' pointer null" test to the common
3133     * method invocation code, and use a flag to indicate that static
3134     * calls don't count.  If we do this as part of copying the arguments
3135     * out we could avoiding loading the first arg twice.)
3136     *
3137     * for: invoke-direct, invoke-direct/range
3138     */
3139    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3140    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3141    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3142    FETCH(r1, 1)                        @ r1<- BBBB
3143    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3144    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3145    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3146    .if     (!0)
3147    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3148    .endif
3149    cmp     r0, #0                      @ already resolved?
3150    EXPORT_PC()                         @ must export for invoke
3151    GET_VREG(r9, r10)                   @ r9<- "this" ptr
3152    beq     .LOP_INVOKE_DIRECT_resolve         @ not resolved, do it now
3153.LOP_INVOKE_DIRECT_finish:
3154    cmp     r9, #0                      @ null "this" ref?
3155    bne     common_invokeMethodNoRange   @ r0=method, r9="this"
3156    b       common_errNullObject        @ yes, throw exception
3157
3158/* ------------------------------ */
3159    .balign 64
3160.L_OP_INVOKE_STATIC: /* 0x71 */
3161/* File: armv5te/OP_INVOKE_STATIC.S */
3162    /*
3163     * Handle a static method call.
3164     *
3165     * for: invoke-static, invoke-static/range
3166     */
3167    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3168    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3169    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3170    FETCH(r1, 1)                        @ r1<- BBBB
3171    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3172    mov     r9, #0                      @ null "this" in delay slot
3173    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3174#if defined(WITH_JIT)
3175    add     r10, r3, r1, lsl #2         @ r10<- &resolved_methodToCall
3176#endif
3177    cmp     r0, #0                      @ already resolved?
3178    EXPORT_PC()                         @ must export for invoke
3179    bne     common_invokeMethodNoRange @ yes, continue on
3180    b       .LOP_INVOKE_STATIC_resolve
3181
3182/* ------------------------------ */
3183    .balign 64
3184.L_OP_INVOKE_INTERFACE: /* 0x72 */
3185/* File: armv5te/OP_INVOKE_INTERFACE.S */
3186    /*
3187     * Handle an interface method call.
3188     *
3189     * for: invoke-interface, invoke-interface/range
3190     */
3191    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3192    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3193    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3194    FETCH(r1, 1)                        @ r1<- BBBB
3195    .if     (!0)
3196    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3197    .endif
3198    EXPORT_PC()                         @ must export for invoke
3199    GET_VREG(r9, r2)                    @ r9<- first arg ("this")
3200    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- methodClassDex
3201    cmp     r9, #0                      @ null obj?
3202    ldr     r2, [rSELF, #offThread_method]  @ r2<- method
3203    beq     common_errNullObject        @ yes, fail
3204    ldr     r0, [r9, #offObject_clazz]  @ r0<- thisPtr->clazz
3205    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3206    cmp     r0, #0                      @ failed?
3207    beq     common_exceptionThrown      @ yes, handle exception
3208    b       common_invokeMethodNoRange @ (r0=method, r9="this")
3209
3210/* ------------------------------ */
3211    .balign 64
3212.L_OP_UNUSED_73: /* 0x73 */
3213/* File: armv5te/OP_UNUSED_73.S */
3214/* File: armv5te/unused.S */
3215    bl      common_abort
3216
3217
3218/* ------------------------------ */
3219    .balign 64
3220.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
3221/* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */
3222/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3223    /*
3224     * Handle a virtual method call.
3225     *
3226     * for: invoke-virtual, invoke-virtual/range
3227     */
3228    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3229    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3230    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3231    FETCH(r1, 1)                        @ r1<- BBBB
3232    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3233    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3234    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3235    .if     (!1)
3236    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3237    .endif
3238    cmp     r0, #0                      @ already resolved?
3239    EXPORT_PC()                         @ must export for invoke
3240    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ yes, continue on
3241    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
3242    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3243    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3244    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3245    cmp     r0, #0                      @ got null?
3246    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ no, continue
3247    b       common_exceptionThrown      @ yes, handle exception
3248
3249
3250/* ------------------------------ */
3251    .balign 64
3252.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */
3253/* File: armv5te/OP_INVOKE_SUPER_RANGE.S */
3254/* File: armv5te/OP_INVOKE_SUPER.S */
3255    /*
3256     * Handle a "super" method call.
3257     *
3258     * for: invoke-super, invoke-super/range
3259     */
3260    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3261    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3262    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3263    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3264    .if     (!1)
3265    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3266    .endif
3267    FETCH(r1, 1)                        @ r1<- BBBB
3268    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3269    GET_VREG(r9, r10)                   @ r9<- "this" ptr
3270    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3271    cmp     r9, #0                      @ null "this"?
3272    ldr     r10, [rSELF, #offThread_method] @ r10<- current method
3273    beq     common_errNullObject        @ null "this", throw exception
3274    cmp     r0, #0                      @ already resolved?
3275    ldr     r10, [r10, #offMethod_clazz]  @ r10<- method->clazz
3276    EXPORT_PC()                         @ must export for invoke
3277    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ resolved, continue on
3278    b       .LOP_INVOKE_SUPER_RANGE_resolve         @ do resolve now
3279
3280
3281/* ------------------------------ */
3282    .balign 64
3283.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
3284/* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */
3285/* File: armv5te/OP_INVOKE_DIRECT.S */
3286    /*
3287     * Handle a direct method call.
3288     *
3289     * (We could defer the "is 'this' pointer null" test to the common
3290     * method invocation code, and use a flag to indicate that static
3291     * calls don't count.  If we do this as part of copying the arguments
3292     * out we could avoiding loading the first arg twice.)
3293     *
3294     * for: invoke-direct, invoke-direct/range
3295     */
3296    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3297    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3298    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3299    FETCH(r1, 1)                        @ r1<- BBBB
3300    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3301    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3302    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3303    .if     (!1)
3304    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3305    .endif
3306    cmp     r0, #0                      @ already resolved?
3307    EXPORT_PC()                         @ must export for invoke
3308    GET_VREG(r9, r10)                   @ r9<- "this" ptr
3309    beq     .LOP_INVOKE_DIRECT_RANGE_resolve         @ not resolved, do it now
3310.LOP_INVOKE_DIRECT_RANGE_finish:
3311    cmp     r9, #0                      @ null "this" ref?
3312    bne     common_invokeMethodRange   @ r0=method, r9="this"
3313    b       common_errNullObject        @ yes, throw exception
3314
3315
3316/* ------------------------------ */
3317    .balign 64
3318.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */
3319/* File: armv5te/OP_INVOKE_STATIC_RANGE.S */
3320/* File: armv5te/OP_INVOKE_STATIC.S */
3321    /*
3322     * Handle a static method call.
3323     *
3324     * for: invoke-static, invoke-static/range
3325     */
3326    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3327    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3328    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3329    FETCH(r1, 1)                        @ r1<- BBBB
3330    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3331    mov     r9, #0                      @ null "this" in delay slot
3332    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3333#if defined(WITH_JIT)
3334    add     r10, r3, r1, lsl #2         @ r10<- &resolved_methodToCall
3335#endif
3336    cmp     r0, #0                      @ already resolved?
3337    EXPORT_PC()                         @ must export for invoke
3338    bne     common_invokeMethodRange @ yes, continue on
3339    b       .LOP_INVOKE_STATIC_RANGE_resolve
3340
3341
3342/* ------------------------------ */
3343    .balign 64
3344.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
3345/* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */
3346/* File: armv5te/OP_INVOKE_INTERFACE.S */
3347    /*
3348     * Handle an interface method call.
3349     *
3350     * for: invoke-interface, invoke-interface/range
3351     */
3352    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3353    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3354    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3355    FETCH(r1, 1)                        @ r1<- BBBB
3356    .if     (!1)
3357    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3358    .endif
3359    EXPORT_PC()                         @ must export for invoke
3360    GET_VREG(r9, r2)                    @ r9<- first arg ("this")
3361    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- methodClassDex
3362    cmp     r9, #0                      @ null obj?
3363    ldr     r2, [rSELF, #offThread_method]  @ r2<- method
3364    beq     common_errNullObject        @ yes, fail
3365    ldr     r0, [r9, #offObject_clazz]  @ r0<- thisPtr->clazz
3366    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3367    cmp     r0, #0                      @ failed?
3368    beq     common_exceptionThrown      @ yes, handle exception
3369    b       common_invokeMethodRange @ (r0=method, r9="this")
3370
3371
3372/* ------------------------------ */
3373    .balign 64
3374.L_OP_UNUSED_79: /* 0x79 */
3375/* File: armv5te/OP_UNUSED_79.S */
3376/* File: armv5te/unused.S */
3377    bl      common_abort
3378
3379
3380/* ------------------------------ */
3381    .balign 64
3382.L_OP_UNUSED_7A: /* 0x7a */
3383/* File: armv5te/OP_UNUSED_7A.S */
3384/* File: armv5te/unused.S */
3385    bl      common_abort
3386
3387
3388/* ------------------------------ */
3389    .balign 64
3390.L_OP_NEG_INT: /* 0x7b */
3391/* File: armv6t2/OP_NEG_INT.S */
3392/* File: armv6t2/unop.S */
3393    /*
3394     * Generic 32-bit unary operation.  Provide an "instr" line that
3395     * specifies an instruction that performs "result = op r0".
3396     * This could be an ARM instruction or a function call.
3397     *
3398     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3399     *      int-to-byte, int-to-char, int-to-short
3400     */
3401    /* unop vA, vB */
3402    mov     r3, rINST, lsr #12          @ r3<- B
3403    ubfx    r9, rINST, #8, #4           @ r9<- A
3404    GET_VREG(r0, r3)                    @ r0<- vB
3405                               @ optional op; may set condition codes
3406    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3407    rsb     r0, r0, #0                              @ r0<- op, r0-r3 changed
3408    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3409    SET_VREG(r0, r9)                    @ vAA<- r0
3410    GOTO_OPCODE(ip)                     @ jump to next instruction
3411    /* 8-9 instructions */
3412
3413
3414/* ------------------------------ */
3415    .balign 64
3416.L_OP_NOT_INT: /* 0x7c */
3417/* File: armv6t2/OP_NOT_INT.S */
3418/* File: armv6t2/unop.S */
3419    /*
3420     * Generic 32-bit unary operation.  Provide an "instr" line that
3421     * specifies an instruction that performs "result = op r0".
3422     * This could be an ARM instruction or a function call.
3423     *
3424     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3425     *      int-to-byte, int-to-char, int-to-short
3426     */
3427    /* unop vA, vB */
3428    mov     r3, rINST, lsr #12          @ r3<- B
3429    ubfx    r9, rINST, #8, #4           @ r9<- A
3430    GET_VREG(r0, r3)                    @ r0<- vB
3431                               @ optional op; may set condition codes
3432    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3433    mvn     r0, r0                              @ r0<- op, r0-r3 changed
3434    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3435    SET_VREG(r0, r9)                    @ vAA<- r0
3436    GOTO_OPCODE(ip)                     @ jump to next instruction
3437    /* 8-9 instructions */
3438
3439
3440/* ------------------------------ */
3441    .balign 64
3442.L_OP_NEG_LONG: /* 0x7d */
3443/* File: armv6t2/OP_NEG_LONG.S */
3444/* File: armv6t2/unopWide.S */
3445    /*
3446     * Generic 64-bit unary operation.  Provide an "instr" line that
3447     * specifies an instruction that performs "result = op r0/r1".
3448     * This could be an ARM instruction or a function call.
3449     *
3450     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3451     */
3452    /* unop vA, vB */
3453    mov     r3, rINST, lsr #12          @ r3<- B
3454    ubfx    r9, rINST, #8, #4           @ r9<- A
3455    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3456    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3457    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3458    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3459    rsbs    r0, r0, #0                           @ optional op; may set condition codes
3460    rsc     r1, r1, #0                              @ r0/r1<- op, r2-r3 changed
3461    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3462    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3463    GOTO_OPCODE(ip)                     @ jump to next instruction
3464    /* 10-11 instructions */
3465
3466
3467/* ------------------------------ */
3468    .balign 64
3469.L_OP_NOT_LONG: /* 0x7e */
3470/* File: armv6t2/OP_NOT_LONG.S */
3471/* File: armv6t2/unopWide.S */
3472    /*
3473     * Generic 64-bit unary operation.  Provide an "instr" line that
3474     * specifies an instruction that performs "result = op r0/r1".
3475     * This could be an ARM instruction or a function call.
3476     *
3477     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3478     */
3479    /* unop vA, vB */
3480    mov     r3, rINST, lsr #12          @ r3<- B
3481    ubfx    r9, rINST, #8, #4           @ r9<- A
3482    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3483    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3484    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3485    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3486    mvn     r0, r0                           @ optional op; may set condition codes
3487    mvn     r1, r1                              @ r0/r1<- op, r2-r3 changed
3488    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3489    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3490    GOTO_OPCODE(ip)                     @ jump to next instruction
3491    /* 10-11 instructions */
3492
3493
3494/* ------------------------------ */
3495    .balign 64
3496.L_OP_NEG_FLOAT: /* 0x7f */
3497/* File: armv6t2/OP_NEG_FLOAT.S */
3498/* File: armv6t2/unop.S */
3499    /*
3500     * Generic 32-bit unary operation.  Provide an "instr" line that
3501     * specifies an instruction that performs "result = op r0".
3502     * This could be an ARM instruction or a function call.
3503     *
3504     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3505     *      int-to-byte, int-to-char, int-to-short
3506     */
3507    /* unop vA, vB */
3508    mov     r3, rINST, lsr #12          @ r3<- B
3509    ubfx    r9, rINST, #8, #4           @ r9<- A
3510    GET_VREG(r0, r3)                    @ r0<- vB
3511                               @ optional op; may set condition codes
3512    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3513    add     r0, r0, #0x80000000                              @ r0<- op, r0-r3 changed
3514    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3515    SET_VREG(r0, r9)                    @ vAA<- r0
3516    GOTO_OPCODE(ip)                     @ jump to next instruction
3517    /* 8-9 instructions */
3518
3519
3520/* ------------------------------ */
3521    .balign 64
3522.L_OP_NEG_DOUBLE: /* 0x80 */
3523/* File: armv6t2/OP_NEG_DOUBLE.S */
3524/* File: armv6t2/unopWide.S */
3525    /*
3526     * Generic 64-bit unary operation.  Provide an "instr" line that
3527     * specifies an instruction that performs "result = op r0/r1".
3528     * This could be an ARM instruction or a function call.
3529     *
3530     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3531     */
3532    /* unop vA, vB */
3533    mov     r3, rINST, lsr #12          @ r3<- B
3534    ubfx    r9, rINST, #8, #4           @ r9<- A
3535    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3536    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3537    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3538    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3539                               @ optional op; may set condition codes
3540    add     r1, r1, #0x80000000                              @ r0/r1<- op, r2-r3 changed
3541    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3542    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3543    GOTO_OPCODE(ip)                     @ jump to next instruction
3544    /* 10-11 instructions */
3545
3546
3547/* ------------------------------ */
3548    .balign 64
3549.L_OP_INT_TO_LONG: /* 0x81 */
3550/* File: armv6t2/OP_INT_TO_LONG.S */
3551/* File: armv6t2/unopWider.S */
3552    /*
3553     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3554     * that specifies an instruction that performs "result = op r0", where
3555     * "result" is a 64-bit quantity in r0/r1.
3556     *
3557     * For: int-to-long, int-to-double, float-to-long, float-to-double
3558     */
3559    /* unop vA, vB */
3560    mov     r3, rINST, lsr #12          @ r3<- B
3561    ubfx    r9, rINST, #8, #4           @ r9<- A
3562    GET_VREG(r0, r3)                    @ r0<- vB
3563    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3564                               @ optional op; may set condition codes
3565    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3566    mov     r1, r0, asr #31                              @ r0<- op, r0-r3 changed
3567    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3568    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3569    GOTO_OPCODE(ip)                     @ jump to next instruction
3570    /* 9-10 instructions */
3571
3572
3573/* ------------------------------ */
3574    .balign 64
3575.L_OP_INT_TO_FLOAT: /* 0x82 */
3576/* File: arm-vfp/OP_INT_TO_FLOAT.S */
3577/* File: arm-vfp/funop.S */
3578    /*
3579     * Generic 32-bit unary floating-point operation.  Provide an "instr"
3580     * line that specifies an instruction that performs "s1 = op s0".
3581     *
3582     * for: int-to-float, float-to-int
3583     */
3584    /* unop vA, vB */
3585    mov     r3, rINST, lsr #12          @ r3<- B
3586    mov     r9, rINST, lsr #8           @ r9<- A+
3587    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3588    flds    s0, [r3]                    @ s0<- vB
3589    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3590    and     r9, r9, #15                 @ r9<- A
3591    fsitos  s1, s0                              @ s1<- op
3592    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3593    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3594    fsts    s1, [r9]                    @ vA<- s1
3595    GOTO_OPCODE(ip)                     @ jump to next instruction
3596
3597
3598/* ------------------------------ */
3599    .balign 64
3600.L_OP_INT_TO_DOUBLE: /* 0x83 */
3601/* File: arm-vfp/OP_INT_TO_DOUBLE.S */
3602/* File: arm-vfp/funopWider.S */
3603    /*
3604     * Generic 32bit-to-64bit floating point unary operation.  Provide an
3605     * "instr" line that specifies an instruction that performs "d0 = op s0".
3606     *
3607     * For: int-to-double, float-to-double
3608     */
3609    /* unop vA, vB */
3610    mov     r3, rINST, lsr #12          @ r3<- B
3611    mov     r9, rINST, lsr #8           @ r9<- A+
3612    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3613    flds    s0, [r3]                    @ s0<- vB
3614    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3615    and     r9, r9, #15                 @ r9<- A
3616    fsitod  d0, s0                              @ d0<- op
3617    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3618    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3619    fstd    d0, [r9]                    @ vA<- d0
3620    GOTO_OPCODE(ip)                     @ jump to next instruction
3621
3622
3623/* ------------------------------ */
3624    .balign 64
3625.L_OP_LONG_TO_INT: /* 0x84 */
3626/* File: armv5te/OP_LONG_TO_INT.S */
3627/* we ignore the high word, making this equivalent to a 32-bit reg move */
3628/* File: armv5te/OP_MOVE.S */
3629    /* for move, move-object, long-to-int */
3630    /* op vA, vB */
3631    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
3632    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
3633    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3634    GET_VREG(r2, r1)                    @ r2<- fp[B]
3635    and     r0, r0, #15
3636    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
3637    SET_VREG(r2, r0)                    @ fp[A]<- r2
3638    GOTO_OPCODE(ip)                     @ execute next instruction
3639
3640
3641/* ------------------------------ */
3642    .balign 64
3643.L_OP_LONG_TO_FLOAT: /* 0x85 */
3644/* File: armv6t2/OP_LONG_TO_FLOAT.S */
3645/* File: armv6t2/unopNarrower.S */
3646    /*
3647     * Generic 64bit-to-32bit unary operation.  Provide an "instr" line
3648     * that specifies an instruction that performs "result = op r0/r1", where
3649     * "result" is a 32-bit quantity in r0.
3650     *
3651     * For: long-to-float, double-to-int, double-to-float
3652     *
3653     * (This would work for long-to-int, but that instruction is actually
3654     * an exact match for OP_MOVE.)
3655     */
3656    /* unop vA, vB */
3657    mov     r3, rINST, lsr #12          @ r3<- B
3658    ubfx    r9, rINST, #8, #4           @ r9<- A
3659    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3660    ldmia   r3, {r0-r1}                 @ r0/r1<- vB/vB+1
3661    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3662                               @ optional op; may set condition codes
3663    bl      __aeabi_l2f                              @ r0<- op, r0-r3 changed
3664    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3665    SET_VREG(r0, r9)                    @ vA<- r0
3666    GOTO_OPCODE(ip)                     @ jump to next instruction
3667    /* 9-10 instructions */
3668
3669
3670/* ------------------------------ */
3671    .balign 64
3672.L_OP_LONG_TO_DOUBLE: /* 0x86 */
3673/* File: armv6t2/OP_LONG_TO_DOUBLE.S */
3674/* File: armv6t2/unopWide.S */
3675    /*
3676     * Generic 64-bit unary operation.  Provide an "instr" line that
3677     * specifies an instruction that performs "result = op r0/r1".
3678     * This could be an ARM instruction or a function call.
3679     *
3680     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3681     */
3682    /* unop vA, vB */
3683    mov     r3, rINST, lsr #12          @ r3<- B
3684    ubfx    r9, rINST, #8, #4           @ r9<- A
3685    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3686    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3687    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3688    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3689                               @ optional op; may set condition codes
3690    bl      __aeabi_l2d                              @ r0/r1<- op, r2-r3 changed
3691    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3692    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3693    GOTO_OPCODE(ip)                     @ jump to next instruction
3694    /* 10-11 instructions */
3695
3696
3697/* ------------------------------ */
3698    .balign 64
3699.L_OP_FLOAT_TO_INT: /* 0x87 */
3700/* File: arm-vfp/OP_FLOAT_TO_INT.S */
3701/* File: arm-vfp/funop.S */
3702    /*
3703     * Generic 32-bit unary floating-point operation.  Provide an "instr"
3704     * line that specifies an instruction that performs "s1 = op s0".
3705     *
3706     * for: int-to-float, float-to-int
3707     */
3708    /* unop vA, vB */
3709    mov     r3, rINST, lsr #12          @ r3<- B
3710    mov     r9, rINST, lsr #8           @ r9<- A+
3711    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3712    flds    s0, [r3]                    @ s0<- vB
3713    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3714    and     r9, r9, #15                 @ r9<- A
3715    ftosizs s1, s0                              @ s1<- op
3716    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3717    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3718    fsts    s1, [r9]                    @ vA<- s1
3719    GOTO_OPCODE(ip)                     @ jump to next instruction
3720
3721
3722/* ------------------------------ */
3723    .balign 64
3724.L_OP_FLOAT_TO_LONG: /* 0x88 */
3725/* File: armv6t2/OP_FLOAT_TO_LONG.S */
3726@include "armv6t2/unopWider.S" {"instr":"bl      __aeabi_f2lz"}
3727/* File: armv6t2/unopWider.S */
3728    /*
3729     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3730     * that specifies an instruction that performs "result = op r0", where
3731     * "result" is a 64-bit quantity in r0/r1.
3732     *
3733     * For: int-to-long, int-to-double, float-to-long, float-to-double
3734     */
3735    /* unop vA, vB */
3736    mov     r3, rINST, lsr #12          @ r3<- B
3737    ubfx    r9, rINST, #8, #4           @ r9<- A
3738    GET_VREG(r0, r3)                    @ r0<- vB
3739    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3740                               @ optional op; may set condition codes
3741    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3742    bl      f2l_doconv                              @ r0<- op, r0-r3 changed
3743    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3744    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3745    GOTO_OPCODE(ip)                     @ jump to next instruction
3746    /* 9-10 instructions */
3747
3748
3749
3750/* ------------------------------ */
3751    .balign 64
3752.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */
3753/* File: arm-vfp/OP_FLOAT_TO_DOUBLE.S */
3754/* File: arm-vfp/funopWider.S */
3755    /*
3756     * Generic 32bit-to-64bit floating point unary operation.  Provide an
3757     * "instr" line that specifies an instruction that performs "d0 = op s0".
3758     *
3759     * For: int-to-double, float-to-double
3760     */
3761    /* unop vA, vB */
3762    mov     r3, rINST, lsr #12          @ r3<- B
3763    mov     r9, rINST, lsr #8           @ r9<- A+
3764    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3765    flds    s0, [r3]                    @ s0<- vB
3766    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3767    and     r9, r9, #15                 @ r9<- A
3768    fcvtds  d0, s0                              @ d0<- op
3769    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3770    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3771    fstd    d0, [r9]                    @ vA<- d0
3772    GOTO_OPCODE(ip)                     @ jump to next instruction
3773
3774
3775/* ------------------------------ */
3776    .balign 64
3777.L_OP_DOUBLE_TO_INT: /* 0x8a */
3778/* File: arm-vfp/OP_DOUBLE_TO_INT.S */
3779/* File: arm-vfp/funopNarrower.S */
3780    /*
3781     * Generic 64bit-to-32bit unary floating point operation.  Provide an
3782     * "instr" line that specifies an instruction that performs "s0 = op d0".
3783     *
3784     * For: double-to-int, double-to-float
3785     */
3786    /* unop vA, vB */
3787    mov     r3, rINST, lsr #12          @ r3<- B
3788    mov     r9, rINST, lsr #8           @ r9<- A+
3789    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3790    fldd    d0, [r3]                    @ d0<- vB
3791    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3792    and     r9, r9, #15                 @ r9<- A
3793    ftosizd  s0, d0                              @ s0<- op
3794    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3795    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3796    fsts    s0, [r9]                    @ vA<- s0
3797    GOTO_OPCODE(ip)                     @ jump to next instruction
3798
3799
3800/* ------------------------------ */
3801    .balign 64
3802.L_OP_DOUBLE_TO_LONG: /* 0x8b */
3803/* File: armv6t2/OP_DOUBLE_TO_LONG.S */
3804@include "armv6t2/unopWide.S" {"instr":"bl      __aeabi_d2lz"}
3805/* File: armv6t2/unopWide.S */
3806    /*
3807     * Generic 64-bit unary operation.  Provide an "instr" line that
3808     * specifies an instruction that performs "result = op r0/r1".
3809     * This could be an ARM instruction or a function call.
3810     *
3811     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3812     */
3813    /* unop vA, vB */
3814    mov     r3, rINST, lsr #12          @ r3<- B
3815    ubfx    r9, rINST, #8, #4           @ r9<- A
3816    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3817    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3818    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3819    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3820                               @ optional op; may set condition codes
3821    bl      d2l_doconv                              @ r0/r1<- op, r2-r3 changed
3822    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3823    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3824    GOTO_OPCODE(ip)                     @ jump to next instruction
3825    /* 10-11 instructions */
3826
3827
3828
3829/* ------------------------------ */
3830    .balign 64
3831.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */
3832/* File: arm-vfp/OP_DOUBLE_TO_FLOAT.S */
3833/* File: arm-vfp/funopNarrower.S */
3834    /*
3835     * Generic 64bit-to-32bit unary floating point operation.  Provide an
3836     * "instr" line that specifies an instruction that performs "s0 = op d0".
3837     *
3838     * For: double-to-int, double-to-float
3839     */
3840    /* unop vA, vB */
3841    mov     r3, rINST, lsr #12          @ r3<- B
3842    mov     r9, rINST, lsr #8           @ r9<- A+
3843    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
3844    fldd    d0, [r3]                    @ d0<- vB
3845    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3846    and     r9, r9, #15                 @ r9<- A
3847    fcvtsd  s0, d0                              @ s0<- op
3848    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3849    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
3850    fsts    s0, [r9]                    @ vA<- s0
3851    GOTO_OPCODE(ip)                     @ jump to next instruction
3852
3853
3854/* ------------------------------ */
3855    .balign 64
3856.L_OP_INT_TO_BYTE: /* 0x8d */
3857/* File: armv6t2/OP_INT_TO_BYTE.S */
3858/* File: armv6t2/unop.S */
3859    /*
3860     * Generic 32-bit unary operation.  Provide an "instr" line that
3861     * specifies an instruction that performs "result = op r0".
3862     * This could be an ARM instruction or a function call.
3863     *
3864     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3865     *      int-to-byte, int-to-char, int-to-short
3866     */
3867    /* unop vA, vB */
3868    mov     r3, rINST, lsr #12          @ r3<- B
3869    ubfx    r9, rINST, #8, #4           @ r9<- A
3870    GET_VREG(r0, r3)                    @ r0<- vB
3871                               @ optional op; may set condition codes
3872    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3873    sxtb    r0, r0                              @ r0<- op, r0-r3 changed
3874    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3875    SET_VREG(r0, r9)                    @ vAA<- r0
3876    GOTO_OPCODE(ip)                     @ jump to next instruction
3877    /* 8-9 instructions */
3878
3879
3880/* ------------------------------ */
3881    .balign 64
3882.L_OP_INT_TO_CHAR: /* 0x8e */
3883/* File: armv6t2/OP_INT_TO_CHAR.S */
3884/* File: armv6t2/unop.S */
3885    /*
3886     * Generic 32-bit unary operation.  Provide an "instr" line that
3887     * specifies an instruction that performs "result = op r0".
3888     * This could be an ARM instruction or a function call.
3889     *
3890     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3891     *      int-to-byte, int-to-char, int-to-short
3892     */
3893    /* unop vA, vB */
3894    mov     r3, rINST, lsr #12          @ r3<- B
3895    ubfx    r9, rINST, #8, #4           @ r9<- A
3896    GET_VREG(r0, r3)                    @ r0<- vB
3897                               @ optional op; may set condition codes
3898    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3899    uxth    r0, r0                              @ r0<- op, r0-r3 changed
3900    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3901    SET_VREG(r0, r9)                    @ vAA<- r0
3902    GOTO_OPCODE(ip)                     @ jump to next instruction
3903    /* 8-9 instructions */
3904
3905
3906/* ------------------------------ */
3907    .balign 64
3908.L_OP_INT_TO_SHORT: /* 0x8f */
3909/* File: armv6t2/OP_INT_TO_SHORT.S */
3910/* File: armv6t2/unop.S */
3911    /*
3912     * Generic 32-bit unary operation.  Provide an "instr" line that
3913     * specifies an instruction that performs "result = op r0".
3914     * This could be an ARM instruction or a function call.
3915     *
3916     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3917     *      int-to-byte, int-to-char, int-to-short
3918     */
3919    /* unop vA, vB */
3920    mov     r3, rINST, lsr #12          @ r3<- B
3921    ubfx    r9, rINST, #8, #4           @ r9<- A
3922    GET_VREG(r0, r3)                    @ r0<- vB
3923                               @ optional op; may set condition codes
3924    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3925    sxth    r0, r0                              @ r0<- op, r0-r3 changed
3926    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3927    SET_VREG(r0, r9)                    @ vAA<- r0
3928    GOTO_OPCODE(ip)                     @ jump to next instruction
3929    /* 8-9 instructions */
3930
3931
3932/* ------------------------------ */
3933    .balign 64
3934.L_OP_ADD_INT: /* 0x90 */
3935/* File: armv5te/OP_ADD_INT.S */
3936/* File: armv5te/binop.S */
3937    /*
3938     * Generic 32-bit binary operation.  Provide an "instr" line that
3939     * specifies an instruction that performs "result = r0 op r1".
3940     * This could be an ARM instruction or a function call.  (If the result
3941     * comes back in a register other than r0, you can override "result".)
3942     *
3943     * If "chkzero" is set to 1, we perform a divide-by-zero check on
3944     * vCC (r1).  Useful for integer division and modulus.  Note that we
3945     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
3946     * handles it correctly.
3947     *
3948     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
3949     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
3950     *      mul-float, div-float, rem-float
3951     */
3952    /* binop vAA, vBB, vCC */
3953    FETCH(r0, 1)                        @ r0<- CCBB
3954    mov     r9, rINST, lsr #8           @ r9<- AA
3955    mov     r3, r0, lsr #8              @ r3<- CC
3956    and     r2, r0, #255                @ r2<- BB
3957    GET_VREG(r1, r3)                    @ r1<- vCC
3958    GET_VREG(r0, r2)                    @ r0<- vBB
3959    .if 0
3960    cmp     r1, #0                      @ is second operand zero?
3961    beq     common_errDivideByZero
3962    .endif
3963
3964    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3965                               @ optional op; may set condition codes
3966    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
3967    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3968    SET_VREG(r0, r9)               @ vAA<- r0
3969    GOTO_OPCODE(ip)                     @ jump to next instruction
3970    /* 11-14 instructions */
3971
3972
3973/* ------------------------------ */
3974    .balign 64
3975.L_OP_SUB_INT: /* 0x91 */
3976/* File: armv5te/OP_SUB_INT.S */
3977/* File: armv5te/binop.S */
3978    /*
3979     * Generic 32-bit binary operation.  Provide an "instr" line that
3980     * specifies an instruction that performs "result = r0 op r1".
3981     * This could be an ARM instruction or a function call.  (If the result
3982     * comes back in a register other than r0, you can override "result".)
3983     *
3984     * If "chkzero" is set to 1, we perform a divide-by-zero check on
3985     * vCC (r1).  Useful for integer division and modulus.  Note that we
3986     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
3987     * handles it correctly.
3988     *
3989     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
3990     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
3991     *      mul-float, div-float, rem-float
3992     */
3993    /* binop vAA, vBB, vCC */
3994    FETCH(r0, 1)                        @ r0<- CCBB
3995    mov     r9, rINST, lsr #8           @ r9<- AA
3996    mov     r3, r0, lsr #8              @ r3<- CC
3997    and     r2, r0, #255                @ r2<- BB
3998    GET_VREG(r1, r3)                    @ r1<- vCC
3999    GET_VREG(r0, r2)                    @ r0<- vBB
4000    .if 0
4001    cmp     r1, #0                      @ is second operand zero?
4002    beq     common_errDivideByZero
4003    .endif
4004
4005    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4006                               @ optional op; may set condition codes
4007    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
4008    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4009    SET_VREG(r0, r9)               @ vAA<- r0
4010    GOTO_OPCODE(ip)                     @ jump to next instruction
4011    /* 11-14 instructions */
4012
4013
4014/* ------------------------------ */
4015    .balign 64
4016.L_OP_MUL_INT: /* 0x92 */
4017/* File: armv5te/OP_MUL_INT.S */
4018/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
4019/* File: armv5te/binop.S */
4020    /*
4021     * Generic 32-bit binary operation.  Provide an "instr" line that
4022     * specifies an instruction that performs "result = r0 op r1".
4023     * This could be an ARM instruction or a function call.  (If the result
4024     * comes back in a register other than r0, you can override "result".)
4025     *
4026     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4027     * vCC (r1).  Useful for integer division and modulus.  Note that we
4028     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4029     * handles it correctly.
4030     *
4031     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4032     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4033     *      mul-float, div-float, rem-float
4034     */
4035    /* binop vAA, vBB, vCC */
4036    FETCH(r0, 1)                        @ r0<- CCBB
4037    mov     r9, rINST, lsr #8           @ r9<- AA
4038    mov     r3, r0, lsr #8              @ r3<- CC
4039    and     r2, r0, #255                @ r2<- BB
4040    GET_VREG(r1, r3)                    @ r1<- vCC
4041    GET_VREG(r0, r2)                    @ r0<- vBB
4042    .if 0
4043    cmp     r1, #0                      @ is second operand zero?
4044    beq     common_errDivideByZero
4045    .endif
4046
4047    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4048                               @ optional op; may set condition codes
4049    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
4050    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4051    SET_VREG(r0, r9)               @ vAA<- r0
4052    GOTO_OPCODE(ip)                     @ jump to next instruction
4053    /* 11-14 instructions */
4054
4055
4056/* ------------------------------ */
4057    .balign 64
4058.L_OP_DIV_INT: /* 0x93 */
4059/* File: armv5te/OP_DIV_INT.S */
4060/* File: armv5te/binop.S */
4061    /*
4062     * Generic 32-bit binary operation.  Provide an "instr" line that
4063     * specifies an instruction that performs "result = r0 op r1".
4064     * This could be an ARM instruction or a function call.  (If the result
4065     * comes back in a register other than r0, you can override "result".)
4066     *
4067     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4068     * vCC (r1).  Useful for integer division and modulus.  Note that we
4069     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4070     * handles it correctly.
4071     *
4072     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4073     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4074     *      mul-float, div-float, rem-float
4075     */
4076    /* binop vAA, vBB, vCC */
4077    FETCH(r0, 1)                        @ r0<- CCBB
4078    mov     r9, rINST, lsr #8           @ r9<- AA
4079    mov     r3, r0, lsr #8              @ r3<- CC
4080    and     r2, r0, #255                @ r2<- BB
4081    GET_VREG(r1, r3)                    @ r1<- vCC
4082    GET_VREG(r0, r2)                    @ r0<- vBB
4083    .if 1
4084    cmp     r1, #0                      @ is second operand zero?
4085    beq     common_errDivideByZero
4086    .endif
4087
4088    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4089                               @ optional op; may set condition codes
4090    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
4091    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4092    SET_VREG(r0, r9)               @ vAA<- r0
4093    GOTO_OPCODE(ip)                     @ jump to next instruction
4094    /* 11-14 instructions */
4095
4096
4097/* ------------------------------ */
4098    .balign 64
4099.L_OP_REM_INT: /* 0x94 */
4100/* File: armv5te/OP_REM_INT.S */
4101/* idivmod returns quotient in r0 and remainder in r1 */
4102/* File: armv5te/binop.S */
4103    /*
4104     * Generic 32-bit binary operation.  Provide an "instr" line that
4105     * specifies an instruction that performs "result = r0 op r1".
4106     * This could be an ARM instruction or a function call.  (If the result
4107     * comes back in a register other than r0, you can override "result".)
4108     *
4109     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4110     * vCC (r1).  Useful for integer division and modulus.  Note that we
4111     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4112     * handles it correctly.
4113     *
4114     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4115     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4116     *      mul-float, div-float, rem-float
4117     */
4118    /* binop vAA, vBB, vCC */
4119    FETCH(r0, 1)                        @ r0<- CCBB
4120    mov     r9, rINST, lsr #8           @ r9<- AA
4121    mov     r3, r0, lsr #8              @ r3<- CC
4122    and     r2, r0, #255                @ r2<- BB
4123    GET_VREG(r1, r3)                    @ r1<- vCC
4124    GET_VREG(r0, r2)                    @ r0<- vBB
4125    .if 1
4126    cmp     r1, #0                      @ is second operand zero?
4127    beq     common_errDivideByZero
4128    .endif
4129
4130    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4131                               @ optional op; may set condition codes
4132    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
4133    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4134    SET_VREG(r1, r9)               @ vAA<- r1
4135    GOTO_OPCODE(ip)                     @ jump to next instruction
4136    /* 11-14 instructions */
4137
4138
4139/* ------------------------------ */
4140    .balign 64
4141.L_OP_AND_INT: /* 0x95 */
4142/* File: armv5te/OP_AND_INT.S */
4143/* File: armv5te/binop.S */
4144    /*
4145     * Generic 32-bit binary operation.  Provide an "instr" line that
4146     * specifies an instruction that performs "result = r0 op r1".
4147     * This could be an ARM instruction or a function call.  (If the result
4148     * comes back in a register other than r0, you can override "result".)
4149     *
4150     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4151     * vCC (r1).  Useful for integer division and modulus.  Note that we
4152     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4153     * handles it correctly.
4154     *
4155     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4156     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4157     *      mul-float, div-float, rem-float
4158     */
4159    /* binop vAA, vBB, vCC */
4160    FETCH(r0, 1)                        @ r0<- CCBB
4161    mov     r9, rINST, lsr #8           @ r9<- AA
4162    mov     r3, r0, lsr #8              @ r3<- CC
4163    and     r2, r0, #255                @ r2<- BB
4164    GET_VREG(r1, r3)                    @ r1<- vCC
4165    GET_VREG(r0, r2)                    @ r0<- vBB
4166    .if 0
4167    cmp     r1, #0                      @ is second operand zero?
4168    beq     common_errDivideByZero
4169    .endif
4170
4171    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4172                               @ optional op; may set condition codes
4173    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
4174    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4175    SET_VREG(r0, r9)               @ vAA<- r0
4176    GOTO_OPCODE(ip)                     @ jump to next instruction
4177    /* 11-14 instructions */
4178
4179
4180/* ------------------------------ */
4181    .balign 64
4182.L_OP_OR_INT: /* 0x96 */
4183/* File: armv5te/OP_OR_INT.S */
4184/* File: armv5te/binop.S */
4185    /*
4186     * Generic 32-bit binary operation.  Provide an "instr" line that
4187     * specifies an instruction that performs "result = r0 op r1".
4188     * This could be an ARM instruction or a function call.  (If the result
4189     * comes back in a register other than r0, you can override "result".)
4190     *
4191     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4192     * vCC (r1).  Useful for integer division and modulus.  Note that we
4193     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4194     * handles it correctly.
4195     *
4196     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4197     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4198     *      mul-float, div-float, rem-float
4199     */
4200    /* binop vAA, vBB, vCC */
4201    FETCH(r0, 1)                        @ r0<- CCBB
4202    mov     r9, rINST, lsr #8           @ r9<- AA
4203    mov     r3, r0, lsr #8              @ r3<- CC
4204    and     r2, r0, #255                @ r2<- BB
4205    GET_VREG(r1, r3)                    @ r1<- vCC
4206    GET_VREG(r0, r2)                    @ r0<- vBB
4207    .if 0
4208    cmp     r1, #0                      @ is second operand zero?
4209    beq     common_errDivideByZero
4210    .endif
4211
4212    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4213                               @ optional op; may set condition codes
4214    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
4215    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4216    SET_VREG(r0, r9)               @ vAA<- r0
4217    GOTO_OPCODE(ip)                     @ jump to next instruction
4218    /* 11-14 instructions */
4219
4220
4221/* ------------------------------ */
4222    .balign 64
4223.L_OP_XOR_INT: /* 0x97 */
4224/* File: armv5te/OP_XOR_INT.S */
4225/* File: armv5te/binop.S */
4226    /*
4227     * Generic 32-bit binary operation.  Provide an "instr" line that
4228     * specifies an instruction that performs "result = r0 op r1".
4229     * This could be an ARM instruction or a function call.  (If the result
4230     * comes back in a register other than r0, you can override "result".)
4231     *
4232     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4233     * vCC (r1).  Useful for integer division and modulus.  Note that we
4234     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4235     * handles it correctly.
4236     *
4237     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4238     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4239     *      mul-float, div-float, rem-float
4240     */
4241    /* binop vAA, vBB, vCC */
4242    FETCH(r0, 1)                        @ r0<- CCBB
4243    mov     r9, rINST, lsr #8           @ r9<- AA
4244    mov     r3, r0, lsr #8              @ r3<- CC
4245    and     r2, r0, #255                @ r2<- BB
4246    GET_VREG(r1, r3)                    @ r1<- vCC
4247    GET_VREG(r0, r2)                    @ r0<- vBB
4248    .if 0
4249    cmp     r1, #0                      @ is second operand zero?
4250    beq     common_errDivideByZero
4251    .endif
4252
4253    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4254                               @ optional op; may set condition codes
4255    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
4256    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4257    SET_VREG(r0, r9)               @ vAA<- r0
4258    GOTO_OPCODE(ip)                     @ jump to next instruction
4259    /* 11-14 instructions */
4260
4261
4262/* ------------------------------ */
4263    .balign 64
4264.L_OP_SHL_INT: /* 0x98 */
4265/* File: armv5te/OP_SHL_INT.S */
4266/* File: armv5te/binop.S */
4267    /*
4268     * Generic 32-bit binary operation.  Provide an "instr" line that
4269     * specifies an instruction that performs "result = r0 op r1".
4270     * This could be an ARM instruction or a function call.  (If the result
4271     * comes back in a register other than r0, you can override "result".)
4272     *
4273     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4274     * vCC (r1).  Useful for integer division and modulus.  Note that we
4275     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4276     * handles it correctly.
4277     *
4278     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4279     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4280     *      mul-float, div-float, rem-float
4281     */
4282    /* binop vAA, vBB, vCC */
4283    FETCH(r0, 1)                        @ r0<- CCBB
4284    mov     r9, rINST, lsr #8           @ r9<- AA
4285    mov     r3, r0, lsr #8              @ r3<- CC
4286    and     r2, r0, #255                @ r2<- BB
4287    GET_VREG(r1, r3)                    @ r1<- vCC
4288    GET_VREG(r0, r2)                    @ r0<- vBB
4289    .if 0
4290    cmp     r1, #0                      @ is second operand zero?
4291    beq     common_errDivideByZero
4292    .endif
4293
4294    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4295    and     r1, r1, #31                           @ optional op; may set condition codes
4296    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
4297    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4298    SET_VREG(r0, r9)               @ vAA<- r0
4299    GOTO_OPCODE(ip)                     @ jump to next instruction
4300    /* 11-14 instructions */
4301
4302
4303/* ------------------------------ */
4304    .balign 64
4305.L_OP_SHR_INT: /* 0x99 */
4306/* File: armv5te/OP_SHR_INT.S */
4307/* File: armv5te/binop.S */
4308    /*
4309     * Generic 32-bit binary operation.  Provide an "instr" line that
4310     * specifies an instruction that performs "result = r0 op r1".
4311     * This could be an ARM instruction or a function call.  (If the result
4312     * comes back in a register other than r0, you can override "result".)
4313     *
4314     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4315     * vCC (r1).  Useful for integer division and modulus.  Note that we
4316     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4317     * handles it correctly.
4318     *
4319     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4320     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4321     *      mul-float, div-float, rem-float
4322     */
4323    /* binop vAA, vBB, vCC */
4324    FETCH(r0, 1)                        @ r0<- CCBB
4325    mov     r9, rINST, lsr #8           @ r9<- AA
4326    mov     r3, r0, lsr #8              @ r3<- CC
4327    and     r2, r0, #255                @ r2<- BB
4328    GET_VREG(r1, r3)                    @ r1<- vCC
4329    GET_VREG(r0, r2)                    @ r0<- vBB
4330    .if 0
4331    cmp     r1, #0                      @ is second operand zero?
4332    beq     common_errDivideByZero
4333    .endif
4334
4335    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4336    and     r1, r1, #31                           @ optional op; may set condition codes
4337    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
4338    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4339    SET_VREG(r0, r9)               @ vAA<- r0
4340    GOTO_OPCODE(ip)                     @ jump to next instruction
4341    /* 11-14 instructions */
4342
4343
4344/* ------------------------------ */
4345    .balign 64
4346.L_OP_USHR_INT: /* 0x9a */
4347/* File: armv5te/OP_USHR_INT.S */
4348/* File: armv5te/binop.S */
4349    /*
4350     * Generic 32-bit binary operation.  Provide an "instr" line that
4351     * specifies an instruction that performs "result = r0 op r1".
4352     * This could be an ARM instruction or a function call.  (If the result
4353     * comes back in a register other than r0, you can override "result".)
4354     *
4355     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4356     * vCC (r1).  Useful for integer division and modulus.  Note that we
4357     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4358     * handles it correctly.
4359     *
4360     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4361     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4362     *      mul-float, div-float, rem-float
4363     */
4364    /* binop vAA, vBB, vCC */
4365    FETCH(r0, 1)                        @ r0<- CCBB
4366    mov     r9, rINST, lsr #8           @ r9<- AA
4367    mov     r3, r0, lsr #8              @ r3<- CC
4368    and     r2, r0, #255                @ r2<- BB
4369    GET_VREG(r1, r3)                    @ r1<- vCC
4370    GET_VREG(r0, r2)                    @ r0<- vBB
4371    .if 0
4372    cmp     r1, #0                      @ is second operand zero?
4373    beq     common_errDivideByZero
4374    .endif
4375
4376    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4377    and     r1, r1, #31                           @ optional op; may set condition codes
4378    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
4379    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4380    SET_VREG(r0, r9)               @ vAA<- r0
4381    GOTO_OPCODE(ip)                     @ jump to next instruction
4382    /* 11-14 instructions */
4383
4384
4385/* ------------------------------ */
4386    .balign 64
4387.L_OP_ADD_LONG: /* 0x9b */
4388/* File: armv5te/OP_ADD_LONG.S */
4389/* File: armv5te/binopWide.S */
4390    /*
4391     * Generic 64-bit binary operation.  Provide an "instr" line that
4392     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4393     * This could be an ARM instruction or a function call.  (If the result
4394     * comes back in a register other than r0, you can override "result".)
4395     *
4396     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4397     * vCC (r1).  Useful for integer division and modulus.
4398     *
4399     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4400     *      xor-long, add-double, sub-double, mul-double, div-double,
4401     *      rem-double
4402     *
4403     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4404     */
4405    /* binop vAA, vBB, vCC */
4406    FETCH(r0, 1)                        @ r0<- CCBB
4407    mov     r9, rINST, lsr #8           @ r9<- AA
4408    and     r2, r0, #255                @ r2<- BB
4409    mov     r3, r0, lsr #8              @ r3<- CC
4410    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4411    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4412    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4413    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4414    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4415    .if 0
4416    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4417    beq     common_errDivideByZero
4418    .endif
4419    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4420
4421    adds    r0, r0, r2                           @ optional op; may set condition codes
4422    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
4423    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4424    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4425    GOTO_OPCODE(ip)                     @ jump to next instruction
4426    /* 14-17 instructions */
4427
4428
4429/* ------------------------------ */
4430    .balign 64
4431.L_OP_SUB_LONG: /* 0x9c */
4432/* File: armv5te/OP_SUB_LONG.S */
4433/* File: armv5te/binopWide.S */
4434    /*
4435     * Generic 64-bit binary operation.  Provide an "instr" line that
4436     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4437     * This could be an ARM instruction or a function call.  (If the result
4438     * comes back in a register other than r0, you can override "result".)
4439     *
4440     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4441     * vCC (r1).  Useful for integer division and modulus.
4442     *
4443     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4444     *      xor-long, add-double, sub-double, mul-double, div-double,
4445     *      rem-double
4446     *
4447     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4448     */
4449    /* binop vAA, vBB, vCC */
4450    FETCH(r0, 1)                        @ r0<- CCBB
4451    mov     r9, rINST, lsr #8           @ r9<- AA
4452    and     r2, r0, #255                @ r2<- BB
4453    mov     r3, r0, lsr #8              @ r3<- CC
4454    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4455    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4456    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4457    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4458    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4459    .if 0
4460    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4461    beq     common_errDivideByZero
4462    .endif
4463    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4464
4465    subs    r0, r0, r2                           @ optional op; may set condition codes
4466    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
4467    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4468    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4469    GOTO_OPCODE(ip)                     @ jump to next instruction
4470    /* 14-17 instructions */
4471
4472
4473/* ------------------------------ */
4474    .balign 64
4475.L_OP_MUL_LONG: /* 0x9d */
4476/* File: armv5te/OP_MUL_LONG.S */
4477    /*
4478     * Signed 64-bit integer multiply.
4479     *
4480     * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
4481     *        WX
4482     *      x YZ
4483     *  --------
4484     *     ZW ZX
4485     *  YW YX
4486     *
4487     * The low word of the result holds ZX, the high word holds
4488     * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
4489     * it doesn't fit in the low 64 bits.
4490     *
4491     * Unlike most ARM math operations, multiply instructions have
4492     * restrictions on using the same register more than once (Rd and Rm
4493     * cannot be the same).
4494     */
4495    /* mul-long vAA, vBB, vCC */
4496    FETCH(r0, 1)                        @ r0<- CCBB
4497    and     r2, r0, #255                @ r2<- BB
4498    mov     r3, r0, lsr #8              @ r3<- CC
4499    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4500    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4501    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4502    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4503    mul     ip, r2, r1                  @  ip<- ZxW
4504    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
4505    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
4506    mov     r0, rINST, lsr #8           @ r0<- AA
4507    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
4508    add     r0, rFP, r0, lsl #2         @ r0<- &fp[AA]
4509    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4510    b       .LOP_MUL_LONG_finish
4511
4512/* ------------------------------ */
4513    .balign 64
4514.L_OP_DIV_LONG: /* 0x9e */
4515/* File: armv5te/OP_DIV_LONG.S */
4516/* File: armv5te/binopWide.S */
4517    /*
4518     * Generic 64-bit binary operation.  Provide an "instr" line that
4519     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4520     * This could be an ARM instruction or a function call.  (If the result
4521     * comes back in a register other than r0, you can override "result".)
4522     *
4523     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4524     * vCC (r1).  Useful for integer division and modulus.
4525     *
4526     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4527     *      xor-long, add-double, sub-double, mul-double, div-double,
4528     *      rem-double
4529     *
4530     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4531     */
4532    /* binop vAA, vBB, vCC */
4533    FETCH(r0, 1)                        @ r0<- CCBB
4534    mov     r9, rINST, lsr #8           @ r9<- AA
4535    and     r2, r0, #255                @ r2<- BB
4536    mov     r3, r0, lsr #8              @ r3<- CC
4537    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4538    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4539    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4540    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4541    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4542    .if 1
4543    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4544    beq     common_errDivideByZero
4545    .endif
4546    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4547
4548                               @ optional op; may set condition codes
4549    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4550    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4551    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4552    GOTO_OPCODE(ip)                     @ jump to next instruction
4553    /* 14-17 instructions */
4554
4555
4556/* ------------------------------ */
4557    .balign 64
4558.L_OP_REM_LONG: /* 0x9f */
4559/* File: armv5te/OP_REM_LONG.S */
4560/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
4561/* File: armv5te/binopWide.S */
4562    /*
4563     * Generic 64-bit binary operation.  Provide an "instr" line that
4564     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4565     * This could be an ARM instruction or a function call.  (If the result
4566     * comes back in a register other than r0, you can override "result".)
4567     *
4568     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4569     * vCC (r1).  Useful for integer division and modulus.
4570     *
4571     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4572     *      xor-long, add-double, sub-double, mul-double, div-double,
4573     *      rem-double
4574     *
4575     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4576     */
4577    /* binop vAA, vBB, vCC */
4578    FETCH(r0, 1)                        @ r0<- CCBB
4579    mov     r9, rINST, lsr #8           @ r9<- AA
4580    and     r2, r0, #255                @ r2<- BB
4581    mov     r3, r0, lsr #8              @ r3<- CC
4582    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4583    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4584    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4585    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4586    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4587    .if 1
4588    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4589    beq     common_errDivideByZero
4590    .endif
4591    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4592
4593                               @ optional op; may set condition codes
4594    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4595    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4596    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
4597    GOTO_OPCODE(ip)                     @ jump to next instruction
4598    /* 14-17 instructions */
4599
4600
4601/* ------------------------------ */
4602    .balign 64
4603.L_OP_AND_LONG: /* 0xa0 */
4604/* File: armv5te/OP_AND_LONG.S */
4605/* File: armv5te/binopWide.S */
4606    /*
4607     * Generic 64-bit binary operation.  Provide an "instr" line that
4608     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4609     * This could be an ARM instruction or a function call.  (If the result
4610     * comes back in a register other than r0, you can override "result".)
4611     *
4612     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4613     * vCC (r1).  Useful for integer division and modulus.
4614     *
4615     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4616     *      xor-long, add-double, sub-double, mul-double, div-double,
4617     *      rem-double
4618     *
4619     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4620     */
4621    /* binop vAA, vBB, vCC */
4622    FETCH(r0, 1)                        @ r0<- CCBB
4623    mov     r9, rINST, lsr #8           @ r9<- AA
4624    and     r2, r0, #255                @ r2<- BB
4625    mov     r3, r0, lsr #8              @ r3<- CC
4626    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4627    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4628    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4629    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4630    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4631    .if 0
4632    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4633    beq     common_errDivideByZero
4634    .endif
4635    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4636
4637    and     r0, r0, r2                           @ optional op; may set condition codes
4638    and     r1, r1, r3                              @ result<- op, r0-r3 changed
4639    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4640    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4641    GOTO_OPCODE(ip)                     @ jump to next instruction
4642    /* 14-17 instructions */
4643
4644
4645/* ------------------------------ */
4646    .balign 64
4647.L_OP_OR_LONG: /* 0xa1 */
4648/* File: armv5te/OP_OR_LONG.S */
4649/* File: armv5te/binopWide.S */
4650    /*
4651     * Generic 64-bit binary operation.  Provide an "instr" line that
4652     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4653     * This could be an ARM instruction or a function call.  (If the result
4654     * comes back in a register other than r0, you can override "result".)
4655     *
4656     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4657     * vCC (r1).  Useful for integer division and modulus.
4658     *
4659     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4660     *      xor-long, add-double, sub-double, mul-double, div-double,
4661     *      rem-double
4662     *
4663     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4664     */
4665    /* binop vAA, vBB, vCC */
4666    FETCH(r0, 1)                        @ r0<- CCBB
4667    mov     r9, rINST, lsr #8           @ r9<- AA
4668    and     r2, r0, #255                @ r2<- BB
4669    mov     r3, r0, lsr #8              @ r3<- CC
4670    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4671    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4672    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4673    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4674    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4675    .if 0
4676    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4677    beq     common_errDivideByZero
4678    .endif
4679    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4680
4681    orr     r0, r0, r2                           @ optional op; may set condition codes
4682    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
4683    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4684    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4685    GOTO_OPCODE(ip)                     @ jump to next instruction
4686    /* 14-17 instructions */
4687
4688
4689/* ------------------------------ */
4690    .balign 64
4691.L_OP_XOR_LONG: /* 0xa2 */
4692/* File: armv5te/OP_XOR_LONG.S */
4693/* File: armv5te/binopWide.S */
4694    /*
4695     * Generic 64-bit binary operation.  Provide an "instr" line that
4696     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4697     * This could be an ARM instruction or a function call.  (If the result
4698     * comes back in a register other than r0, you can override "result".)
4699     *
4700     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4701     * vCC (r1).  Useful for integer division and modulus.
4702     *
4703     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4704     *      xor-long, add-double, sub-double, mul-double, div-double,
4705     *      rem-double
4706     *
4707     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4708     */
4709    /* binop vAA, vBB, vCC */
4710    FETCH(r0, 1)                        @ r0<- CCBB
4711    mov     r9, rINST, lsr #8           @ r9<- AA
4712    and     r2, r0, #255                @ r2<- BB
4713    mov     r3, r0, lsr #8              @ r3<- CC
4714    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4715    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4716    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4717    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4718    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4719    .if 0
4720    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4721    beq     common_errDivideByZero
4722    .endif
4723    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4724
4725    eor     r0, r0, r2                           @ optional op; may set condition codes
4726    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
4727    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4728    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4729    GOTO_OPCODE(ip)                     @ jump to next instruction
4730    /* 14-17 instructions */
4731
4732
4733/* ------------------------------ */
4734    .balign 64
4735.L_OP_SHL_LONG: /* 0xa3 */
4736/* File: armv5te/OP_SHL_LONG.S */
4737    /*
4738     * Long integer shift.  This is different from the generic 32/64-bit
4739     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4740     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4741     * 6 bits of the shift distance.
4742     */
4743    /* shl-long vAA, vBB, vCC */
4744    FETCH(r0, 1)                        @ r0<- CCBB
4745    mov     r9, rINST, lsr #8           @ r9<- AA
4746    and     r3, r0, #255                @ r3<- BB
4747    mov     r0, r0, lsr #8              @ r0<- CC
4748    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4749    GET_VREG(r2, r0)                    @ r2<- vCC
4750    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4751    and     r2, r2, #63                 @ r2<- r2 & 0x3f
4752    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4753
4754    mov     r1, r1, asl r2              @  r1<- r1 << r2
4755    rsb     r3, r2, #32                 @  r3<- 32 - r2
4756    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
4757    subs    ip, r2, #32                 @  ip<- r2 - 32
4758    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
4759    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4760    b       .LOP_SHL_LONG_finish
4761
4762/* ------------------------------ */
4763    .balign 64
4764.L_OP_SHR_LONG: /* 0xa4 */
4765/* File: armv5te/OP_SHR_LONG.S */
4766    /*
4767     * Long integer shift.  This is different from the generic 32/64-bit
4768     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4769     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4770     * 6 bits of the shift distance.
4771     */
4772    /* shr-long vAA, vBB, vCC */
4773    FETCH(r0, 1)                        @ r0<- CCBB
4774    mov     r9, rINST, lsr #8           @ r9<- AA
4775    and     r3, r0, #255                @ r3<- BB
4776    mov     r0, r0, lsr #8              @ r0<- CC
4777    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4778    GET_VREG(r2, r0)                    @ r2<- vCC
4779    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4780    and     r2, r2, #63                 @ r0<- r0 & 0x3f
4781    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4782
4783    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
4784    rsb     r3, r2, #32                 @  r3<- 32 - r2
4785    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
4786    subs    ip, r2, #32                 @  ip<- r2 - 32
4787    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
4788    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4789    b       .LOP_SHR_LONG_finish
4790
4791/* ------------------------------ */
4792    .balign 64
4793.L_OP_USHR_LONG: /* 0xa5 */
4794/* File: armv5te/OP_USHR_LONG.S */
4795    /*
4796     * Long integer shift.  This is different from the generic 32/64-bit
4797     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4798     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4799     * 6 bits of the shift distance.
4800     */
4801    /* ushr-long vAA, vBB, vCC */
4802    FETCH(r0, 1)                        @ r0<- CCBB
4803    mov     r9, rINST, lsr #8           @ r9<- AA
4804    and     r3, r0, #255                @ r3<- BB
4805    mov     r0, r0, lsr #8              @ r0<- CC
4806    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4807    GET_VREG(r2, r0)                    @ r2<- vCC
4808    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4809    and     r2, r2, #63                 @ r0<- r0 & 0x3f
4810    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4811
4812    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
4813    rsb     r3, r2, #32                 @  r3<- 32 - r2
4814    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
4815    subs    ip, r2, #32                 @  ip<- r2 - 32
4816    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
4817    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4818    b       .LOP_USHR_LONG_finish
4819
4820/* ------------------------------ */
4821    .balign 64
4822.L_OP_ADD_FLOAT: /* 0xa6 */
4823/* File: arm-vfp/OP_ADD_FLOAT.S */
4824/* File: arm-vfp/fbinop.S */
4825    /*
4826     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4827     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4828     * use the "softfp" ABI, this must be an instruction, not a function call.
4829     *
4830     * For: add-float, sub-float, mul-float, div-float
4831     */
4832    /* floatop vAA, vBB, vCC */
4833    FETCH(r0, 1)                        @ r0<- CCBB
4834    mov     r9, rINST, lsr #8           @ r9<- AA
4835    mov     r3, r0, lsr #8              @ r3<- CC
4836    and     r2, r0, #255                @ r2<- BB
4837    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4838    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4839    flds    s1, [r3]                    @ s1<- vCC
4840    flds    s0, [r2]                    @ s0<- vBB
4841
4842    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4843    fadds   s2, s0, s1                              @ s2<- op
4844    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4845    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4846    fsts    s2, [r9]                    @ vAA<- s2
4847    GOTO_OPCODE(ip)                     @ jump to next instruction
4848
4849
4850/* ------------------------------ */
4851    .balign 64
4852.L_OP_SUB_FLOAT: /* 0xa7 */
4853/* File: arm-vfp/OP_SUB_FLOAT.S */
4854/* File: arm-vfp/fbinop.S */
4855    /*
4856     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4857     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4858     * use the "softfp" ABI, this must be an instruction, not a function call.
4859     *
4860     * For: add-float, sub-float, mul-float, div-float
4861     */
4862    /* floatop vAA, vBB, vCC */
4863    FETCH(r0, 1)                        @ r0<- CCBB
4864    mov     r9, rINST, lsr #8           @ r9<- AA
4865    mov     r3, r0, lsr #8              @ r3<- CC
4866    and     r2, r0, #255                @ r2<- BB
4867    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4868    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4869    flds    s1, [r3]                    @ s1<- vCC
4870    flds    s0, [r2]                    @ s0<- vBB
4871
4872    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4873    fsubs   s2, s0, s1                              @ s2<- op
4874    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4875    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4876    fsts    s2, [r9]                    @ vAA<- s2
4877    GOTO_OPCODE(ip)                     @ jump to next instruction
4878
4879
4880/* ------------------------------ */
4881    .balign 64
4882.L_OP_MUL_FLOAT: /* 0xa8 */
4883/* File: arm-vfp/OP_MUL_FLOAT.S */
4884/* File: arm-vfp/fbinop.S */
4885    /*
4886     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4887     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4888     * use the "softfp" ABI, this must be an instruction, not a function call.
4889     *
4890     * For: add-float, sub-float, mul-float, div-float
4891     */
4892    /* floatop vAA, vBB, vCC */
4893    FETCH(r0, 1)                        @ r0<- CCBB
4894    mov     r9, rINST, lsr #8           @ r9<- AA
4895    mov     r3, r0, lsr #8              @ r3<- CC
4896    and     r2, r0, #255                @ r2<- BB
4897    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4898    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4899    flds    s1, [r3]                    @ s1<- vCC
4900    flds    s0, [r2]                    @ s0<- vBB
4901
4902    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4903    fmuls   s2, s0, s1                              @ s2<- op
4904    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4905    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4906    fsts    s2, [r9]                    @ vAA<- s2
4907    GOTO_OPCODE(ip)                     @ jump to next instruction
4908
4909
4910/* ------------------------------ */
4911    .balign 64
4912.L_OP_DIV_FLOAT: /* 0xa9 */
4913/* File: arm-vfp/OP_DIV_FLOAT.S */
4914/* File: arm-vfp/fbinop.S */
4915    /*
4916     * Generic 32-bit floating-point operation.  Provide an "instr" line that
4917     * specifies an instruction that performs "s2 = s0 op s1".  Because we
4918     * use the "softfp" ABI, this must be an instruction, not a function call.
4919     *
4920     * For: add-float, sub-float, mul-float, div-float
4921     */
4922    /* floatop vAA, vBB, vCC */
4923    FETCH(r0, 1)                        @ r0<- CCBB
4924    mov     r9, rINST, lsr #8           @ r9<- AA
4925    mov     r3, r0, lsr #8              @ r3<- CC
4926    and     r2, r0, #255                @ r2<- BB
4927    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
4928    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
4929    flds    s1, [r3]                    @ s1<- vCC
4930    flds    s0, [r2]                    @ s0<- vBB
4931
4932    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4933    fdivs   s2, s0, s1                              @ s2<- op
4934    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4935    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
4936    fsts    s2, [r9]                    @ vAA<- s2
4937    GOTO_OPCODE(ip)                     @ jump to next instruction
4938
4939
4940/* ------------------------------ */
4941    .balign 64
4942.L_OP_REM_FLOAT: /* 0xaa */
4943/* File: armv5te/OP_REM_FLOAT.S */
4944/* EABI doesn't define a float remainder function, but libm does */
4945/* File: armv5te/binop.S */
4946    /*
4947     * Generic 32-bit binary operation.  Provide an "instr" line that
4948     * specifies an instruction that performs "result = r0 op r1".
4949     * This could be an ARM instruction or a function call.  (If the result
4950     * comes back in a register other than r0, you can override "result".)
4951     *
4952     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4953     * vCC (r1).  Useful for integer division and modulus.  Note that we
4954     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4955     * handles it correctly.
4956     *
4957     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4958     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4959     *      mul-float, div-float, rem-float
4960     */
4961    /* binop vAA, vBB, vCC */
4962    FETCH(r0, 1)                        @ r0<- CCBB
4963    mov     r9, rINST, lsr #8           @ r9<- AA
4964    mov     r3, r0, lsr #8              @ r3<- CC
4965    and     r2, r0, #255                @ r2<- BB
4966    GET_VREG(r1, r3)                    @ r1<- vCC
4967    GET_VREG(r0, r2)                    @ r0<- vBB
4968    .if 0
4969    cmp     r1, #0                      @ is second operand zero?
4970    beq     common_errDivideByZero
4971    .endif
4972
4973    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4974                               @ optional op; may set condition codes
4975    bl      fmodf                              @ r0<- op, r0-r3 changed
4976    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4977    SET_VREG(r0, r9)               @ vAA<- r0
4978    GOTO_OPCODE(ip)                     @ jump to next instruction
4979    /* 11-14 instructions */
4980
4981
4982/* ------------------------------ */
4983    .balign 64
4984.L_OP_ADD_DOUBLE: /* 0xab */
4985/* File: arm-vfp/OP_ADD_DOUBLE.S */
4986/* File: arm-vfp/fbinopWide.S */
4987    /*
4988     * Generic 64-bit double-precision floating point binary operation.
4989     * Provide an "instr" line that specifies an instruction that performs
4990     * "d2 = d0 op d1".
4991     *
4992     * for: add-double, sub-double, mul-double, div-double
4993     */
4994    /* doubleop vAA, vBB, vCC */
4995    FETCH(r0, 1)                        @ r0<- CCBB
4996    mov     r9, rINST, lsr #8           @ r9<- AA
4997    mov     r3, r0, lsr #8              @ r3<- CC
4998    and     r2, r0, #255                @ r2<- BB
4999    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5000    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5001    fldd    d1, [r3]                    @ d1<- vCC
5002    fldd    d0, [r2]                    @ d0<- vBB
5003
5004    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5005    faddd   d2, d0, d1                              @ s2<- op
5006    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5007    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5008    fstd    d2, [r9]                    @ vAA<- d2
5009    GOTO_OPCODE(ip)                     @ jump to next instruction
5010
5011
5012/* ------------------------------ */
5013    .balign 64
5014.L_OP_SUB_DOUBLE: /* 0xac */
5015/* File: arm-vfp/OP_SUB_DOUBLE.S */
5016/* File: arm-vfp/fbinopWide.S */
5017    /*
5018     * Generic 64-bit double-precision floating point binary operation.
5019     * Provide an "instr" line that specifies an instruction that performs
5020     * "d2 = d0 op d1".
5021     *
5022     * for: add-double, sub-double, mul-double, div-double
5023     */
5024    /* doubleop vAA, vBB, vCC */
5025    FETCH(r0, 1)                        @ r0<- CCBB
5026    mov     r9, rINST, lsr #8           @ r9<- AA
5027    mov     r3, r0, lsr #8              @ r3<- CC
5028    and     r2, r0, #255                @ r2<- BB
5029    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5030    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5031    fldd    d1, [r3]                    @ d1<- vCC
5032    fldd    d0, [r2]                    @ d0<- vBB
5033
5034    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5035    fsubd   d2, d0, d1                              @ s2<- op
5036    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5037    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5038    fstd    d2, [r9]                    @ vAA<- d2
5039    GOTO_OPCODE(ip)                     @ jump to next instruction
5040
5041
5042/* ------------------------------ */
5043    .balign 64
5044.L_OP_MUL_DOUBLE: /* 0xad */
5045/* File: arm-vfp/OP_MUL_DOUBLE.S */
5046/* File: arm-vfp/fbinopWide.S */
5047    /*
5048     * Generic 64-bit double-precision floating point binary operation.
5049     * Provide an "instr" line that specifies an instruction that performs
5050     * "d2 = d0 op d1".
5051     *
5052     * for: add-double, sub-double, mul-double, div-double
5053     */
5054    /* doubleop vAA, vBB, vCC */
5055    FETCH(r0, 1)                        @ r0<- CCBB
5056    mov     r9, rINST, lsr #8           @ r9<- AA
5057    mov     r3, r0, lsr #8              @ r3<- CC
5058    and     r2, r0, #255                @ r2<- BB
5059    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5060    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5061    fldd    d1, [r3]                    @ d1<- vCC
5062    fldd    d0, [r2]                    @ d0<- vBB
5063
5064    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5065    fmuld   d2, d0, d1                              @ s2<- op
5066    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5067    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5068    fstd    d2, [r9]                    @ vAA<- d2
5069    GOTO_OPCODE(ip)                     @ jump to next instruction
5070
5071
5072/* ------------------------------ */
5073    .balign 64
5074.L_OP_DIV_DOUBLE: /* 0xae */
5075/* File: arm-vfp/OP_DIV_DOUBLE.S */
5076/* File: arm-vfp/fbinopWide.S */
5077    /*
5078     * Generic 64-bit double-precision floating point binary operation.
5079     * Provide an "instr" line that specifies an instruction that performs
5080     * "d2 = d0 op d1".
5081     *
5082     * for: add-double, sub-double, mul-double, div-double
5083     */
5084    /* doubleop vAA, vBB, vCC */
5085    FETCH(r0, 1)                        @ r0<- CCBB
5086    mov     r9, rINST, lsr #8           @ r9<- AA
5087    mov     r3, r0, lsr #8              @ r3<- CC
5088    and     r2, r0, #255                @ r2<- BB
5089    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vCC
5090    VREG_INDEX_TO_ADDR(r2, r2)          @ r2<- &vBB
5091    fldd    d1, [r3]                    @ d1<- vCC
5092    fldd    d0, [r2]                    @ d0<- vBB
5093
5094    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5095    fdivd   d2, d0, d1                              @ s2<- op
5096    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5097    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vAA
5098    fstd    d2, [r9]                    @ vAA<- d2
5099    GOTO_OPCODE(ip)                     @ jump to next instruction
5100
5101
5102/* ------------------------------ */
5103    .balign 64
5104.L_OP_REM_DOUBLE: /* 0xaf */
5105/* File: armv5te/OP_REM_DOUBLE.S */
5106/* EABI doesn't define a double remainder function, but libm does */
5107/* File: armv5te/binopWide.S */
5108    /*
5109     * Generic 64-bit binary operation.  Provide an "instr" line that
5110     * specifies an instruction that performs "result = r0-r1 op r2-r3".
5111     * This could be an ARM instruction or a function call.  (If the result
5112     * comes back in a register other than r0, you can override "result".)
5113     *
5114     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5115     * vCC (r1).  Useful for integer division and modulus.
5116     *
5117     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
5118     *      xor-long, add-double, sub-double, mul-double, div-double,
5119     *      rem-double
5120     *
5121     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
5122     */
5123    /* binop vAA, vBB, vCC */
5124    FETCH(r0, 1)                        @ r0<- CCBB
5125    mov     r9, rINST, lsr #8           @ r9<- AA
5126    and     r2, r0, #255                @ r2<- BB
5127    mov     r3, r0, lsr #8              @ r3<- CC
5128    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5129    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
5130    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
5131    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5132    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
5133    .if 0
5134    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5135    beq     common_errDivideByZero
5136    .endif
5137    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5138
5139                               @ optional op; may set condition codes
5140    bl      fmod                              @ result<- op, r0-r3 changed
5141    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5142    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5143    GOTO_OPCODE(ip)                     @ jump to next instruction
5144    /* 14-17 instructions */
5145
5146
5147/* ------------------------------ */
5148    .balign 64
5149.L_OP_ADD_INT_2ADDR: /* 0xb0 */
5150/* File: armv6t2/OP_ADD_INT_2ADDR.S */
5151/* File: armv6t2/binop2addr.S */
5152    /*
5153     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5154     * that specifies an instruction that performs "result = r0 op r1".
5155     * This could be an ARM instruction or a function call.  (If the result
5156     * comes back in a register other than r0, you can override "result".)
5157     *
5158     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5159     * vCC (r1).  Useful for integer division and modulus.
5160     *
5161     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5162     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5163     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5164     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5165     */
5166    /* binop/2addr vA, vB */
5167    mov     r3, rINST, lsr #12          @ r3<- B
5168    ubfx    r9, rINST, #8, #4           @ r9<- A
5169    GET_VREG(r1, r3)                    @ r1<- vB
5170    GET_VREG(r0, r9)                    @ r0<- vA
5171    .if 0
5172    cmp     r1, #0                      @ is second operand zero?
5173    beq     common_errDivideByZero
5174    .endif
5175    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5176
5177                               @ optional op; may set condition codes
5178    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
5179    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5180    SET_VREG(r0, r9)               @ vAA<- r0
5181    GOTO_OPCODE(ip)                     @ jump to next instruction
5182    /* 10-13 instructions */
5183
5184
5185/* ------------------------------ */
5186    .balign 64
5187.L_OP_SUB_INT_2ADDR: /* 0xb1 */
5188/* File: armv6t2/OP_SUB_INT_2ADDR.S */
5189/* File: armv6t2/binop2addr.S */
5190    /*
5191     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5192     * that specifies an instruction that performs "result = r0 op r1".
5193     * This could be an ARM instruction or a function call.  (If the result
5194     * comes back in a register other than r0, you can override "result".)
5195     *
5196     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5197     * vCC (r1).  Useful for integer division and modulus.
5198     *
5199     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5200     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5201     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5202     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5203     */
5204    /* binop/2addr vA, vB */
5205    mov     r3, rINST, lsr #12          @ r3<- B
5206    ubfx    r9, rINST, #8, #4           @ r9<- A
5207    GET_VREG(r1, r3)                    @ r1<- vB
5208    GET_VREG(r0, r9)                    @ r0<- vA
5209    .if 0
5210    cmp     r1, #0                      @ is second operand zero?
5211    beq     common_errDivideByZero
5212    .endif
5213    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5214
5215                               @ optional op; may set condition codes
5216    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
5217    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5218    SET_VREG(r0, r9)               @ vAA<- r0
5219    GOTO_OPCODE(ip)                     @ jump to next instruction
5220    /* 10-13 instructions */
5221
5222
5223/* ------------------------------ */
5224    .balign 64
5225.L_OP_MUL_INT_2ADDR: /* 0xb2 */
5226/* File: armv6t2/OP_MUL_INT_2ADDR.S */
5227/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
5228/* File: armv6t2/binop2addr.S */
5229    /*
5230     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5231     * that specifies an instruction that performs "result = r0 op r1".
5232     * This could be an ARM instruction or a function call.  (If the result
5233     * comes back in a register other than r0, you can override "result".)
5234     *
5235     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5236     * vCC (r1).  Useful for integer division and modulus.
5237     *
5238     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5239     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5240     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5241     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5242     */
5243    /* binop/2addr vA, vB */
5244    mov     r3, rINST, lsr #12          @ r3<- B
5245    ubfx    r9, rINST, #8, #4           @ r9<- A
5246    GET_VREG(r1, r3)                    @ r1<- vB
5247    GET_VREG(r0, r9)                    @ r0<- vA
5248    .if 0
5249    cmp     r1, #0                      @ is second operand zero?
5250    beq     common_errDivideByZero
5251    .endif
5252    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5253
5254                               @ optional op; may set condition codes
5255    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
5256    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5257    SET_VREG(r0, r9)               @ vAA<- r0
5258    GOTO_OPCODE(ip)                     @ jump to next instruction
5259    /* 10-13 instructions */
5260
5261
5262/* ------------------------------ */
5263    .balign 64
5264.L_OP_DIV_INT_2ADDR: /* 0xb3 */
5265/* File: armv6t2/OP_DIV_INT_2ADDR.S */
5266/* File: armv6t2/binop2addr.S */
5267    /*
5268     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5269     * that specifies an instruction that performs "result = r0 op r1".
5270     * This could be an ARM instruction or a function call.  (If the result
5271     * comes back in a register other than r0, you can override "result".)
5272     *
5273     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5274     * vCC (r1).  Useful for integer division and modulus.
5275     *
5276     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5277     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5278     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5279     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5280     */
5281    /* binop/2addr vA, vB */
5282    mov     r3, rINST, lsr #12          @ r3<- B
5283    ubfx    r9, rINST, #8, #4           @ r9<- A
5284    GET_VREG(r1, r3)                    @ r1<- vB
5285    GET_VREG(r0, r9)                    @ r0<- vA
5286    .if 1
5287    cmp     r1, #0                      @ is second operand zero?
5288    beq     common_errDivideByZero
5289    .endif
5290    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5291
5292                               @ optional op; may set condition codes
5293    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
5294    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5295    SET_VREG(r0, r9)               @ vAA<- r0
5296    GOTO_OPCODE(ip)                     @ jump to next instruction
5297    /* 10-13 instructions */
5298
5299
5300/* ------------------------------ */
5301    .balign 64
5302.L_OP_REM_INT_2ADDR: /* 0xb4 */
5303/* File: armv6t2/OP_REM_INT_2ADDR.S */
5304/* idivmod returns quotient in r0 and remainder in r1 */
5305/* File: armv6t2/binop2addr.S */
5306    /*
5307     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5308     * that specifies an instruction that performs "result = r0 op r1".
5309     * This could be an ARM instruction or a function call.  (If the result
5310     * comes back in a register other than r0, you can override "result".)
5311     *
5312     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5313     * vCC (r1).  Useful for integer division and modulus.
5314     *
5315     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5316     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5317     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5318     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5319     */
5320    /* binop/2addr vA, vB */
5321    mov     r3, rINST, lsr #12          @ r3<- B
5322    ubfx    r9, rINST, #8, #4           @ r9<- A
5323    GET_VREG(r1, r3)                    @ r1<- vB
5324    GET_VREG(r0, r9)                    @ r0<- vA
5325    .if 1
5326    cmp     r1, #0                      @ is second operand zero?
5327    beq     common_errDivideByZero
5328    .endif
5329    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5330
5331                               @ optional op; may set condition codes
5332    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
5333    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5334    SET_VREG(r1, r9)               @ vAA<- r1
5335    GOTO_OPCODE(ip)                     @ jump to next instruction
5336    /* 10-13 instructions */
5337
5338
5339/* ------------------------------ */
5340    .balign 64
5341.L_OP_AND_INT_2ADDR: /* 0xb5 */
5342/* File: armv6t2/OP_AND_INT_2ADDR.S */
5343/* File: armv6t2/binop2addr.S */
5344    /*
5345     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5346     * that specifies an instruction that performs "result = r0 op r1".
5347     * This could be an ARM instruction or a function call.  (If the result
5348     * comes back in a register other than r0, you can override "result".)
5349     *
5350     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5351     * vCC (r1).  Useful for integer division and modulus.
5352     *
5353     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5354     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5355     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5356     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5357     */
5358    /* binop/2addr vA, vB */
5359    mov     r3, rINST, lsr #12          @ r3<- B
5360    ubfx    r9, rINST, #8, #4           @ r9<- A
5361    GET_VREG(r1, r3)                    @ r1<- vB
5362    GET_VREG(r0, r9)                    @ r0<- vA
5363    .if 0
5364    cmp     r1, #0                      @ is second operand zero?
5365    beq     common_errDivideByZero
5366    .endif
5367    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5368
5369                               @ optional op; may set condition codes
5370    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
5371    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5372    SET_VREG(r0, r9)               @ vAA<- r0
5373    GOTO_OPCODE(ip)                     @ jump to next instruction
5374    /* 10-13 instructions */
5375
5376
5377/* ------------------------------ */
5378    .balign 64
5379.L_OP_OR_INT_2ADDR: /* 0xb6 */
5380/* File: armv6t2/OP_OR_INT_2ADDR.S */
5381/* File: armv6t2/binop2addr.S */
5382    /*
5383     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5384     * that specifies an instruction that performs "result = r0 op r1".
5385     * This could be an ARM instruction or a function call.  (If the result
5386     * comes back in a register other than r0, you can override "result".)
5387     *
5388     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5389     * vCC (r1).  Useful for integer division and modulus.
5390     *
5391     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5392     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5393     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5394     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5395     */
5396    /* binop/2addr vA, vB */
5397    mov     r3, rINST, lsr #12          @ r3<- B
5398    ubfx    r9, rINST, #8, #4           @ r9<- A
5399    GET_VREG(r1, r3)                    @ r1<- vB
5400    GET_VREG(r0, r9)                    @ r0<- vA
5401    .if 0
5402    cmp     r1, #0                      @ is second operand zero?
5403    beq     common_errDivideByZero
5404    .endif
5405    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5406
5407                               @ optional op; may set condition codes
5408    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
5409    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5410    SET_VREG(r0, r9)               @ vAA<- r0
5411    GOTO_OPCODE(ip)                     @ jump to next instruction
5412    /* 10-13 instructions */
5413
5414
5415/* ------------------------------ */
5416    .balign 64
5417.L_OP_XOR_INT_2ADDR: /* 0xb7 */
5418/* File: armv6t2/OP_XOR_INT_2ADDR.S */
5419/* File: armv6t2/binop2addr.S */
5420    /*
5421     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5422     * that specifies an instruction that performs "result = r0 op r1".
5423     * This could be an ARM instruction or a function call.  (If the result
5424     * comes back in a register other than r0, you can override "result".)
5425     *
5426     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5427     * vCC (r1).  Useful for integer division and modulus.
5428     *
5429     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5430     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5431     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5432     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5433     */
5434    /* binop/2addr vA, vB */
5435    mov     r3, rINST, lsr #12          @ r3<- B
5436    ubfx    r9, rINST, #8, #4           @ r9<- A
5437    GET_VREG(r1, r3)                    @ r1<- vB
5438    GET_VREG(r0, r9)                    @ r0<- vA
5439    .if 0
5440    cmp     r1, #0                      @ is second operand zero?
5441    beq     common_errDivideByZero
5442    .endif
5443    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5444
5445                               @ optional op; may set condition codes
5446    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
5447    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5448    SET_VREG(r0, r9)               @ vAA<- r0
5449    GOTO_OPCODE(ip)                     @ jump to next instruction
5450    /* 10-13 instructions */
5451
5452
5453/* ------------------------------ */
5454    .balign 64
5455.L_OP_SHL_INT_2ADDR: /* 0xb8 */
5456/* File: armv6t2/OP_SHL_INT_2ADDR.S */
5457/* File: armv6t2/binop2addr.S */
5458    /*
5459     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5460     * that specifies an instruction that performs "result = r0 op r1".
5461     * This could be an ARM instruction or a function call.  (If the result
5462     * comes back in a register other than r0, you can override "result".)
5463     *
5464     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5465     * vCC (r1).  Useful for integer division and modulus.
5466     *
5467     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5468     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5469     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5470     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5471     */
5472    /* binop/2addr vA, vB */
5473    mov     r3, rINST, lsr #12          @ r3<- B
5474    ubfx    r9, rINST, #8, #4           @ r9<- A
5475    GET_VREG(r1, r3)                    @ r1<- vB
5476    GET_VREG(r0, r9)                    @ r0<- vA
5477    .if 0
5478    cmp     r1, #0                      @ is second operand zero?
5479    beq     common_errDivideByZero
5480    .endif
5481    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5482
5483    and     r1, r1, #31                           @ optional op; may set condition codes
5484    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
5485    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5486    SET_VREG(r0, r9)               @ vAA<- r0
5487    GOTO_OPCODE(ip)                     @ jump to next instruction
5488    /* 10-13 instructions */
5489
5490
5491/* ------------------------------ */
5492    .balign 64
5493.L_OP_SHR_INT_2ADDR: /* 0xb9 */
5494/* File: armv6t2/OP_SHR_INT_2ADDR.S */
5495/* File: armv6t2/binop2addr.S */
5496    /*
5497     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5498     * that specifies an instruction that performs "result = r0 op r1".
5499     * This could be an ARM instruction or a function call.  (If the result
5500     * comes back in a register other than r0, you can override "result".)
5501     *
5502     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5503     * vCC (r1).  Useful for integer division and modulus.
5504     *
5505     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5506     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5507     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5508     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5509     */
5510    /* binop/2addr vA, vB */
5511    mov     r3, rINST, lsr #12          @ r3<- B
5512    ubfx    r9, rINST, #8, #4           @ r9<- A
5513    GET_VREG(r1, r3)                    @ r1<- vB
5514    GET_VREG(r0, r9)                    @ r0<- vA
5515    .if 0
5516    cmp     r1, #0                      @ is second operand zero?
5517    beq     common_errDivideByZero
5518    .endif
5519    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5520
5521    and     r1, r1, #31                           @ optional op; may set condition codes
5522    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
5523    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5524    SET_VREG(r0, r9)               @ vAA<- r0
5525    GOTO_OPCODE(ip)                     @ jump to next instruction
5526    /* 10-13 instructions */
5527
5528
5529/* ------------------------------ */
5530    .balign 64
5531.L_OP_USHR_INT_2ADDR: /* 0xba */
5532/* File: armv6t2/OP_USHR_INT_2ADDR.S */
5533/* File: armv6t2/binop2addr.S */
5534    /*
5535     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5536     * that specifies an instruction that performs "result = r0 op r1".
5537     * This could be an ARM instruction or a function call.  (If the result
5538     * comes back in a register other than r0, you can override "result".)
5539     *
5540     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5541     * vCC (r1).  Useful for integer division and modulus.
5542     *
5543     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5544     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5545     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5546     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5547     */
5548    /* binop/2addr vA, vB */
5549    mov     r3, rINST, lsr #12          @ r3<- B
5550    ubfx    r9, rINST, #8, #4           @ r9<- A
5551    GET_VREG(r1, r3)                    @ r1<- vB
5552    GET_VREG(r0, r9)                    @ r0<- vA
5553    .if 0
5554    cmp     r1, #0                      @ is second operand zero?
5555    beq     common_errDivideByZero
5556    .endif
5557    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5558
5559    and     r1, r1, #31                           @ optional op; may set condition codes
5560    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
5561    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5562    SET_VREG(r0, r9)               @ vAA<- r0
5563    GOTO_OPCODE(ip)                     @ jump to next instruction
5564    /* 10-13 instructions */
5565
5566
5567/* ------------------------------ */
5568    .balign 64
5569.L_OP_ADD_LONG_2ADDR: /* 0xbb */
5570/* File: armv6t2/OP_ADD_LONG_2ADDR.S */
5571/* File: armv6t2/binopWide2addr.S */
5572    /*
5573     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5574     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5575     * This could be an ARM instruction or a function call.  (If the result
5576     * comes back in a register other than r0, you can override "result".)
5577     *
5578     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5579     * vCC (r1).  Useful for integer division and modulus.
5580     *
5581     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5582     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5583     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5584     *      rem-double/2addr
5585     */
5586    /* binop/2addr vA, vB */
5587    mov     r1, rINST, lsr #12          @ r1<- B
5588    ubfx    r9, rINST, #8, #4           @ r9<- A
5589    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5590    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5591    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5592    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5593    .if 0
5594    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5595    beq     common_errDivideByZero
5596    .endif
5597    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5598
5599    adds    r0, r0, r2                           @ optional op; may set condition codes
5600    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
5601    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5602    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5603    GOTO_OPCODE(ip)                     @ jump to next instruction
5604    /* 12-15 instructions */
5605
5606
5607/* ------------------------------ */
5608    .balign 64
5609.L_OP_SUB_LONG_2ADDR: /* 0xbc */
5610/* File: armv6t2/OP_SUB_LONG_2ADDR.S */
5611/* File: armv6t2/binopWide2addr.S */
5612    /*
5613     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5614     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5615     * This could be an ARM instruction or a function call.  (If the result
5616     * comes back in a register other than r0, you can override "result".)
5617     *
5618     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5619     * vCC (r1).  Useful for integer division and modulus.
5620     *
5621     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5622     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5623     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5624     *      rem-double/2addr
5625     */
5626    /* binop/2addr vA, vB */
5627    mov     r1, rINST, lsr #12          @ r1<- B
5628    ubfx    r9, rINST, #8, #4           @ r9<- A
5629    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5630    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5631    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5632    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5633    .if 0
5634    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5635    beq     common_errDivideByZero
5636    .endif
5637    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5638
5639    subs    r0, r0, r2                           @ optional op; may set condition codes
5640    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
5641    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5642    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5643    GOTO_OPCODE(ip)                     @ jump to next instruction
5644    /* 12-15 instructions */
5645
5646
5647/* ------------------------------ */
5648    .balign 64
5649.L_OP_MUL_LONG_2ADDR: /* 0xbd */
5650/* File: armv6t2/OP_MUL_LONG_2ADDR.S */
5651    /*
5652     * Signed 64-bit integer multiply, "/2addr" version.
5653     *
5654     * See OP_MUL_LONG for an explanation.
5655     *
5656     * We get a little tight on registers, so to avoid looking up &fp[A]
5657     * again we stuff it into rINST.
5658     */
5659    /* mul-long/2addr vA, vB */
5660    mov     r1, rINST, lsr #12          @ r1<- B
5661    ubfx    r9, rINST, #8, #4           @ r9<- A
5662    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5663    add     rINST, rFP, r9, lsl #2      @ rINST<- &fp[A]
5664    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5665    ldmia   rINST, {r0-r1}              @ r0/r1<- vAA/vAA+1
5666    mul     ip, r2, r1                  @  ip<- ZxW
5667    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
5668    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
5669    mov     r0, rINST                   @ r0<- &fp[A] (free up rINST)
5670    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5671    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
5672    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5673    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
5674    GOTO_OPCODE(ip)                     @ jump to next instruction
5675
5676/* ------------------------------ */
5677    .balign 64
5678.L_OP_DIV_LONG_2ADDR: /* 0xbe */
5679/* File: armv6t2/OP_DIV_LONG_2ADDR.S */
5680/* File: armv6t2/binopWide2addr.S */
5681    /*
5682     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5683     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5684     * This could be an ARM instruction or a function call.  (If the result
5685     * comes back in a register other than r0, you can override "result".)
5686     *
5687     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5688     * vCC (r1).  Useful for integer division and modulus.
5689     *
5690     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5691     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5692     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5693     *      rem-double/2addr
5694     */
5695    /* binop/2addr vA, vB */
5696    mov     r1, rINST, lsr #12          @ r1<- B
5697    ubfx    r9, rINST, #8, #4           @ r9<- A
5698    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5699    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5700    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5701    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5702    .if 1
5703    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5704    beq     common_errDivideByZero
5705    .endif
5706    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5707
5708                               @ optional op; may set condition codes
5709    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
5710    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5711    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5712    GOTO_OPCODE(ip)                     @ jump to next instruction
5713    /* 12-15 instructions */
5714
5715
5716/* ------------------------------ */
5717    .balign 64
5718.L_OP_REM_LONG_2ADDR: /* 0xbf */
5719/* File: armv6t2/OP_REM_LONG_2ADDR.S */
5720/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
5721/* File: armv6t2/binopWide2addr.S */
5722    /*
5723     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5724     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5725     * This could be an ARM instruction or a function call.  (If the result
5726     * comes back in a register other than r0, you can override "result".)
5727     *
5728     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5729     * vCC (r1).  Useful for integer division and modulus.
5730     *
5731     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5732     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5733     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5734     *      rem-double/2addr
5735     */
5736    /* binop/2addr vA, vB */
5737    mov     r1, rINST, lsr #12          @ r1<- B
5738    ubfx    r9, rINST, #8, #4           @ r9<- A
5739    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5740    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5741    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5742    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5743    .if 1
5744    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5745    beq     common_errDivideByZero
5746    .endif
5747    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5748
5749                               @ optional op; may set condition codes
5750    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
5751    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5752    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
5753    GOTO_OPCODE(ip)                     @ jump to next instruction
5754    /* 12-15 instructions */
5755
5756
5757/* ------------------------------ */
5758    .balign 64
5759.L_OP_AND_LONG_2ADDR: /* 0xc0 */
5760/* File: armv6t2/OP_AND_LONG_2ADDR.S */
5761/* File: armv6t2/binopWide2addr.S */
5762    /*
5763     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5764     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5765     * This could be an ARM instruction or a function call.  (If the result
5766     * comes back in a register other than r0, you can override "result".)
5767     *
5768     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5769     * vCC (r1).  Useful for integer division and modulus.
5770     *
5771     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5772     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5773     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5774     *      rem-double/2addr
5775     */
5776    /* binop/2addr vA, vB */
5777    mov     r1, rINST, lsr #12          @ r1<- B
5778    ubfx    r9, rINST, #8, #4           @ r9<- A
5779    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5780    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5781    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5782    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5783    .if 0
5784    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5785    beq     common_errDivideByZero
5786    .endif
5787    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5788
5789    and     r0, r0, r2                           @ optional op; may set condition codes
5790    and     r1, r1, r3                              @ result<- op, r0-r3 changed
5791    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5792    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5793    GOTO_OPCODE(ip)                     @ jump to next instruction
5794    /* 12-15 instructions */
5795
5796
5797/* ------------------------------ */
5798    .balign 64
5799.L_OP_OR_LONG_2ADDR: /* 0xc1 */
5800/* File: armv6t2/OP_OR_LONG_2ADDR.S */
5801/* File: armv6t2/binopWide2addr.S */
5802    /*
5803     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5804     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5805     * This could be an ARM instruction or a function call.  (If the result
5806     * comes back in a register other than r0, you can override "result".)
5807     *
5808     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5809     * vCC (r1).  Useful for integer division and modulus.
5810     *
5811     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5812     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5813     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5814     *      rem-double/2addr
5815     */
5816    /* binop/2addr vA, vB */
5817    mov     r1, rINST, lsr #12          @ r1<- B
5818    ubfx    r9, rINST, #8, #4           @ r9<- A
5819    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5820    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5821    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5822    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5823    .if 0
5824    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5825    beq     common_errDivideByZero
5826    .endif
5827    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5828
5829    orr     r0, r0, r2                           @ optional op; may set condition codes
5830    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
5831    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5832    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5833    GOTO_OPCODE(ip)                     @ jump to next instruction
5834    /* 12-15 instructions */
5835
5836
5837/* ------------------------------ */
5838    .balign 64
5839.L_OP_XOR_LONG_2ADDR: /* 0xc2 */
5840/* File: armv6t2/OP_XOR_LONG_2ADDR.S */
5841/* File: armv6t2/binopWide2addr.S */
5842    /*
5843     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5844     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5845     * This could be an ARM instruction or a function call.  (If the result
5846     * comes back in a register other than r0, you can override "result".)
5847     *
5848     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5849     * vCC (r1).  Useful for integer division and modulus.
5850     *
5851     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5852     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5853     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5854     *      rem-double/2addr
5855     */
5856    /* binop/2addr vA, vB */
5857    mov     r1, rINST, lsr #12          @ r1<- B
5858    ubfx    r9, rINST, #8, #4           @ r9<- A
5859    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5860    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5861    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5862    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5863    .if 0
5864    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5865    beq     common_errDivideByZero
5866    .endif
5867    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5868
5869    eor     r0, r0, r2                           @ optional op; may set condition codes
5870    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
5871    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5872    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5873    GOTO_OPCODE(ip)                     @ jump to next instruction
5874    /* 12-15 instructions */
5875
5876
5877/* ------------------------------ */
5878    .balign 64
5879.L_OP_SHL_LONG_2ADDR: /* 0xc3 */
5880/* File: armv6t2/OP_SHL_LONG_2ADDR.S */
5881    /*
5882     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5883     * 32-bit shift distance.
5884     */
5885    /* shl-long/2addr vA, vB */
5886    mov     r3, rINST, lsr #12          @ r3<- B
5887    ubfx    r9, rINST, #8, #4           @ r9<- A
5888    GET_VREG(r2, r3)                    @ r2<- vB
5889    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5890    and     r2, r2, #63                 @ r2<- r2 & 0x3f
5891    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5892
5893    mov     r1, r1, asl r2              @  r1<- r1 << r2
5894    rsb     r3, r2, #32                 @  r3<- 32 - r2
5895    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
5896    subs    ip, r2, #32                 @  ip<- r2 - 32
5897    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5898    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
5899    mov     r0, r0, asl r2              @  r0<- r0 << r2
5900    b       .LOP_SHL_LONG_2ADDR_finish
5901
5902/* ------------------------------ */
5903    .balign 64
5904.L_OP_SHR_LONG_2ADDR: /* 0xc4 */
5905/* File: armv6t2/OP_SHR_LONG_2ADDR.S */
5906    /*
5907     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5908     * 32-bit shift distance.
5909     */
5910    /* shr-long/2addr vA, vB */
5911    mov     r3, rINST, lsr #12          @ r3<- B
5912    ubfx    r9, rINST, #8, #4           @ r9<- A
5913    GET_VREG(r2, r3)                    @ r2<- vB
5914    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5915    and     r2, r2, #63                 @ r2<- r2 & 0x3f
5916    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5917
5918    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
5919    rsb     r3, r2, #32                 @  r3<- 32 - r2
5920    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
5921    subs    ip, r2, #32                 @  ip<- r2 - 32
5922    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5923    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
5924    mov     r1, r1, asr r2              @  r1<- r1 >> r2
5925    b       .LOP_SHR_LONG_2ADDR_finish
5926
5927/* ------------------------------ */
5928    .balign 64
5929.L_OP_USHR_LONG_2ADDR: /* 0xc5 */
5930/* File: armv6t2/OP_USHR_LONG_2ADDR.S */
5931    /*
5932     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
5933     * 32-bit shift distance.
5934     */
5935    /* ushr-long/2addr vA, vB */
5936    mov     r3, rINST, lsr #12          @ r3<- B
5937    ubfx    r9, rINST, #8, #4           @ r9<- A
5938    GET_VREG(r2, r3)                    @ r2<- vB
5939    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5940    and     r2, r2, #63                 @ r2<- r2 & 0x3f
5941    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5942
5943    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
5944    rsb     r3, r2, #32                 @  r3<- 32 - r2
5945    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
5946    subs    ip, r2, #32                 @  ip<- r2 - 32
5947    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5948    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
5949    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
5950    b       .LOP_USHR_LONG_2ADDR_finish
5951
5952/* ------------------------------ */
5953    .balign 64
5954.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
5955/* File: arm-vfp/OP_ADD_FLOAT_2ADDR.S */
5956/* File: arm-vfp/fbinop2addr.S */
5957    /*
5958     * Generic 32-bit floating point "/2addr" binary operation.  Provide
5959     * an "instr" line that specifies an instruction that performs
5960     * "s2 = s0 op s1".
5961     *
5962     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
5963     */
5964    /* binop/2addr vA, vB */
5965    mov     r3, rINST, lsr #12          @ r3<- B
5966    mov     r9, rINST, lsr #8           @ r9<- A+
5967    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
5968    and     r9, r9, #15                 @ r9<- A
5969    flds    s1, [r3]                    @ s1<- vB
5970    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
5971    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5972    flds    s0, [r9]                    @ s0<- vA
5973
5974    fadds   s2, s0, s1                              @ s2<- op
5975    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5976    fsts    s2, [r9]                    @ vAA<- s2
5977    GOTO_OPCODE(ip)                     @ jump to next instruction
5978
5979
5980/* ------------------------------ */
5981    .balign 64
5982.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
5983/* File: arm-vfp/OP_SUB_FLOAT_2ADDR.S */
5984/* File: arm-vfp/fbinop2addr.S */
5985    /*
5986     * Generic 32-bit floating point "/2addr" binary operation.  Provide
5987     * an "instr" line that specifies an instruction that performs
5988     * "s2 = s0 op s1".
5989     *
5990     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
5991     */
5992    /* binop/2addr vA, vB */
5993    mov     r3, rINST, lsr #12          @ r3<- B
5994    mov     r9, rINST, lsr #8           @ r9<- A+
5995    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
5996    and     r9, r9, #15                 @ r9<- A
5997    flds    s1, [r3]                    @ s1<- vB
5998    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
5999    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6000    flds    s0, [r9]                    @ s0<- vA
6001
6002    fsubs   s2, s0, s1                              @ s2<- op
6003    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6004    fsts    s2, [r9]                    @ vAA<- s2
6005    GOTO_OPCODE(ip)                     @ jump to next instruction
6006
6007
6008/* ------------------------------ */
6009    .balign 64
6010.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
6011/* File: arm-vfp/OP_MUL_FLOAT_2ADDR.S */
6012/* File: arm-vfp/fbinop2addr.S */
6013    /*
6014     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6015     * an "instr" line that specifies an instruction that performs
6016     * "s2 = s0 op s1".
6017     *
6018     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6019     */
6020    /* binop/2addr vA, vB */
6021    mov     r3, rINST, lsr #12          @ r3<- B
6022    mov     r9, rINST, lsr #8           @ r9<- A+
6023    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6024    and     r9, r9, #15                 @ r9<- A
6025    flds    s1, [r3]                    @ s1<- vB
6026    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6027    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6028    flds    s0, [r9]                    @ s0<- vA
6029
6030    fmuls   s2, s0, s1                              @ s2<- op
6031    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6032    fsts    s2, [r9]                    @ vAA<- s2
6033    GOTO_OPCODE(ip)                     @ jump to next instruction
6034
6035
6036/* ------------------------------ */
6037    .balign 64
6038.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
6039/* File: arm-vfp/OP_DIV_FLOAT_2ADDR.S */
6040/* File: arm-vfp/fbinop2addr.S */
6041    /*
6042     * Generic 32-bit floating point "/2addr" binary operation.  Provide
6043     * an "instr" line that specifies an instruction that performs
6044     * "s2 = s0 op s1".
6045     *
6046     * For: add-float/2addr, sub-float/2addr, mul-float/2addr, div-float/2addr
6047     */
6048    /* binop/2addr vA, vB */
6049    mov     r3, rINST, lsr #12          @ r3<- B
6050    mov     r9, rINST, lsr #8           @ r9<- A+
6051    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6052    and     r9, r9, #15                 @ r9<- A
6053    flds    s1, [r3]                    @ s1<- vB
6054    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6055    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6056    flds    s0, [r9]                    @ s0<- vA
6057
6058    fdivs   s2, s0, s1                              @ s2<- op
6059    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6060    fsts    s2, [r9]                    @ vAA<- s2
6061    GOTO_OPCODE(ip)                     @ jump to next instruction
6062
6063
6064/* ------------------------------ */
6065    .balign 64
6066.L_OP_REM_FLOAT_2ADDR: /* 0xca */
6067/* File: armv6t2/OP_REM_FLOAT_2ADDR.S */
6068/* EABI doesn't define a float remainder function, but libm does */
6069/* File: armv6t2/binop2addr.S */
6070    /*
6071     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6072     * that specifies an instruction that performs "result = r0 op r1".
6073     * This could be an ARM instruction or a function call.  (If the result
6074     * comes back in a register other than r0, you can override "result".)
6075     *
6076     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6077     * vCC (r1).  Useful for integer division and modulus.
6078     *
6079     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6080     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6081     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6082     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6083     */
6084    /* binop/2addr vA, vB */
6085    mov     r3, rINST, lsr #12          @ r3<- B
6086    ubfx    r9, rINST, #8, #4           @ r9<- A
6087    GET_VREG(r1, r3)                    @ r1<- vB
6088    GET_VREG(r0, r9)                    @ r0<- vA
6089    .if 0
6090    cmp     r1, #0                      @ is second operand zero?
6091    beq     common_errDivideByZero
6092    .endif
6093    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6094
6095                               @ optional op; may set condition codes
6096    bl      fmodf                              @ r0<- op, r0-r3 changed
6097    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6098    SET_VREG(r0, r9)               @ vAA<- r0
6099    GOTO_OPCODE(ip)                     @ jump to next instruction
6100    /* 10-13 instructions */
6101
6102
6103/* ------------------------------ */
6104    .balign 64
6105.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
6106/* File: arm-vfp/OP_ADD_DOUBLE_2ADDR.S */
6107/* File: arm-vfp/fbinopWide2addr.S */
6108    /*
6109     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6110     * an "instr" line that specifies an instruction that performs
6111     * "d2 = d0 op d1".
6112     *
6113     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6114     *      div-double/2addr
6115     */
6116    /* binop/2addr vA, vB */
6117    mov     r3, rINST, lsr #12          @ r3<- B
6118    mov     r9, rINST, lsr #8           @ r9<- A+
6119    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6120    and     r9, r9, #15                 @ r9<- A
6121    fldd    d1, [r3]                    @ d1<- vB
6122    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6123    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6124    fldd    d0, [r9]                    @ d0<- vA
6125
6126    faddd   d2, d0, d1                              @ d2<- op
6127    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6128    fstd    d2, [r9]                    @ vAA<- d2
6129    GOTO_OPCODE(ip)                     @ jump to next instruction
6130
6131
6132/* ------------------------------ */
6133    .balign 64
6134.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
6135/* File: arm-vfp/OP_SUB_DOUBLE_2ADDR.S */
6136/* File: arm-vfp/fbinopWide2addr.S */
6137    /*
6138     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6139     * an "instr" line that specifies an instruction that performs
6140     * "d2 = d0 op d1".
6141     *
6142     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6143     *      div-double/2addr
6144     */
6145    /* binop/2addr vA, vB */
6146    mov     r3, rINST, lsr #12          @ r3<- B
6147    mov     r9, rINST, lsr #8           @ r9<- A+
6148    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6149    and     r9, r9, #15                 @ r9<- A
6150    fldd    d1, [r3]                    @ d1<- vB
6151    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6152    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6153    fldd    d0, [r9]                    @ d0<- vA
6154
6155    fsubd   d2, d0, d1                              @ d2<- op
6156    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6157    fstd    d2, [r9]                    @ vAA<- d2
6158    GOTO_OPCODE(ip)                     @ jump to next instruction
6159
6160
6161/* ------------------------------ */
6162    .balign 64
6163.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
6164/* File: arm-vfp/OP_MUL_DOUBLE_2ADDR.S */
6165/* File: arm-vfp/fbinopWide2addr.S */
6166    /*
6167     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6168     * an "instr" line that specifies an instruction that performs
6169     * "d2 = d0 op d1".
6170     *
6171     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6172     *      div-double/2addr
6173     */
6174    /* binop/2addr vA, vB */
6175    mov     r3, rINST, lsr #12          @ r3<- B
6176    mov     r9, rINST, lsr #8           @ r9<- A+
6177    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6178    and     r9, r9, #15                 @ r9<- A
6179    fldd    d1, [r3]                    @ d1<- vB
6180    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6181    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6182    fldd    d0, [r9]                    @ d0<- vA
6183
6184    fmuld   d2, d0, d1                              @ d2<- op
6185    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6186    fstd    d2, [r9]                    @ vAA<- d2
6187    GOTO_OPCODE(ip)                     @ jump to next instruction
6188
6189
6190/* ------------------------------ */
6191    .balign 64
6192.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */
6193/* File: arm-vfp/OP_DIV_DOUBLE_2ADDR.S */
6194/* File: arm-vfp/fbinopWide2addr.S */
6195    /*
6196     * Generic 64-bit floating point "/2addr" binary operation.  Provide
6197     * an "instr" line that specifies an instruction that performs
6198     * "d2 = d0 op d1".
6199     *
6200     * For: add-double/2addr, sub-double/2addr, mul-double/2addr,
6201     *      div-double/2addr
6202     */
6203    /* binop/2addr vA, vB */
6204    mov     r3, rINST, lsr #12          @ r3<- B
6205    mov     r9, rINST, lsr #8           @ r9<- A+
6206    VREG_INDEX_TO_ADDR(r3, r3)          @ r3<- &vB
6207    and     r9, r9, #15                 @ r9<- A
6208    fldd    d1, [r3]                    @ d1<- vB
6209    VREG_INDEX_TO_ADDR(r9, r9)          @ r9<- &vA
6210    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6211    fldd    d0, [r9]                    @ d0<- vA
6212
6213    fdivd   d2, d0, d1                              @ d2<- op
6214    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6215    fstd    d2, [r9]                    @ vAA<- d2
6216    GOTO_OPCODE(ip)                     @ jump to next instruction
6217
6218
6219/* ------------------------------ */
6220    .balign 64
6221.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */
6222/* File: armv6t2/OP_REM_DOUBLE_2ADDR.S */
6223/* EABI doesn't define a double remainder function, but libm does */
6224/* File: armv6t2/binopWide2addr.S */
6225    /*
6226     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6227     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6228     * This could be an ARM instruction or a function call.  (If the result
6229     * comes back in a register other than r0, you can override "result".)
6230     *
6231     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6232     * vCC (r1).  Useful for integer division and modulus.
6233     *
6234     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6235     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6236     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6237     *      rem-double/2addr
6238     */
6239    /* binop/2addr vA, vB */
6240    mov     r1, rINST, lsr #12          @ r1<- B
6241    ubfx    r9, rINST, #8, #4           @ r9<- A
6242    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6243    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6244    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6245    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6246    .if 0
6247    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6248    beq     common_errDivideByZero
6249    .endif
6250    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6251
6252                               @ optional op; may set condition codes
6253    bl      fmod                              @ result<- op, r0-r3 changed
6254    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6255    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6256    GOTO_OPCODE(ip)                     @ jump to next instruction
6257    /* 12-15 instructions */
6258
6259
6260/* ------------------------------ */
6261    .balign 64
6262.L_OP_ADD_INT_LIT16: /* 0xd0 */
6263/* File: armv6t2/OP_ADD_INT_LIT16.S */
6264/* File: armv6t2/binopLit16.S */
6265    /*
6266     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6267     * that specifies an instruction that performs "result = r0 op r1".
6268     * This could be an ARM instruction or a function call.  (If the result
6269     * comes back in a register other than r0, you can override "result".)
6270     *
6271     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6272     * vCC (r1).  Useful for integer division and modulus.
6273     *
6274     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6275     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6276     */
6277    /* binop/lit16 vA, vB, #+CCCC */
6278    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6279    mov     r2, rINST, lsr #12          @ r2<- B
6280    ubfx    r9, rINST, #8, #4           @ r9<- A
6281    GET_VREG(r0, r2)                    @ r0<- vB
6282    .if 0
6283    cmp     r1, #0                      @ is second operand zero?
6284    beq     common_errDivideByZero
6285    .endif
6286    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6287
6288    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
6289    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6290    SET_VREG(r0, r9)               @ vAA<- r0
6291    GOTO_OPCODE(ip)                     @ jump to next instruction
6292    /* 10-13 instructions */
6293
6294
6295/* ------------------------------ */
6296    .balign 64
6297.L_OP_RSUB_INT: /* 0xd1 */
6298/* File: armv6t2/OP_RSUB_INT.S */
6299/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
6300/* File: armv6t2/binopLit16.S */
6301    /*
6302     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6303     * that specifies an instruction that performs "result = r0 op r1".
6304     * This could be an ARM instruction or a function call.  (If the result
6305     * comes back in a register other than r0, you can override "result".)
6306     *
6307     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6308     * vCC (r1).  Useful for integer division and modulus.
6309     *
6310     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6311     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6312     */
6313    /* binop/lit16 vA, vB, #+CCCC */
6314    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6315    mov     r2, rINST, lsr #12          @ r2<- B
6316    ubfx    r9, rINST, #8, #4           @ r9<- A
6317    GET_VREG(r0, r2)                    @ r0<- vB
6318    .if 0
6319    cmp     r1, #0                      @ is second operand zero?
6320    beq     common_errDivideByZero
6321    .endif
6322    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6323
6324    rsb     r0, r0, r1                              @ r0<- op, r0-r3 changed
6325    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6326    SET_VREG(r0, r9)               @ vAA<- r0
6327    GOTO_OPCODE(ip)                     @ jump to next instruction
6328    /* 10-13 instructions */
6329
6330
6331/* ------------------------------ */
6332    .balign 64
6333.L_OP_MUL_INT_LIT16: /* 0xd2 */
6334/* File: armv6t2/OP_MUL_INT_LIT16.S */
6335/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
6336/* File: armv6t2/binopLit16.S */
6337    /*
6338     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6339     * that specifies an instruction that performs "result = r0 op r1".
6340     * This could be an ARM instruction or a function call.  (If the result
6341     * comes back in a register other than r0, you can override "result".)
6342     *
6343     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6344     * vCC (r1).  Useful for integer division and modulus.
6345     *
6346     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6347     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6348     */
6349    /* binop/lit16 vA, vB, #+CCCC */
6350    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6351    mov     r2, rINST, lsr #12          @ r2<- B
6352    ubfx    r9, rINST, #8, #4           @ r9<- A
6353    GET_VREG(r0, r2)                    @ r0<- vB
6354    .if 0
6355    cmp     r1, #0                      @ is second operand zero?
6356    beq     common_errDivideByZero
6357    .endif
6358    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6359
6360    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
6361    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6362    SET_VREG(r0, r9)               @ vAA<- r0
6363    GOTO_OPCODE(ip)                     @ jump to next instruction
6364    /* 10-13 instructions */
6365
6366
6367/* ------------------------------ */
6368    .balign 64
6369.L_OP_DIV_INT_LIT16: /* 0xd3 */
6370/* File: armv6t2/OP_DIV_INT_LIT16.S */
6371/* File: armv6t2/binopLit16.S */
6372    /*
6373     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6374     * that specifies an instruction that performs "result = r0 op r1".
6375     * This could be an ARM instruction or a function call.  (If the result
6376     * comes back in a register other than r0, you can override "result".)
6377     *
6378     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6379     * vCC (r1).  Useful for integer division and modulus.
6380     *
6381     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6382     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6383     */
6384    /* binop/lit16 vA, vB, #+CCCC */
6385    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6386    mov     r2, rINST, lsr #12          @ r2<- B
6387    ubfx    r9, rINST, #8, #4           @ r9<- A
6388    GET_VREG(r0, r2)                    @ r0<- vB
6389    .if 1
6390    cmp     r1, #0                      @ is second operand zero?
6391    beq     common_errDivideByZero
6392    .endif
6393    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6394
6395    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
6396    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6397    SET_VREG(r0, r9)               @ vAA<- r0
6398    GOTO_OPCODE(ip)                     @ jump to next instruction
6399    /* 10-13 instructions */
6400
6401
6402/* ------------------------------ */
6403    .balign 64
6404.L_OP_REM_INT_LIT16: /* 0xd4 */
6405/* File: armv6t2/OP_REM_INT_LIT16.S */
6406/* idivmod returns quotient in r0 and remainder in r1 */
6407/* File: armv6t2/binopLit16.S */
6408    /*
6409     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6410     * that specifies an instruction that performs "result = r0 op r1".
6411     * This could be an ARM instruction or a function call.  (If the result
6412     * comes back in a register other than r0, you can override "result".)
6413     *
6414     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6415     * vCC (r1).  Useful for integer division and modulus.
6416     *
6417     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6418     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6419     */
6420    /* binop/lit16 vA, vB, #+CCCC */
6421    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6422    mov     r2, rINST, lsr #12          @ r2<- B
6423    ubfx    r9, rINST, #8, #4           @ r9<- A
6424    GET_VREG(r0, r2)                    @ r0<- vB
6425    .if 1
6426    cmp     r1, #0                      @ is second operand zero?
6427    beq     common_errDivideByZero
6428    .endif
6429    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6430
6431    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
6432    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6433    SET_VREG(r1, r9)               @ vAA<- r1
6434    GOTO_OPCODE(ip)                     @ jump to next instruction
6435    /* 10-13 instructions */
6436
6437
6438/* ------------------------------ */
6439    .balign 64
6440.L_OP_AND_INT_LIT16: /* 0xd5 */
6441/* File: armv6t2/OP_AND_INT_LIT16.S */
6442/* File: armv6t2/binopLit16.S */
6443    /*
6444     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6445     * that specifies an instruction that performs "result = r0 op r1".
6446     * This could be an ARM instruction or a function call.  (If the result
6447     * comes back in a register other than r0, you can override "result".)
6448     *
6449     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6450     * vCC (r1).  Useful for integer division and modulus.
6451     *
6452     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6453     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6454     */
6455    /* binop/lit16 vA, vB, #+CCCC */
6456    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6457    mov     r2, rINST, lsr #12          @ r2<- B
6458    ubfx    r9, rINST, #8, #4           @ r9<- A
6459    GET_VREG(r0, r2)                    @ r0<- vB
6460    .if 0
6461    cmp     r1, #0                      @ is second operand zero?
6462    beq     common_errDivideByZero
6463    .endif
6464    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6465
6466    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
6467    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6468    SET_VREG(r0, r9)               @ vAA<- r0
6469    GOTO_OPCODE(ip)                     @ jump to next instruction
6470    /* 10-13 instructions */
6471
6472
6473/* ------------------------------ */
6474    .balign 64
6475.L_OP_OR_INT_LIT16: /* 0xd6 */
6476/* File: armv6t2/OP_OR_INT_LIT16.S */
6477/* File: armv6t2/binopLit16.S */
6478    /*
6479     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6480     * that specifies an instruction that performs "result = r0 op r1".
6481     * This could be an ARM instruction or a function call.  (If the result
6482     * comes back in a register other than r0, you can override "result".)
6483     *
6484     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6485     * vCC (r1).  Useful for integer division and modulus.
6486     *
6487     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6488     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6489     */
6490    /* binop/lit16 vA, vB, #+CCCC */
6491    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6492    mov     r2, rINST, lsr #12          @ r2<- B
6493    ubfx    r9, rINST, #8, #4           @ r9<- A
6494    GET_VREG(r0, r2)                    @ r0<- vB
6495    .if 0
6496    cmp     r1, #0                      @ is second operand zero?
6497    beq     common_errDivideByZero
6498    .endif
6499    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6500
6501    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
6502    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6503    SET_VREG(r0, r9)               @ vAA<- r0
6504    GOTO_OPCODE(ip)                     @ jump to next instruction
6505    /* 10-13 instructions */
6506
6507
6508/* ------------------------------ */
6509    .balign 64
6510.L_OP_XOR_INT_LIT16: /* 0xd7 */
6511/* File: armv6t2/OP_XOR_INT_LIT16.S */
6512/* File: armv6t2/binopLit16.S */
6513    /*
6514     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6515     * that specifies an instruction that performs "result = r0 op r1".
6516     * This could be an ARM instruction or a function call.  (If the result
6517     * comes back in a register other than r0, you can override "result".)
6518     *
6519     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6520     * vCC (r1).  Useful for integer division and modulus.
6521     *
6522     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6523     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6524     */
6525    /* binop/lit16 vA, vB, #+CCCC */
6526    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6527    mov     r2, rINST, lsr #12          @ r2<- B
6528    ubfx    r9, rINST, #8, #4           @ r9<- A
6529    GET_VREG(r0, r2)                    @ r0<- vB
6530    .if 0
6531    cmp     r1, #0                      @ is second operand zero?
6532    beq     common_errDivideByZero
6533    .endif
6534    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6535
6536    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
6537    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6538    SET_VREG(r0, r9)               @ vAA<- r0
6539    GOTO_OPCODE(ip)                     @ jump to next instruction
6540    /* 10-13 instructions */
6541
6542
6543/* ------------------------------ */
6544    .balign 64
6545.L_OP_ADD_INT_LIT8: /* 0xd8 */
6546/* File: armv5te/OP_ADD_INT_LIT8.S */
6547/* File: armv5te/binopLit8.S */
6548    /*
6549     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6550     * that specifies an instruction that performs "result = r0 op r1".
6551     * This could be an ARM instruction or a function call.  (If the result
6552     * comes back in a register other than r0, you can override "result".)
6553     *
6554     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6555     * vCC (r1).  Useful for integer division and modulus.
6556     *
6557     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6558     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6559     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6560     */
6561    /* binop/lit8 vAA, vBB, #+CC */
6562    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6563    mov     r9, rINST, lsr #8           @ r9<- AA
6564    and     r2, r3, #255                @ r2<- BB
6565    GET_VREG(r0, r2)                    @ r0<- vBB
6566    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6567    .if 0
6568    @cmp     r1, #0                      @ is second operand zero?
6569    beq     common_errDivideByZero
6570    .endif
6571    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6572
6573                               @ optional op; may set condition codes
6574    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
6575    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6576    SET_VREG(r0, r9)               @ vAA<- r0
6577    GOTO_OPCODE(ip)                     @ jump to next instruction
6578    /* 10-12 instructions */
6579
6580
6581/* ------------------------------ */
6582    .balign 64
6583.L_OP_RSUB_INT_LIT8: /* 0xd9 */
6584/* File: armv5te/OP_RSUB_INT_LIT8.S */
6585/* File: armv5te/binopLit8.S */
6586    /*
6587     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6588     * that specifies an instruction that performs "result = r0 op r1".
6589     * This could be an ARM instruction or a function call.  (If the result
6590     * comes back in a register other than r0, you can override "result".)
6591     *
6592     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6593     * vCC (r1).  Useful for integer division and modulus.
6594     *
6595     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6596     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6597     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6598     */
6599    /* binop/lit8 vAA, vBB, #+CC */
6600    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6601    mov     r9, rINST, lsr #8           @ r9<- AA
6602    and     r2, r3, #255                @ r2<- BB
6603    GET_VREG(r0, r2)                    @ r0<- vBB
6604    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6605    .if 0
6606    @cmp     r1, #0                      @ is second operand zero?
6607    beq     common_errDivideByZero
6608    .endif
6609    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6610
6611                               @ optional op; may set condition codes
6612    rsb     r0, r0, r1                              @ r0<- op, r0-r3 changed
6613    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6614    SET_VREG(r0, r9)               @ vAA<- r0
6615    GOTO_OPCODE(ip)                     @ jump to next instruction
6616    /* 10-12 instructions */
6617
6618
6619/* ------------------------------ */
6620    .balign 64
6621.L_OP_MUL_INT_LIT8: /* 0xda */
6622/* File: armv5te/OP_MUL_INT_LIT8.S */
6623/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
6624/* File: armv5te/binopLit8.S */
6625    /*
6626     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6627     * that specifies an instruction that performs "result = r0 op r1".
6628     * This could be an ARM instruction or a function call.  (If the result
6629     * comes back in a register other than r0, you can override "result".)
6630     *
6631     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6632     * vCC (r1).  Useful for integer division and modulus.
6633     *
6634     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6635     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6636     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6637     */
6638    /* binop/lit8 vAA, vBB, #+CC */
6639    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6640    mov     r9, rINST, lsr #8           @ r9<- AA
6641    and     r2, r3, #255                @ r2<- BB
6642    GET_VREG(r0, r2)                    @ r0<- vBB
6643    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6644    .if 0
6645    @cmp     r1, #0                      @ is second operand zero?
6646    beq     common_errDivideByZero
6647    .endif
6648    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6649
6650                               @ optional op; may set condition codes
6651    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
6652    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6653    SET_VREG(r0, r9)               @ vAA<- r0
6654    GOTO_OPCODE(ip)                     @ jump to next instruction
6655    /* 10-12 instructions */
6656
6657
6658/* ------------------------------ */
6659    .balign 64
6660.L_OP_DIV_INT_LIT8: /* 0xdb */
6661/* File: armv5te/OP_DIV_INT_LIT8.S */
6662/* File: armv5te/binopLit8.S */
6663    /*
6664     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6665     * that specifies an instruction that performs "result = r0 op r1".
6666     * This could be an ARM instruction or a function call.  (If the result
6667     * comes back in a register other than r0, you can override "result".)
6668     *
6669     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6670     * vCC (r1).  Useful for integer division and modulus.
6671     *
6672     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6673     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6674     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6675     */
6676    /* binop/lit8 vAA, vBB, #+CC */
6677    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6678    mov     r9, rINST, lsr #8           @ r9<- AA
6679    and     r2, r3, #255                @ r2<- BB
6680    GET_VREG(r0, r2)                    @ r0<- vBB
6681    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6682    .if 1
6683    @cmp     r1, #0                      @ is second operand zero?
6684    beq     common_errDivideByZero
6685    .endif
6686    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6687
6688                               @ optional op; may set condition codes
6689    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
6690    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6691    SET_VREG(r0, r9)               @ vAA<- r0
6692    GOTO_OPCODE(ip)                     @ jump to next instruction
6693    /* 10-12 instructions */
6694
6695
6696/* ------------------------------ */
6697    .balign 64
6698.L_OP_REM_INT_LIT8: /* 0xdc */
6699/* File: armv5te/OP_REM_INT_LIT8.S */
6700/* idivmod returns quotient in r0 and remainder in r1 */
6701/* File: armv5te/binopLit8.S */
6702    /*
6703     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6704     * that specifies an instruction that performs "result = r0 op r1".
6705     * This could be an ARM instruction or a function call.  (If the result
6706     * comes back in a register other than r0, you can override "result".)
6707     *
6708     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6709     * vCC (r1).  Useful for integer division and modulus.
6710     *
6711     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6712     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6713     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6714     */
6715    /* binop/lit8 vAA, vBB, #+CC */
6716    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6717    mov     r9, rINST, lsr #8           @ r9<- AA
6718    and     r2, r3, #255                @ r2<- BB
6719    GET_VREG(r0, r2)                    @ r0<- vBB
6720    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6721    .if 1
6722    @cmp     r1, #0                      @ is second operand zero?
6723    beq     common_errDivideByZero
6724    .endif
6725    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6726
6727                               @ optional op; may set condition codes
6728    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
6729    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6730    SET_VREG(r1, r9)               @ vAA<- r1
6731    GOTO_OPCODE(ip)                     @ jump to next instruction
6732    /* 10-12 instructions */
6733
6734
6735/* ------------------------------ */
6736    .balign 64
6737.L_OP_AND_INT_LIT8: /* 0xdd */
6738/* File: armv5te/OP_AND_INT_LIT8.S */
6739/* File: armv5te/binopLit8.S */
6740    /*
6741     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6742     * that specifies an instruction that performs "result = r0 op r1".
6743     * This could be an ARM instruction or a function call.  (If the result
6744     * comes back in a register other than r0, you can override "result".)
6745     *
6746     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6747     * vCC (r1).  Useful for integer division and modulus.
6748     *
6749     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6750     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6751     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6752     */
6753    /* binop/lit8 vAA, vBB, #+CC */
6754    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6755    mov     r9, rINST, lsr #8           @ r9<- AA
6756    and     r2, r3, #255                @ r2<- BB
6757    GET_VREG(r0, r2)                    @ r0<- vBB
6758    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6759    .if 0
6760    @cmp     r1, #0                      @ is second operand zero?
6761    beq     common_errDivideByZero
6762    .endif
6763    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6764
6765                               @ optional op; may set condition codes
6766    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
6767    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6768    SET_VREG(r0, r9)               @ vAA<- r0
6769    GOTO_OPCODE(ip)                     @ jump to next instruction
6770    /* 10-12 instructions */
6771
6772
6773/* ------------------------------ */
6774    .balign 64
6775.L_OP_OR_INT_LIT8: /* 0xde */
6776/* File: armv5te/OP_OR_INT_LIT8.S */
6777/* File: armv5te/binopLit8.S */
6778    /*
6779     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6780     * that specifies an instruction that performs "result = r0 op r1".
6781     * This could be an ARM instruction or a function call.  (If the result
6782     * comes back in a register other than r0, you can override "result".)
6783     *
6784     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6785     * vCC (r1).  Useful for integer division and modulus.
6786     *
6787     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6788     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6789     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6790     */
6791    /* binop/lit8 vAA, vBB, #+CC */
6792    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6793    mov     r9, rINST, lsr #8           @ r9<- AA
6794    and     r2, r3, #255                @ r2<- BB
6795    GET_VREG(r0, r2)                    @ r0<- vBB
6796    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6797    .if 0
6798    @cmp     r1, #0                      @ is second operand zero?
6799    beq     common_errDivideByZero
6800    .endif
6801    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6802
6803                               @ optional op; may set condition codes
6804    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
6805    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6806    SET_VREG(r0, r9)               @ vAA<- r0
6807    GOTO_OPCODE(ip)                     @ jump to next instruction
6808    /* 10-12 instructions */
6809
6810
6811/* ------------------------------ */
6812    .balign 64
6813.L_OP_XOR_INT_LIT8: /* 0xdf */
6814/* File: armv5te/OP_XOR_INT_LIT8.S */
6815/* File: armv5te/binopLit8.S */
6816    /*
6817     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6818     * that specifies an instruction that performs "result = r0 op r1".
6819     * This could be an ARM instruction or a function call.  (If the result
6820     * comes back in a register other than r0, you can override "result".)
6821     *
6822     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6823     * vCC (r1).  Useful for integer division and modulus.
6824     *
6825     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6826     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6827     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6828     */
6829    /* binop/lit8 vAA, vBB, #+CC */
6830    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6831    mov     r9, rINST, lsr #8           @ r9<- AA
6832    and     r2, r3, #255                @ r2<- BB
6833    GET_VREG(r0, r2)                    @ r0<- vBB
6834    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6835    .if 0
6836    @cmp     r1, #0                      @ is second operand zero?
6837    beq     common_errDivideByZero
6838    .endif
6839    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6840
6841                               @ optional op; may set condition codes
6842    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
6843    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6844    SET_VREG(r0, r9)               @ vAA<- r0
6845    GOTO_OPCODE(ip)                     @ jump to next instruction
6846    /* 10-12 instructions */
6847
6848
6849/* ------------------------------ */
6850    .balign 64
6851.L_OP_SHL_INT_LIT8: /* 0xe0 */
6852/* File: armv5te/OP_SHL_INT_LIT8.S */
6853/* File: armv5te/binopLit8.S */
6854    /*
6855     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6856     * that specifies an instruction that performs "result = r0 op r1".
6857     * This could be an ARM instruction or a function call.  (If the result
6858     * comes back in a register other than r0, you can override "result".)
6859     *
6860     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6861     * vCC (r1).  Useful for integer division and modulus.
6862     *
6863     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6864     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6865     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6866     */
6867    /* binop/lit8 vAA, vBB, #+CC */
6868    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6869    mov     r9, rINST, lsr #8           @ r9<- AA
6870    and     r2, r3, #255                @ r2<- BB
6871    GET_VREG(r0, r2)                    @ r0<- vBB
6872    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6873    .if 0
6874    @cmp     r1, #0                      @ is second operand zero?
6875    beq     common_errDivideByZero
6876    .endif
6877    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6878
6879    and     r1, r1, #31                           @ optional op; may set condition codes
6880    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
6881    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6882    SET_VREG(r0, r9)               @ vAA<- r0
6883    GOTO_OPCODE(ip)                     @ jump to next instruction
6884    /* 10-12 instructions */
6885
6886
6887/* ------------------------------ */
6888    .balign 64
6889.L_OP_SHR_INT_LIT8: /* 0xe1 */
6890/* File: armv5te/OP_SHR_INT_LIT8.S */
6891/* File: armv5te/binopLit8.S */
6892    /*
6893     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6894     * that specifies an instruction that performs "result = r0 op r1".
6895     * This could be an ARM instruction or a function call.  (If the result
6896     * comes back in a register other than r0, you can override "result".)
6897     *
6898     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6899     * vCC (r1).  Useful for integer division and modulus.
6900     *
6901     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6902     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6903     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6904     */
6905    /* binop/lit8 vAA, vBB, #+CC */
6906    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6907    mov     r9, rINST, lsr #8           @ r9<- AA
6908    and     r2, r3, #255                @ r2<- BB
6909    GET_VREG(r0, r2)                    @ r0<- vBB
6910    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6911    .if 0
6912    @cmp     r1, #0                      @ is second operand zero?
6913    beq     common_errDivideByZero
6914    .endif
6915    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6916
6917    and     r1, r1, #31                           @ optional op; may set condition codes
6918    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
6919    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6920    SET_VREG(r0, r9)               @ vAA<- r0
6921    GOTO_OPCODE(ip)                     @ jump to next instruction
6922    /* 10-12 instructions */
6923
6924
6925/* ------------------------------ */
6926    .balign 64
6927.L_OP_USHR_INT_LIT8: /* 0xe2 */
6928/* File: armv5te/OP_USHR_INT_LIT8.S */
6929/* File: armv5te/binopLit8.S */
6930    /*
6931     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6932     * that specifies an instruction that performs "result = r0 op r1".
6933     * This could be an ARM instruction or a function call.  (If the result
6934     * comes back in a register other than r0, you can override "result".)
6935     *
6936     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6937     * vCC (r1).  Useful for integer division and modulus.
6938     *
6939     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6940     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6941     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6942     */
6943    /* binop/lit8 vAA, vBB, #+CC */
6944    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6945    mov     r9, rINST, lsr #8           @ r9<- AA
6946    and     r2, r3, #255                @ r2<- BB
6947    GET_VREG(r0, r2)                    @ r0<- vBB
6948    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6949    .if 0
6950    @cmp     r1, #0                      @ is second operand zero?
6951    beq     common_errDivideByZero
6952    .endif
6953    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6954
6955    and     r1, r1, #31                           @ optional op; may set condition codes
6956    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
6957    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6958    SET_VREG(r0, r9)               @ vAA<- r0
6959    GOTO_OPCODE(ip)                     @ jump to next instruction
6960    /* 10-12 instructions */
6961
6962
6963/* ------------------------------ */
6964    .balign 64
6965.L_OP_IGET_VOLATILE: /* 0xe3 */
6966/* File: armv5te/OP_IGET_VOLATILE.S */
6967/* File: armv5te/OP_IGET.S */
6968    /*
6969     * General 32-bit instance field get.
6970     *
6971     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
6972     */
6973    /* op vA, vB, field@CCCC */
6974    mov     r0, rINST, lsr #12          @ r0<- B
6975    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
6976    FETCH(r1, 1)                        @ r1<- field ref CCCC
6977    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
6978    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
6979    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
6980    cmp     r0, #0                      @ is resolved entry null?
6981    bne     .LOP_IGET_VOLATILE_finish          @ no, already resolved
69828:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
6983    EXPORT_PC()                         @ resolve() could throw
6984    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
6985    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
6986    cmp     r0, #0
6987    bne     .LOP_IGET_VOLATILE_finish
6988    b       common_exceptionThrown
6989
6990
6991/* ------------------------------ */
6992    .balign 64
6993.L_OP_IPUT_VOLATILE: /* 0xe4 */
6994/* File: armv5te/OP_IPUT_VOLATILE.S */
6995/* File: armv5te/OP_IPUT.S */
6996    /*
6997     * General 32-bit instance field put.
6998     *
6999     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
7000     */
7001    /* op vA, vB, field@CCCC */
7002    mov     r0, rINST, lsr #12          @ r0<- B
7003    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7004    FETCH(r1, 1)                        @ r1<- field ref CCCC
7005    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7006    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7007    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7008    cmp     r0, #0                      @ is resolved entry null?
7009    bne     .LOP_IPUT_VOLATILE_finish          @ no, already resolved
70108:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7011    EXPORT_PC()                         @ resolve() could throw
7012    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7013    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7014    cmp     r0, #0                      @ success?
7015    bne     .LOP_IPUT_VOLATILE_finish          @ yes, finish up
7016    b       common_exceptionThrown
7017
7018
7019/* ------------------------------ */
7020    .balign 64
7021.L_OP_SGET_VOLATILE: /* 0xe5 */
7022/* File: armv5te/OP_SGET_VOLATILE.S */
7023/* File: armv5te/OP_SGET.S */
7024    /*
7025     * General 32-bit SGET handler.
7026     *
7027     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7028     */
7029    /* op vAA, field@BBBB */
7030    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7031    FETCH(r1, 1)                        @ r1<- field ref BBBB
7032    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
7033    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
7034    cmp     r0, #0                      @ is resolved entry null?
7035    beq     .LOP_SGET_VOLATILE_resolve         @ yes, do resolve
7036.LOP_SGET_VOLATILE_finish: @ field ptr in r0
7037    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7038    SMP_DMB                            @ acquiring load
7039    mov     r2, rINST, lsr #8           @ r2<- AA
7040    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7041    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7042    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7043    GOTO_OPCODE(ip)                     @ jump to next instruction
7044
7045
7046/* ------------------------------ */
7047    .balign 64
7048.L_OP_SPUT_VOLATILE: /* 0xe6 */
7049/* File: armv5te/OP_SPUT_VOLATILE.S */
7050/* File: armv5te/OP_SPUT.S */
7051    /*
7052     * General 32-bit SPUT handler.
7053     *
7054     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
7055     */
7056    /* op vAA, field@BBBB */
7057    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7058    FETCH(r1, 1)                        @ r1<- field ref BBBB
7059    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
7060    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
7061    cmp     r0, #0                      @ is resolved entry null?
7062    beq     .LOP_SPUT_VOLATILE_resolve         @ yes, do resolve
7063.LOP_SPUT_VOLATILE_finish:   @ field ptr in r0
7064    mov     r2, rINST, lsr #8           @ r2<- AA
7065    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7066    GET_VREG(r1, r2)                    @ r1<- fp[AA]
7067    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7068    SMP_DMB_ST                        @ releasing store
7069    str     r1, [r0, #offStaticField_value] @ field<- vAA
7070    SMP_DMB
7071    GOTO_OPCODE(ip)                     @ jump to next instruction
7072
7073
7074/* ------------------------------ */
7075    .balign 64
7076.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
7077/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */
7078/* File: armv5te/OP_IGET.S */
7079    /*
7080     * General 32-bit instance field get.
7081     *
7082     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7083     */
7084    /* op vA, vB, field@CCCC */
7085    mov     r0, rINST, lsr #12          @ r0<- B
7086    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7087    FETCH(r1, 1)                        @ r1<- field ref CCCC
7088    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7089    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7090    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7091    cmp     r0, #0                      @ is resolved entry null?
7092    bne     .LOP_IGET_OBJECT_VOLATILE_finish          @ no, already resolved
70938:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7094    EXPORT_PC()                         @ resolve() could throw
7095    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7096    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7097    cmp     r0, #0
7098    bne     .LOP_IGET_OBJECT_VOLATILE_finish
7099    b       common_exceptionThrown
7100
7101
7102/* ------------------------------ */
7103    .balign 64
7104.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
7105/* File: armv5te/OP_IGET_WIDE_VOLATILE.S */
7106/* File: armv5te/OP_IGET_WIDE.S */
7107    /*
7108     * Wide 32-bit instance field get.
7109     */
7110    /* iget-wide vA, vB, field@CCCC */
7111    mov     r0, rINST, lsr #12          @ r0<- B
7112    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7113    FETCH(r1, 1)                        @ r1<- field ref CCCC
7114    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7115    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7116    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7117    cmp     r0, #0                      @ is resolved entry null?
7118    bne     .LOP_IGET_WIDE_VOLATILE_finish          @ no, already resolved
71198:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
7120    EXPORT_PC()                         @ resolve() could throw
7121    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7122    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7123    cmp     r0, #0
7124    bne     .LOP_IGET_WIDE_VOLATILE_finish
7125    b       common_exceptionThrown
7126
7127
7128/* ------------------------------ */
7129    .balign 64
7130.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
7131/* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */
7132/* File: armv5te/OP_IPUT_WIDE.S */
7133    /* iput-wide vA, vB, field@CCCC */
7134    mov     r0, rINST, lsr #12          @ r0<- B
7135    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7136    FETCH(r1, 1)                        @ r1<- field ref CCCC
7137    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7138    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7139    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7140    cmp     r0, #0                      @ is resolved entry null?
7141    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ no, already resolved
71428:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
7143    EXPORT_PC()                         @ resolve() could throw
7144    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7145    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7146    cmp     r0, #0                      @ success?
7147    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ yes, finish up
7148    b       common_exceptionThrown
7149
7150
7151/* ------------------------------ */
7152    .balign 64
7153.L_OP_SGET_WIDE_VOLATILE: /* 0xea */
7154/* File: armv5te/OP_SGET_WIDE_VOLATILE.S */
7155/* File: armv5te/OP_SGET_WIDE.S */
7156    /*
7157     * 64-bit SGET handler.
7158     */
7159    /* sget-wide vAA, field@BBBB */
7160    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7161    FETCH(r1, 1)                        @ r1<- field ref BBBB
7162    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
7163    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
7164    cmp     r0, #0                      @ is resolved entry null?
7165    beq     .LOP_SGET_WIDE_VOLATILE_resolve         @ yes, do resolve
7166.LOP_SGET_WIDE_VOLATILE_finish:
7167    mov     r9, rINST, lsr #8           @ r9<- AA
7168    .if 1
7169    add     r0, r0, #offStaticField_value @ r0<- pointer to data
7170    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
7171    .else
7172    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
7173    .endif
7174    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7175    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7176    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
7177    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7178    GOTO_OPCODE(ip)                     @ jump to next instruction
7179
7180
7181/* ------------------------------ */
7182    .balign 64
7183.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
7184/* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */
7185/* File: armv5te/OP_SPUT_WIDE.S */
7186    /*
7187     * 64-bit SPUT handler.
7188     */
7189    /* sput-wide vAA, field@BBBB */
7190    ldr     r0, [rSELF, #offThread_methodClassDex]  @ r0<- DvmDex
7191    FETCH(r1, 1)                        @ r1<- field ref BBBB
7192    ldr     r10, [r0, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
7193    mov     r9, rINST, lsr #8           @ r9<- AA
7194    ldr     r2, [r10, r1, lsl #2]        @ r2<- resolved StaticField ptr
7195    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7196    cmp     r2, #0                      @ is resolved entry null?
7197    beq     .LOP_SPUT_WIDE_VOLATILE_resolve         @ yes, do resolve
7198.LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9
7199    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7200    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
7201    GET_INST_OPCODE(r10)                @ extract opcode from rINST
7202    .if 1
7203    add     r2, r2, #offStaticField_value @ r2<- pointer to data
7204    bl      dvmQuasiAtomicSwap64Sync    @ stores r0/r1 into addr r2
7205    .else
7206    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
7207    .endif
7208    GOTO_OPCODE(r10)                    @ jump to next instruction
7209
7210
7211/* ------------------------------ */
7212    .balign 64
7213.L_OP_BREAKPOINT: /* 0xec */
7214/* File: armv5te/OP_BREAKPOINT.S */
7215    /*
7216     * Breakpoint handler.
7217     *
7218     * Restart this instruction with the original opcode.  By
7219     * the time we get here, the breakpoint will have already been
7220     * handled.
7221     */
7222    mov     r0, rPC
7223    bl      dvmGetOriginalOpcode        @ (rPC)
7224    FETCH(rINST, 0)                     @ reload OP_BREAKPOINT + rest of inst
7225    ldr     r1, [rSELF, #offThread_mainHandlerTable]
7226    and     rINST, #0xff00
7227    orr     rINST, rINST, r0
7228    GOTO_OPCODE_BASE(r1, r0)
7229
7230/* ------------------------------ */
7231    .balign 64
7232.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
7233/* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */
7234    /*
7235     * Handle a throw-verification-error instruction.  This throws an
7236     * exception for an error discovered during verification.  The
7237     * exception is indicated by AA, with some detail provided by BBBB.
7238     */
7239    /* op AA, ref@BBBB */
7240    ldr     r0, [rSELF, #offThread_method]    @ r0<- self->method
7241    FETCH(r2, 1)                        @ r2<- BBBB
7242    EXPORT_PC()                         @ export the PC
7243    mov     r1, rINST, lsr #8           @ r1<- AA
7244    bl      dvmThrowVerificationError   @ always throws
7245    b       common_exceptionThrown      @ handle exception
7246
7247/* ------------------------------ */
7248    .balign 64
7249.L_OP_EXECUTE_INLINE: /* 0xee */
7250/* File: armv5te/OP_EXECUTE_INLINE.S */
7251    /*
7252     * Execute a "native inline" instruction.
7253     *
7254     * We need to call an InlineOp4Func:
7255     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7256     *
7257     * The first four args are in r0-r3, pointer to return value storage
7258     * is on the stack.  The function's return value is a flag that tells
7259     * us if an exception was thrown.
7260     *
7261     * TUNING: could maintain two tables, pointer in Thread and
7262     * swap if profiler/debuggger active.
7263     */
7264    /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
7265    ldrh    r2, [rSELF, #offThread_subMode]
7266    FETCH(r10, 1)                       @ r10<- BBBB
7267    EXPORT_PC()                         @ can throw
7268    ands    r2, #kSubModeDebugProfile   @ Any going on?
7269    bne     .LOP_EXECUTE_INLINE_debugmode       @ yes - take slow path
7270.LOP_EXECUTE_INLINE_resume:
7271    add     r1, rSELF, #offThread_retval  @ r1<- &self->retval
7272    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7273    mov     r0, rINST, lsr #12          @ r0<- B
7274    str     r1, [sp]                    @ push &self->retval
7275    bl      .LOP_EXECUTE_INLINE_continue        @ make call; will return after
7276    add     sp, sp, #8                  @ pop stack
7277    cmp     r0, #0                      @ test boolean result of inline
7278    beq     common_exceptionThrown      @ returned false, handle exception
7279    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7280    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7281    GOTO_OPCODE(ip)                     @ jump to next instruction
7282
7283/* ------------------------------ */
7284    .balign 64
7285.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
7286/* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */
7287    /*
7288     * Execute a "native inline" instruction, using "/range" semantics.
7289     * Same idea as execute-inline, but we get the args differently.
7290     *
7291     * We need to call an InlineOp4Func:
7292     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7293     *
7294     * The first four args are in r0-r3, pointer to return value storage
7295     * is on the stack.  The function's return value is a flag that tells
7296     * us if an exception was thrown.
7297     */
7298    /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */
7299    ldrh    r2, [rSELF, #offThread_subMode]
7300    FETCH(r10, 1)                       @ r10<- BBBB
7301    EXPORT_PC()                         @ can throw
7302    ands    r2, #kSubModeDebugProfile   @ Any going on?
7303    bne     .LOP_EXECUTE_INLINE_RANGE_debugmode       @ yes - take slow path
7304.LOP_EXECUTE_INLINE_RANGE_resume:
7305    add     r1, rSELF, #offThread_retval  @ r1<- &self->retval
7306    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7307    mov     r0, rINST, lsr #8           @ r0<- AA
7308    str     r1, [sp]                    @ push &self->retval
7309    bl      .LOP_EXECUTE_INLINE_RANGE_continue        @ make call; will return after
7310    add     sp, sp, #8                  @ pop stack
7311    cmp     r0, #0                      @ test boolean result of inline
7312    beq     common_exceptionThrown      @ returned false, handle exception
7313    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7314    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7315    GOTO_OPCODE(ip)                     @ jump to next instruction
7316
7317/* ------------------------------ */
7318    .balign 64
7319.L_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */
7320/* File: armv5te/OP_INVOKE_OBJECT_INIT_RANGE.S */
7321    /*
7322     * Invoke Object.<init> on an object.  In practice we know that
7323     * Object's nullary constructor doesn't do anything, so we just
7324     * skip it unless a debugger is active.
7325     */
7326    FETCH(r1, 2)                  @ r1<- CCCC
7327    GET_VREG(r0, r1)                    @ r0<- "this" ptr
7328    cmp     r0, #0                      @ check for NULL
7329    beq     common_errNullObject        @ export PC and throw NPE
7330    ldr     r1, [r0, #offObject_clazz]  @ r1<- obj->clazz
7331    ldr     r2, [r1, #offClassObject_accessFlags] @ r2<- clazz->accessFlags
7332    tst     r2, #CLASS_ISFINALIZABLE    @ is this class finalizable?
7333    bne     .LOP_INVOKE_OBJECT_INIT_RANGE_setFinal        @ yes, go
7334.LOP_INVOKE_OBJECT_INIT_RANGE_finish:
7335    ldrh    r1, [rSELF, #offThread_subMode]
7336    ands    r1, #kSubModeDebuggerActive @ debugger active?
7337    bne     .LOP_INVOKE_OBJECT_INIT_RANGE_debugger        @ Yes - skip optimization
7338    FETCH_ADVANCE_INST(2+1)       @ advance to next instr, load rINST
7339    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
7340    GOTO_OPCODE(ip)                     @ execute it
7341
7342/* ------------------------------ */
7343    .balign 64
7344.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */
7345/* File: armv5te/OP_RETURN_VOID_BARRIER.S */
7346    SMP_DMB_ST
7347    b       common_returnFromMethod
7348
7349/* ------------------------------ */
7350    .balign 64
7351.L_OP_IGET_QUICK: /* 0xf2 */
7352/* File: armv6t2/OP_IGET_QUICK.S */
7353    /* For: iget-quick, iget-object-quick */
7354    /* op vA, vB, offset@CCCC */
7355    mov     r2, rINST, lsr #12          @ r2<- B
7356    FETCH(r1, 1)                        @ r1<- field byte offset
7357    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7358    ubfx    r2, rINST, #8, #4           @ r2<- A
7359    cmp     r3, #0                      @ check object for null
7360    beq     common_errNullObject        @ object was null
7361    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7362    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7363    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7364    SET_VREG(r0, r2)                    @ fp[A]<- r0
7365    GOTO_OPCODE(ip)                     @ jump to next instruction
7366
7367/* ------------------------------ */
7368    .balign 64
7369.L_OP_IGET_WIDE_QUICK: /* 0xf3 */
7370/* File: armv6t2/OP_IGET_WIDE_QUICK.S */
7371    /* iget-wide-quick vA, vB, offset@CCCC */
7372    mov     r2, rINST, lsr #12          @ r2<- B
7373    FETCH(ip, 1)                        @ ip<- field byte offset
7374    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7375    ubfx    r2, rINST, #8, #4           @ r2<- A
7376    cmp     r3, #0                      @ check object for null
7377    beq     common_errNullObject        @ object was null
7378    ldrd    r0, [r3, ip]                @ r0<- obj.field (64 bits, aligned)
7379    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7380    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
7381    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7382    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
7383    GOTO_OPCODE(ip)                     @ jump to next instruction
7384
7385/* ------------------------------ */
7386    .balign 64
7387.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */
7388/* File: armv5te/OP_IGET_OBJECT_QUICK.S */
7389/* File: armv5te/OP_IGET_QUICK.S */
7390    /* For: iget-quick, iget-object-quick */
7391    /* op vA, vB, offset@CCCC */
7392    mov     r2, rINST, lsr #12          @ r2<- B
7393    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7394    FETCH(r1, 1)                        @ r1<- field byte offset
7395    cmp     r3, #0                      @ check object for null
7396    mov     r2, rINST, lsr #8           @ r2<- A(+)
7397    beq     common_errNullObject        @ object was null
7398    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7399    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7400    and     r2, r2, #15
7401    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7402    SET_VREG(r0, r2)                    @ fp[A]<- r0
7403    GOTO_OPCODE(ip)                     @ jump to next instruction
7404
7405
7406/* ------------------------------ */
7407    .balign 64
7408.L_OP_IPUT_QUICK: /* 0xf5 */
7409/* File: armv6t2/OP_IPUT_QUICK.S */
7410    /* For: iput-quick, iput-object-quick */
7411    /* op vA, vB, offset@CCCC */
7412    mov     r2, rINST, lsr #12          @ r2<- B
7413    FETCH(r1, 1)                        @ r1<- field byte offset
7414    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7415    ubfx    r2, rINST, #8, #4           @ r2<- A
7416    cmp     r3, #0                      @ check object for null
7417    beq     common_errNullObject        @ object was null
7418    GET_VREG(r0, r2)                    @ r0<- fp[A]
7419    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7420    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7421    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7422    GOTO_OPCODE(ip)                     @ jump to next instruction
7423
7424/* ------------------------------ */
7425    .balign 64
7426.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */
7427/* File: armv6t2/OP_IPUT_WIDE_QUICK.S */
7428    /* iput-wide-quick vA, vB, offset@CCCC */
7429    mov     r1, rINST, lsr #12          @ r1<- B
7430    ubfx    r0, rINST, #8, #4           @ r0<- A
7431    GET_VREG(r2, r1)                    @ r2<- fp[B], the object pointer
7432    add     r3, rFP, r0, lsl #2         @ r3<- &fp[A]
7433    cmp     r2, #0                      @ check object for null
7434    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[A]
7435    beq     common_errNullObject        @ object was null
7436    FETCH(r3, 1)                        @ r3<- field byte offset
7437    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7438    strd    r0, [r2, r3]                @ obj.field (64 bits, aligned)<- r0/r1
7439    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7440    GOTO_OPCODE(ip)                     @ jump to next instruction
7441
7442/* ------------------------------ */
7443    .balign 64
7444.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
7445/* File: armv5te/OP_IPUT_OBJECT_QUICK.S */
7446    /* For: iput-object-quick */
7447    /* op vA, vB, offset@CCCC */
7448    mov     r2, rINST, lsr #12          @ r2<- B
7449    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7450    FETCH(r1, 1)                        @ r1<- field byte offset
7451    cmp     r3, #0                      @ check object for null
7452    mov     r2, rINST, lsr #8           @ r2<- A(+)
7453    beq     common_errNullObject        @ object was null
7454    and     r2, r2, #15
7455    GET_VREG(r0, r2)                    @ r0<- fp[A]
7456    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
7457    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7458    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7459    cmp     r0, #0
7460    strneb  r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head
7461    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7462    GOTO_OPCODE(ip)                     @ jump to next instruction
7463
7464/* ------------------------------ */
7465    .balign 64
7466.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
7467/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7468    /*
7469     * Handle an optimized virtual method call.
7470     *
7471     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7472     */
7473    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7474    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7475    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7476    FETCH(r1, 1)                        @ r1<- BBBB
7477    .if     (!0)
7478    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7479    .endif
7480    GET_VREG(r9, r3)                    @ r9<- vC ("this" ptr)
7481    cmp     r9, #0                      @ is "this" null?
7482    beq     common_errNullObject        @ null "this", throw exception
7483    ldr     r2, [r9, #offObject_clazz]  @ r2<- thisPtr->clazz
7484    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7485    EXPORT_PC()                         @ invoke must export
7486    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7487    bl      common_invokeMethodNoRange @ (r0=method, r9="this")
7488
7489/* ------------------------------ */
7490    .balign 64
7491.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
7492/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */
7493/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7494    /*
7495     * Handle an optimized virtual method call.
7496     *
7497     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7498     */
7499    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7500    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7501    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7502    FETCH(r1, 1)                        @ r1<- BBBB
7503    .if     (!1)
7504    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7505    .endif
7506    GET_VREG(r9, r3)                    @ r9<- vC ("this" ptr)
7507    cmp     r9, #0                      @ is "this" null?
7508    beq     common_errNullObject        @ null "this", throw exception
7509    ldr     r2, [r9, #offObject_clazz]  @ r2<- thisPtr->clazz
7510    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7511    EXPORT_PC()                         @ invoke must export
7512    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7513    bl      common_invokeMethodRange @ (r0=method, r9="this")
7514
7515
7516/* ------------------------------ */
7517    .balign 64
7518.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */
7519/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7520    /*
7521     * Handle an optimized "super" method call.
7522     *
7523     * for: [opt] invoke-super-quick, invoke-super-quick/range
7524     */
7525    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7526    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7527    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7528    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7529    .if     (!0)
7530    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7531    .endif
7532    FETCH(r1, 1)                        @ r1<- BBBB
7533    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7534    EXPORT_PC()                         @ must export for invoke
7535    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7536    GET_VREG(r9, r10)                   @ r9<- "this"
7537    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7538    cmp     r9, #0                      @ null "this" ref?
7539    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7540    beq     common_errNullObject        @ "this" is null, throw exception
7541    bl      common_invokeMethodNoRange @ (r0=method, r9="this")
7542
7543/* ------------------------------ */
7544    .balign 64
7545.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
7546/* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */
7547/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7548    /*
7549     * Handle an optimized "super" method call.
7550     *
7551     * for: [opt] invoke-super-quick, invoke-super-quick/range
7552     */
7553    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7554    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7555    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7556    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7557    .if     (!1)
7558    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7559    .endif
7560    FETCH(r1, 1)                        @ r1<- BBBB
7561    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7562    EXPORT_PC()                         @ must export for invoke
7563    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7564    GET_VREG(r9, r10)                   @ r9<- "this"
7565    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7566    cmp     r9, #0                      @ null "this" ref?
7567    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7568    beq     common_errNullObject        @ "this" is null, throw exception
7569    bl      common_invokeMethodRange @ (r0=method, r9="this")
7570
7571
7572/* ------------------------------ */
7573    .balign 64
7574.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
7575/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */
7576/* File: armv5te/OP_IPUT_OBJECT.S */
7577    /*
7578     * 32-bit instance field put.
7579     *
7580     * for: iput-object, iput-object-volatile
7581     */
7582    /* op vA, vB, field@CCCC */
7583    mov     r0, rINST, lsr #12          @ r0<- B
7584    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7585    FETCH(r1, 1)                        @ r1<- field ref CCCC
7586    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7587    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7588    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7589    cmp     r0, #0                      @ is resolved entry null?
7590    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ no, already resolved
75918:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7592    EXPORT_PC()                         @ resolve() could throw
7593    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7594    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7595    cmp     r0, #0                      @ success?
7596    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ yes, finish up
7597    b       common_exceptionThrown
7598
7599
7600/* ------------------------------ */
7601    .balign 64
7602.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
7603/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */
7604/* File: armv5te/OP_SGET.S */
7605    /*
7606     * General 32-bit SGET handler.
7607     *
7608     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7609     */
7610    /* op vAA, field@BBBB */
7611    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7612    FETCH(r1, 1)                        @ r1<- field ref BBBB
7613    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
7614    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
7615    cmp     r0, #0                      @ is resolved entry null?
7616    beq     .LOP_SGET_OBJECT_VOLATILE_resolve         @ yes, do resolve
7617.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0
7618    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7619    SMP_DMB                            @ acquiring load
7620    mov     r2, rINST, lsr #8           @ r2<- AA
7621    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7622    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7623    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7624    GOTO_OPCODE(ip)                     @ jump to next instruction
7625
7626
7627/* ------------------------------ */
7628    .balign 64
7629.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
7630/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */
7631/* File: armv5te/OP_SPUT_OBJECT.S */
7632    /*
7633     * 32-bit SPUT handler for objects
7634     *
7635     * for: sput-object, sput-object-volatile
7636     */
7637    /* op vAA, field@BBBB */
7638    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7639    FETCH(r1, 1)                        @ r1<- field ref BBBB
7640    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
7641    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
7642    cmp     r0, #0                      @ is resolved entry null?
7643    beq     .LOP_SPUT_OBJECT_VOLATILE_resolve         @ yes, do resolve
7644.LOP_SPUT_OBJECT_VOLATILE_finish:   @ field ptr in r0
7645    mov     r2, rINST, lsr #8           @ r2<- AA
7646    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7647    GET_VREG(r1, r2)                    @ r1<- fp[AA]
7648    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
7649    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
7650    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7651    SMP_DMB_ST                        @ releasing store
7652    b       .LOP_SPUT_OBJECT_VOLATILE_end
7653
7654
7655/* ------------------------------ */
7656    .balign 64
7657.L_OP_UNUSED_FF: /* 0xff */
7658/* File: armv5te/OP_UNUSED_FF.S */
7659/* File: armv5te/unused.S */
7660    bl      common_abort
7661
7662
7663    .balign 64
7664    .size   dvmAsmInstructionStart, .-dvmAsmInstructionStart
7665    .global dvmAsmInstructionEnd
7666dvmAsmInstructionEnd:
7667
7668/*
7669 * ===========================================================================
7670 *  Sister implementations
7671 * ===========================================================================
7672 */
7673    .global dvmAsmSisterStart
7674    .type   dvmAsmSisterStart, %function
7675    .text
7676    .balign 4
7677dvmAsmSisterStart:
7678
7679/* continuation for OP_CONST_STRING */
7680
7681    /*
7682     * Continuation if the String has not yet been resolved.
7683     *  r1: BBBB (String ref)
7684     *  r9: target register
7685     */
7686.LOP_CONST_STRING_resolve:
7687    EXPORT_PC()
7688    ldr     r0, [rSELF, #offThread_method] @ r0<- self->method
7689    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
7690    bl      dvmResolveString            @ r0<- String reference
7691    cmp     r0, #0                      @ failed?
7692    beq     common_exceptionThrown      @ yup, handle the exception
7693    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7694    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7695    SET_VREG(r0, r9)                    @ vAA<- r0
7696    GOTO_OPCODE(ip)                     @ jump to next instruction
7697
7698/* continuation for OP_CONST_STRING_JUMBO */
7699
7700    /*
7701     * Continuation if the String has not yet been resolved.
7702     *  r1: BBBBBBBB (String ref)
7703     *  r9: target register
7704     */
7705.LOP_CONST_STRING_JUMBO_resolve:
7706    EXPORT_PC()
7707    ldr     r0, [rSELF, #offThread_method] @ r0<- self->method
7708    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
7709    bl      dvmResolveString            @ r0<- String reference
7710    cmp     r0, #0                      @ failed?
7711    beq     common_exceptionThrown      @ yup, handle the exception
7712    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7713    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7714    SET_VREG(r0, r9)                    @ vAA<- r0
7715    GOTO_OPCODE(ip)                     @ jump to next instruction
7716
7717/* continuation for OP_CONST_CLASS */
7718
7719    /*
7720     * Continuation if the Class has not yet been resolved.
7721     *  r1: BBBB (Class ref)
7722     *  r9: target register
7723     */
7724.LOP_CONST_CLASS_resolve:
7725    EXPORT_PC()
7726    ldr     r0, [rSELF, #offThread_method] @ r0<- self->method
7727    mov     r2, #1                      @ r2<- true
7728    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
7729    bl      dvmResolveClass             @ r0<- Class reference
7730    cmp     r0, #0                      @ failed?
7731    beq     common_exceptionThrown      @ yup, handle the exception
7732    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7733    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7734    SET_VREG(r0, r9)                    @ vAA<- r0
7735    GOTO_OPCODE(ip)                     @ jump to next instruction
7736
7737/* continuation for OP_CHECK_CAST */
7738
7739    /*
7740     * Trivial test failed, need to perform full check.  This is common.
7741     *  r0 holds obj->clazz
7742     *  r1 holds desired class resolved from BBBB
7743     *  r9 holds object
7744     */
7745.LOP_CHECK_CAST_fullcheck:
7746    mov     r10, r1                     @ avoid ClassObject getting clobbered
7747    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
7748    cmp     r0, #0                      @ failed?
7749    bne     .LOP_CHECK_CAST_okay            @ no, success
7750
7751    @ A cast has failed.  We need to throw a ClassCastException.
7752    EXPORT_PC()                         @ about to throw
7753    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
7754    mov     r1, r10                     @ r1<- desired class
7755    bl      dvmThrowClassCastException
7756    b       common_exceptionThrown
7757
7758    /*
7759     * Resolution required.  This is the least-likely path.
7760     *
7761     *  r2 holds BBBB
7762     *  r9 holds object
7763     */
7764.LOP_CHECK_CAST_resolve:
7765    EXPORT_PC()                         @ resolve() could throw
7766    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
7767    mov     r1, r2                      @ r1<- BBBB
7768    mov     r2, #0                      @ r2<- false
7769    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
7770    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
7771    cmp     r0, #0                      @ got null?
7772    beq     common_exceptionThrown      @ yes, handle exception
7773    mov     r1, r0                      @ r1<- class resolved from BBB
7774    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
7775    b       .LOP_CHECK_CAST_resolved        @ pick up where we left off
7776
7777/* continuation for OP_INSTANCE_OF */
7778
7779    /*
7780     * Trivial test failed, need to perform full check.  This is common.
7781     *  r0 holds obj->clazz
7782     *  r1 holds class resolved from BBBB
7783     *  r9 holds A
7784     */
7785.LOP_INSTANCE_OF_fullcheck:
7786    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
7787    @ fall through to OP_INSTANCE_OF_store
7788
7789    /*
7790     * r0 holds boolean result
7791     * r9 holds A
7792     */
7793.LOP_INSTANCE_OF_store:
7794    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7795    SET_VREG(r0, r9)                    @ vA<- r0
7796    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7797    GOTO_OPCODE(ip)                     @ jump to next instruction
7798
7799    /*
7800     * Trivial test succeeded, save and bail.
7801     *  r9 holds A
7802     */
7803.LOP_INSTANCE_OF_trivial:
7804    mov     r0, #1                      @ indicate success
7805    @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper
7806    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7807    SET_VREG(r0, r9)                    @ vA<- r0
7808    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7809    GOTO_OPCODE(ip)                     @ jump to next instruction
7810
7811    /*
7812     * Resolution required.  This is the least-likely path.
7813     *
7814     *  r3 holds BBBB
7815     *  r9 holds A
7816     */
7817.LOP_INSTANCE_OF_resolve:
7818    EXPORT_PC()                         @ resolve() could throw
7819    ldr     r0, [rSELF, #offThread_method]    @ r0<- self->method
7820    mov     r1, r3                      @ r1<- BBBB
7821    mov     r2, #1                      @ r2<- true
7822    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
7823    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
7824    cmp     r0, #0                      @ got null?
7825    beq     common_exceptionThrown      @ yes, handle exception
7826    mov     r1, r0                      @ r1<- class resolved from BBB
7827    mov     r3, rINST, lsr #12          @ r3<- B
7828    GET_VREG(r0, r3)                    @ r0<- vB (object)
7829    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
7830    b       .LOP_INSTANCE_OF_resolved        @ pick up where we left off
7831
7832/* continuation for OP_NEW_INSTANCE */
7833
7834    .balign 32                          @ minimize cache lines
7835.LOP_NEW_INSTANCE_finish: @ r0=new object
7836    mov     r3, rINST, lsr #8           @ r3<- AA
7837    cmp     r0, #0                      @ failed?
7838#if defined(WITH_JIT)
7839    /*
7840     * The JIT needs the class to be fully resolved before it can
7841     * include this instruction in a trace.
7842     */
7843    ldrh    r1, [rSELF, #offThread_subMode]
7844    beq     common_exceptionThrown      @ yes, handle the exception
7845    ands    r1, #kSubModeJitTraceBuild  @ under construction?
7846    bne     .LOP_NEW_INSTANCE_jitCheck
7847#else
7848    beq     common_exceptionThrown      @ yes, handle the exception
7849#endif
7850.LOP_NEW_INSTANCE_end:
7851    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7852    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7853    SET_VREG(r0, r3)                    @ vAA<- r0
7854    GOTO_OPCODE(ip)                     @ jump to next instruction
7855
7856#if defined(WITH_JIT)
7857    /*
7858     * Check to see if we need to stop the trace building early.
7859     * r0: new object
7860     * r3: vAA
7861     */
7862.LOP_NEW_INSTANCE_jitCheck:
7863    ldr     r1, [r10]                   @ reload resolved class
7864    cmp     r1, #0                      @ okay?
7865    bne     .LOP_NEW_INSTANCE_end             @ yes, finish
7866    mov     r9, r0                      @ preserve new object
7867    mov     r10, r3                     @ preserve vAA
7868    mov     r0, rSELF
7869    mov     r1, rPC
7870    bl      dvmJitEndTraceSelect        @ (self, pc)
7871    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7872    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7873    SET_VREG(r9, r10)                   @ vAA<- new object
7874    GOTO_OPCODE(ip)                     @ jump to next instruction
7875#endif
7876
7877    /*
7878     * Class initialization required.
7879     *
7880     *  r0 holds class object
7881     */
7882.LOP_NEW_INSTANCE_needinit:
7883    mov     r9, r0                      @ save r0
7884    bl      dvmInitClass                @ initialize class
7885    cmp     r0, #0                      @ check boolean result
7886    mov     r0, r9                      @ restore r0
7887    bne     .LOP_NEW_INSTANCE_initialized     @ success, continue
7888    b       common_exceptionThrown      @ failed, deal with init exception
7889
7890    /*
7891     * Resolution required.  This is the least-likely path.
7892     *
7893     *  r1 holds BBBB
7894     */
7895.LOP_NEW_INSTANCE_resolve:
7896    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
7897    mov     r2, #0                      @ r2<- false
7898    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
7899    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
7900    cmp     r0, #0                      @ got null?
7901    bne     .LOP_NEW_INSTANCE_resolved        @ no, continue
7902    b       common_exceptionThrown      @ yes, handle exception
7903
7904/* continuation for OP_NEW_ARRAY */
7905
7906
7907    /*
7908     * Resolve class.  (This is an uncommon case.)
7909     *
7910     *  r1 holds array length
7911     *  r2 holds class ref CCCC
7912     */
7913.LOP_NEW_ARRAY_resolve:
7914    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
7915    mov     r9, r1                      @ r9<- length (save)
7916    mov     r1, r2                      @ r1<- CCCC
7917    mov     r2, #0                      @ r2<- false
7918    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
7919    bl      dvmResolveClass             @ r0<- call(clazz, ref)
7920    cmp     r0, #0                      @ got null?
7921    mov     r1, r9                      @ r1<- length (restore)
7922    beq     common_exceptionThrown      @ yes, handle exception
7923    @ fall through to OP_NEW_ARRAY_finish
7924
7925    /*
7926     * Finish allocation.
7927     *
7928     *  r0 holds class
7929     *  r1 holds array length
7930     */
7931.LOP_NEW_ARRAY_finish:
7932    mov     r2, #ALLOC_DONT_TRACK       @ don't track in local refs table
7933    bl      dvmAllocArrayByClass        @ r0<- call(clazz, length, flags)
7934    cmp     r0, #0                      @ failed?
7935    mov     r2, rINST, lsr #8           @ r2<- A+
7936    beq     common_exceptionThrown      @ yes, handle the exception
7937    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7938    and     r2, r2, #15                 @ r2<- A
7939    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7940    SET_VREG(r0, r2)                    @ vA<- r0
7941    GOTO_OPCODE(ip)                     @ jump to next instruction
7942
7943/* continuation for OP_FILLED_NEW_ARRAY */
7944
7945    /*
7946     * On entry:
7947     *  r0 holds array class
7948     *  r10 holds AA or BA
7949     */
7950.LOP_FILLED_NEW_ARRAY_continue:
7951    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
7952    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
7953    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
7954    .if     0
7955    mov     r1, r10                     @ r1<- AA (length)
7956    .else
7957    mov     r1, r10, lsr #4             @ r1<- B (length)
7958    .endif
7959    cmp     rINST, #'I'                 @ array of ints?
7960    cmpne   rINST, #'L'                 @ array of objects?
7961    cmpne   rINST, #'['                 @ array of arrays?
7962    mov     r9, r1                      @ save length in r9
7963    bne     .LOP_FILLED_NEW_ARRAY_notimpl         @ no, not handled yet
7964    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
7965    cmp     r0, #0                      @ null return?
7966    beq     common_exceptionThrown      @ alloc failed, handle exception
7967
7968    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
7969    str     r0, [rSELF, #offThread_retval]      @ retval.l <- new array
7970    str     rINST, [rSELF, #offThread_retval+4] @ retval.h <- type
7971    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
7972    subs    r9, r9, #1                  @ length--, check for neg
7973    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
7974    bmi     2f                          @ was zero, bail
7975
7976    @ copy values from registers into the array
7977    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
7978    .if     0
7979    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
79801:  ldr     r3, [r2], #4                @ r3<- *r2++
7981    subs    r9, r9, #1                  @ count--
7982    str     r3, [r0], #4                @ *contents++ = vX
7983    bpl     1b
7984    @ continue at 2
7985    .else
7986    cmp     r9, #4                      @ length was initially 5?
7987    and     r2, r10, #15                @ r2<- A
7988    bne     1f                          @ <= 4 args, branch
7989    GET_VREG(r3, r2)                    @ r3<- vA
7990    sub     r9, r9, #1                  @ count--
7991    str     r3, [r0, #16]               @ contents[4] = vA
79921:  and     r2, r1, #15                 @ r2<- F/E/D/C
7993    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
7994    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
7995    subs    r9, r9, #1                  @ count--
7996    str     r3, [r0], #4                @ *contents++ = vX
7997    bpl     1b
7998    @ continue at 2
7999    .endif
8000
80012:
8002    ldr     r0, [rSELF, #offThread_retval]     @ r0<- object
8003    ldr     r1, [rSELF, #offThread_retval+4]   @ r1<- type
8004    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
8005    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
8006    cmp     r1, #'I'                         @ Is int array?
8007    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
8008    GOTO_OPCODE(ip)                          @ execute it
8009
8010    /*
8011     * Throw an exception indicating that we have not implemented this
8012     * mode of filled-new-array.
8013     */
8014.LOP_FILLED_NEW_ARRAY_notimpl:
8015    ldr     r0, .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY
8016    bl      dvmThrowInternalError
8017    b       common_exceptionThrown
8018
8019    /*
8020     * Ideally we'd only define this once, but depending on layout we can
8021     * exceed the range of the load above.
8022     */
8023
8024.L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY:
8025    .word   .LstrFilledNewArrayNotImpl
8026
8027/* continuation for OP_FILLED_NEW_ARRAY_RANGE */
8028
8029    /*
8030     * On entry:
8031     *  r0 holds array class
8032     *  r10 holds AA or BA
8033     */
8034.LOP_FILLED_NEW_ARRAY_RANGE_continue:
8035    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
8036    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
8037    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
8038    .if     1
8039    mov     r1, r10                     @ r1<- AA (length)
8040    .else
8041    mov     r1, r10, lsr #4             @ r1<- B (length)
8042    .endif
8043    cmp     rINST, #'I'                 @ array of ints?
8044    cmpne   rINST, #'L'                 @ array of objects?
8045    cmpne   rINST, #'['                 @ array of arrays?
8046    mov     r9, r1                      @ save length in r9
8047    bne     .LOP_FILLED_NEW_ARRAY_RANGE_notimpl         @ no, not handled yet
8048    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
8049    cmp     r0, #0                      @ null return?
8050    beq     common_exceptionThrown      @ alloc failed, handle exception
8051
8052    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
8053    str     r0, [rSELF, #offThread_retval]      @ retval.l <- new array
8054    str     rINST, [rSELF, #offThread_retval+4] @ retval.h <- type
8055    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
8056    subs    r9, r9, #1                  @ length--, check for neg
8057    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
8058    bmi     2f                          @ was zero, bail
8059
8060    @ copy values from registers into the array
8061    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
8062    .if     1
8063    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
80641:  ldr     r3, [r2], #4                @ r3<- *r2++
8065    subs    r9, r9, #1                  @ count--
8066    str     r3, [r0], #4                @ *contents++ = vX
8067    bpl     1b
8068    @ continue at 2
8069    .else
8070    cmp     r9, #4                      @ length was initially 5?
8071    and     r2, r10, #15                @ r2<- A
8072    bne     1f                          @ <= 4 args, branch
8073    GET_VREG(r3, r2)                    @ r3<- vA
8074    sub     r9, r9, #1                  @ count--
8075    str     r3, [r0, #16]               @ contents[4] = vA
80761:  and     r2, r1, #15                 @ r2<- F/E/D/C
8077    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
8078    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
8079    subs    r9, r9, #1                  @ count--
8080    str     r3, [r0], #4                @ *contents++ = vX
8081    bpl     1b
8082    @ continue at 2
8083    .endif
8084
80852:
8086    ldr     r0, [rSELF, #offThread_retval]     @ r0<- object
8087    ldr     r1, [rSELF, #offThread_retval+4]   @ r1<- type
8088    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
8089    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
8090    cmp     r1, #'I'                         @ Is int array?
8091    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
8092    GOTO_OPCODE(ip)                          @ execute it
8093
8094    /*
8095     * Throw an exception indicating that we have not implemented this
8096     * mode of filled-new-array.
8097     */
8098.LOP_FILLED_NEW_ARRAY_RANGE_notimpl:
8099    ldr     r0, .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY_RANGE
8100    bl      dvmThrowInternalError
8101    b       common_exceptionThrown
8102
8103    /*
8104     * Ideally we'd only define this once, but depending on layout we can
8105     * exceed the range of the load above.
8106     */
8107
8108.L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY_RANGE:
8109    .word   .LstrFilledNewArrayNotImpl
8110
8111/* continuation for OP_CMPL_FLOAT */
8112.LOP_CMPL_FLOAT_finish:
8113    SET_VREG(r0, r9)                    @ vAA<- r0
8114    GOTO_OPCODE(ip)                     @ jump to next instruction
8115
8116/* continuation for OP_CMPG_FLOAT */
8117.LOP_CMPG_FLOAT_finish:
8118    SET_VREG(r0, r9)                    @ vAA<- r0
8119    GOTO_OPCODE(ip)                     @ jump to next instruction
8120
8121/* continuation for OP_CMPL_DOUBLE */
8122.LOP_CMPL_DOUBLE_finish:
8123    SET_VREG(r0, r9)                    @ vAA<- r0
8124    GOTO_OPCODE(ip)                     @ jump to next instruction
8125
8126/* continuation for OP_CMPG_DOUBLE */
8127.LOP_CMPG_DOUBLE_finish:
8128    SET_VREG(r0, r9)                    @ vAA<- r0
8129    GOTO_OPCODE(ip)                     @ jump to next instruction
8130
8131/* continuation for OP_CMP_LONG */
8132
8133.LOP_CMP_LONG_less:
8134    mvn     r1, #0                      @ r1<- -1
8135    @ Want to cond code the next mov so we can avoid branch, but don't see it;
8136    @ instead, we just replicate the tail end.
8137    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8138    SET_VREG(r1, r9)                    @ vAA<- r1
8139    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8140    GOTO_OPCODE(ip)                     @ jump to next instruction
8141
8142.LOP_CMP_LONG_greater:
8143    mov     r1, #1                      @ r1<- 1
8144    @ fall through to _finish
8145
8146.LOP_CMP_LONG_finish:
8147    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8148    SET_VREG(r1, r9)                    @ vAA<- r1
8149    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8150    GOTO_OPCODE(ip)                     @ jump to next instruction
8151
8152/* continuation for OP_AGET_WIDE */
8153
8154.LOP_AGET_WIDE_finish:
8155    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8156    ldrd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
8157    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
8158    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8159    stmia   r9, {r2-r3}                 @ vAA/vAA+1<- r2/r3
8160    GOTO_OPCODE(ip)                     @ jump to next instruction
8161
8162/* continuation for OP_APUT_WIDE */
8163
8164.LOP_APUT_WIDE_finish:
8165    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8166    ldmia   r9, {r2-r3}                 @ r2/r3<- vAA/vAA+1
8167    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8168    strd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
8169    GOTO_OPCODE(ip)                     @ jump to next instruction
8170
8171/* continuation for OP_APUT_OBJECT */
8172    /*
8173     * On entry:
8174     *  rINST = vBB (arrayObj)
8175     *  r9 = vAA (obj)
8176     *  r10 = offset into array (vBB + vCC * width)
8177     */
8178.LOP_APUT_OBJECT_finish:
8179    cmp     r9, #0                      @ storing null reference?
8180    beq     .LOP_APUT_OBJECT_skip_check      @ yes, skip type checks
8181    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
8182    ldr     r1, [rINST, #offObject_clazz]  @ r1<- arrayObj->clazz
8183    bl      dvmCanPutArrayElement       @ test object type vs. array type
8184    cmp     r0, #0                      @ okay?
8185    beq     .LOP_APUT_OBJECT_throw           @ no
8186    mov     r1, rINST                   @ r1<- arrayObj
8187    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8188    ldr     r2, [rSELF, #offThread_cardTable]     @ get biased CT base
8189    add     r10, #offArrayObject_contents   @ r0<- pointer to slot
8190    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8191    str     r9, [r10]                   @ vBB[vCC]<- vAA
8192    strb    r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head
8193    GOTO_OPCODE(ip)                     @ jump to next instruction
8194.LOP_APUT_OBJECT_skip_check:
8195    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8196    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8197    str     r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA
8198    GOTO_OPCODE(ip)                     @ jump to next instruction
8199.LOP_APUT_OBJECT_throw:
8200    @ The types don't match.  We need to throw an ArrayStoreException.
8201    ldr     r0, [r9, #offObject_clazz]
8202    ldr     r1, [rINST, #offObject_clazz]
8203    EXPORT_PC()
8204    bl      dvmThrowArrayStoreExceptionIncompatibleElement
8205    b       common_exceptionThrown
8206
8207/* continuation for OP_IGET */
8208
8209    /*
8210     * Currently:
8211     *  r0 holds resolved field
8212     *  r9 holds object
8213     */
8214.LOP_IGET_finish:
8215    @bl      common_squeak0
8216    cmp     r9, #0                      @ check object for null
8217    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8218    beq     common_errNullObject        @ object was null
8219    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8220    ubfx    r2, rINST, #8, #4           @ r2<- A
8221    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8222    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8223    SET_VREG(r0, r2)                    @ fp[A]<- r0
8224    GOTO_OPCODE(ip)                     @ jump to next instruction
8225
8226/* continuation for OP_IGET_WIDE */
8227
8228    /*
8229     * Currently:
8230     *  r0 holds resolved field
8231     *  r9 holds object
8232     */
8233.LOP_IGET_WIDE_finish:
8234    cmp     r9, #0                      @ check object for null
8235    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8236    beq     common_errNullObject        @ object was null
8237    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
8238    ubfx    r2, rINST, #8, #4           @ r2<- A
8239    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8240    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
8241    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8242    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
8243    GOTO_OPCODE(ip)                     @ jump to next instruction
8244
8245/* continuation for OP_IGET_OBJECT */
8246
8247    /*
8248     * Currently:
8249     *  r0 holds resolved field
8250     *  r9 holds object
8251     */
8252.LOP_IGET_OBJECT_finish:
8253    @bl      common_squeak0
8254    cmp     r9, #0                      @ check object for null
8255    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8256    beq     common_errNullObject        @ object was null
8257    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8258    @ no-op                             @ acquiring load
8259    mov     r2, rINST, lsr #8           @ r2<- A+
8260    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8261    and     r2, r2, #15                 @ r2<- A
8262    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8263    SET_VREG(r0, r2)                    @ fp[A]<- r0
8264    GOTO_OPCODE(ip)                     @ jump to next instruction
8265
8266/* continuation for OP_IGET_BOOLEAN */
8267
8268    /*
8269     * Currently:
8270     *  r0 holds resolved field
8271     *  r9 holds object
8272     */
8273.LOP_IGET_BOOLEAN_finish:
8274    @bl      common_squeak1
8275    cmp     r9, #0                      @ check object for null
8276    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8277    beq     common_errNullObject        @ object was null
8278    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8279    @ no-op                             @ acquiring load
8280    mov     r2, rINST, lsr #8           @ r2<- A+
8281    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8282    and     r2, r2, #15                 @ r2<- A
8283    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8284    SET_VREG(r0, r2)                    @ fp[A]<- r0
8285    GOTO_OPCODE(ip)                     @ jump to next instruction
8286
8287/* continuation for OP_IGET_BYTE */
8288
8289    /*
8290     * Currently:
8291     *  r0 holds resolved field
8292     *  r9 holds object
8293     */
8294.LOP_IGET_BYTE_finish:
8295    @bl      common_squeak2
8296    cmp     r9, #0                      @ check object for null
8297    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8298    beq     common_errNullObject        @ object was null
8299    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8300    @ no-op                             @ acquiring load
8301    mov     r2, rINST, lsr #8           @ r2<- A+
8302    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8303    and     r2, r2, #15                 @ r2<- A
8304    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8305    SET_VREG(r0, r2)                    @ fp[A]<- r0
8306    GOTO_OPCODE(ip)                     @ jump to next instruction
8307
8308/* continuation for OP_IGET_CHAR */
8309
8310    /*
8311     * Currently:
8312     *  r0 holds resolved field
8313     *  r9 holds object
8314     */
8315.LOP_IGET_CHAR_finish:
8316    @bl      common_squeak3
8317    cmp     r9, #0                      @ check object for null
8318    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8319    beq     common_errNullObject        @ object was null
8320    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8321    @ no-op                             @ acquiring load
8322    mov     r2, rINST, lsr #8           @ r2<- A+
8323    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8324    and     r2, r2, #15                 @ r2<- A
8325    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8326    SET_VREG(r0, r2)                    @ fp[A]<- r0
8327    GOTO_OPCODE(ip)                     @ jump to next instruction
8328
8329/* continuation for OP_IGET_SHORT */
8330
8331    /*
8332     * Currently:
8333     *  r0 holds resolved field
8334     *  r9 holds object
8335     */
8336.LOP_IGET_SHORT_finish:
8337    @bl      common_squeak4
8338    cmp     r9, #0                      @ check object for null
8339    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8340    beq     common_errNullObject        @ object was null
8341    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8342    @ no-op                             @ acquiring load
8343    mov     r2, rINST, lsr #8           @ r2<- A+
8344    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8345    and     r2, r2, #15                 @ r2<- A
8346    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8347    SET_VREG(r0, r2)                    @ fp[A]<- r0
8348    GOTO_OPCODE(ip)                     @ jump to next instruction
8349
8350/* continuation for OP_IPUT */
8351
8352    /*
8353     * Currently:
8354     *  r0 holds resolved field
8355     *  r9 holds object
8356     */
8357.LOP_IPUT_finish:
8358    @bl      common_squeak0
8359    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8360    ubfx    r1, rINST, #8, #4           @ r1<- A
8361    cmp     r9, #0                      @ check object for null
8362    GET_VREG(r0, r1)                    @ r0<- fp[A]
8363    beq     common_errNullObject        @ object was null
8364    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8365    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8366    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
8367    GOTO_OPCODE(ip)                     @ jump to next instruction
8368
8369/* continuation for OP_IPUT_WIDE */
8370
8371    /*
8372     * Currently:
8373     *  r0 holds resolved field
8374     *  r9 holds object
8375     */
8376.LOP_IPUT_WIDE_finish:
8377    ubfx    r2, rINST, #8, #4           @ r2<- A
8378    cmp     r9, #0                      @ check object for null
8379    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8380    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
8381    beq     common_errNullObject        @ object was null
8382    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8383    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
8384    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8385    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0
8386    GOTO_OPCODE(ip)                     @ jump to next instruction
8387
8388/* continuation for OP_IPUT_OBJECT */
8389
8390    /*
8391     * Currently:
8392     *  r0 holds resolved field
8393     *  r9 holds object
8394     */
8395.LOP_IPUT_OBJECT_finish:
8396    @bl      common_squeak0
8397    mov     r1, rINST, lsr #8           @ r1<- A+
8398    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8399    and     r1, r1, #15                 @ r1<- A
8400    cmp     r9, #0                      @ check object for null
8401    GET_VREG(r0, r1)                    @ r0<- fp[A]
8402    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
8403    beq     common_errNullObject        @ object was null
8404    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8405    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8406    @ no-op                         @ releasing store
8407    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
8408    @ no-op
8409    cmp     r0, #0                      @ stored a null reference?
8410    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
8411    GOTO_OPCODE(ip)                     @ jump to next instruction
8412
8413/* continuation for OP_IPUT_BOOLEAN */
8414
8415    /*
8416     * Currently:
8417     *  r0 holds resolved field
8418     *  r9 holds object
8419     */
8420.LOP_IPUT_BOOLEAN_finish:
8421    @bl      common_squeak1
8422    mov     r1, rINST, lsr #8           @ r1<- A+
8423    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8424    and     r1, r1, #15                 @ r1<- A
8425    cmp     r9, #0                      @ check object for null
8426    GET_VREG(r0, r1)                    @ r0<- fp[A]
8427    beq     common_errNullObject        @ object was null
8428    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8429    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8430    @ no-op                         @ releasing store
8431    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
8432    @ no-op
8433    GOTO_OPCODE(ip)                     @ jump to next instruction
8434
8435/* continuation for OP_IPUT_BYTE */
8436
8437    /*
8438     * Currently:
8439     *  r0 holds resolved field
8440     *  r9 holds object
8441     */
8442.LOP_IPUT_BYTE_finish:
8443    @bl      common_squeak2
8444    mov     r1, rINST, lsr #8           @ r1<- A+
8445    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8446    and     r1, r1, #15                 @ r1<- A
8447    cmp     r9, #0                      @ check object for null
8448    GET_VREG(r0, r1)                    @ r0<- fp[A]
8449    beq     common_errNullObject        @ object was null
8450    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8451    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8452    @ no-op                         @ releasing store
8453    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
8454    @ no-op
8455    GOTO_OPCODE(ip)                     @ jump to next instruction
8456
8457/* continuation for OP_IPUT_CHAR */
8458
8459    /*
8460     * Currently:
8461     *  r0 holds resolved field
8462     *  r9 holds object
8463     */
8464.LOP_IPUT_CHAR_finish:
8465    @bl      common_squeak3
8466    mov     r1, rINST, lsr #8           @ r1<- A+
8467    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8468    and     r1, r1, #15                 @ r1<- A
8469    cmp     r9, #0                      @ check object for null
8470    GET_VREG(r0, r1)                    @ r0<- fp[A]
8471    beq     common_errNullObject        @ object was null
8472    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8473    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8474    @ no-op                         @ releasing store
8475    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
8476    @ no-op
8477    GOTO_OPCODE(ip)                     @ jump to next instruction
8478
8479/* continuation for OP_IPUT_SHORT */
8480
8481    /*
8482     * Currently:
8483     *  r0 holds resolved field
8484     *  r9 holds object
8485     */
8486.LOP_IPUT_SHORT_finish:
8487    @bl      common_squeak4
8488    mov     r1, rINST, lsr #8           @ r1<- A+
8489    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8490    and     r1, r1, #15                 @ r1<- A
8491    cmp     r9, #0                      @ check object for null
8492    GET_VREG(r0, r1)                    @ r0<- fp[A]
8493    beq     common_errNullObject        @ object was null
8494    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8495    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8496    @ no-op                         @ releasing store
8497    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
8498    @ no-op
8499    GOTO_OPCODE(ip)                     @ jump to next instruction
8500
8501/* continuation for OP_SGET */
8502
8503    /*
8504     * Continuation if the field has not yet been resolved.
8505     *  r1:  BBBB field ref
8506     *  r10: dvmDex->pResFields
8507     */
8508.LOP_SGET_resolve:
8509    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8510#if defined(WITH_JIT)
8511    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8512#endif
8513    EXPORT_PC()                         @ resolve() could throw, so export now
8514    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8515    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8516    cmp     r0, #0                      @ success?
8517    beq     common_exceptionThrown      @ no, handle exception
8518#if defined(WITH_JIT)
8519    /*
8520     * If the JIT is actively building a trace we need to make sure
8521     * that the field is fully resolved before including this instruction.
8522     */
8523    bl      common_verifyField
8524#endif
8525    b       .LOP_SGET_finish
8526
8527/* continuation for OP_SGET_WIDE */
8528
8529    /*
8530     * Continuation if the field has not yet been resolved.
8531     *  r1:  BBBB field ref
8532     *  r10: dvmDex->pResFields
8533     *
8534     * Returns StaticField pointer in r0.
8535     */
8536.LOP_SGET_WIDE_resolve:
8537    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8538#if defined(WITH_JIT)
8539    add     r10, r10, r1, lsl #2        @ r1<- &dvmDex->pResFields[field]
8540#endif
8541    EXPORT_PC()                         @ resolve() could throw, so export now
8542    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8543    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8544    cmp     r0, #0                      @ success?
8545    beq     common_exceptionThrown      @ no, handle exception
8546#if defined(WITH_JIT)
8547    /*
8548     * If the JIT is actively building a trace we need to make sure
8549     * that the field is fully resolved before including this instruction.
8550     */
8551    bl      common_verifyField
8552#endif
8553    b       .LOP_SGET_WIDE_finish          @ resume
8554
8555/* continuation for OP_SGET_OBJECT */
8556
8557    /*
8558     * Continuation if the field has not yet been resolved.
8559     *  r1:  BBBB field ref
8560     *  r10: dvmDex->pResFields
8561     */
8562.LOP_SGET_OBJECT_resolve:
8563    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8564#if defined(WITH_JIT)
8565    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8566#endif
8567    EXPORT_PC()                         @ resolve() could throw, so export now
8568    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8569    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8570    cmp     r0, #0                      @ success?
8571    beq     common_exceptionThrown      @ no, handle exception
8572#if defined(WITH_JIT)
8573    /*
8574     * If the JIT is actively building a trace we need to make sure
8575     * that the field is fully resolved before including this instruction.
8576     */
8577    bl      common_verifyField
8578#endif
8579    b       .LOP_SGET_OBJECT_finish
8580
8581/* continuation for OP_SGET_BOOLEAN */
8582
8583    /*
8584     * Continuation if the field has not yet been resolved.
8585     *  r1:  BBBB field ref
8586     *  r10: dvmDex->pResFields
8587     */
8588.LOP_SGET_BOOLEAN_resolve:
8589    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8590#if defined(WITH_JIT)
8591    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8592#endif
8593    EXPORT_PC()                         @ resolve() could throw, so export now
8594    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8595    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8596    cmp     r0, #0                      @ success?
8597    beq     common_exceptionThrown      @ no, handle exception
8598#if defined(WITH_JIT)
8599    /*
8600     * If the JIT is actively building a trace we need to make sure
8601     * that the field is fully resolved before including this instruction.
8602     */
8603    bl      common_verifyField
8604#endif
8605    b       .LOP_SGET_BOOLEAN_finish
8606
8607/* continuation for OP_SGET_BYTE */
8608
8609    /*
8610     * Continuation if the field has not yet been resolved.
8611     *  r1:  BBBB field ref
8612     *  r10: dvmDex->pResFields
8613     */
8614.LOP_SGET_BYTE_resolve:
8615    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8616#if defined(WITH_JIT)
8617    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8618#endif
8619    EXPORT_PC()                         @ resolve() could throw, so export now
8620    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8621    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8622    cmp     r0, #0                      @ success?
8623    beq     common_exceptionThrown      @ no, handle exception
8624#if defined(WITH_JIT)
8625    /*
8626     * If the JIT is actively building a trace we need to make sure
8627     * that the field is fully resolved before including this instruction.
8628     */
8629    bl      common_verifyField
8630#endif
8631    b       .LOP_SGET_BYTE_finish
8632
8633/* continuation for OP_SGET_CHAR */
8634
8635    /*
8636     * Continuation if the field has not yet been resolved.
8637     *  r1:  BBBB field ref
8638     *  r10: dvmDex->pResFields
8639     */
8640.LOP_SGET_CHAR_resolve:
8641    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8642#if defined(WITH_JIT)
8643    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8644#endif
8645    EXPORT_PC()                         @ resolve() could throw, so export now
8646    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8647    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8648    cmp     r0, #0                      @ success?
8649    beq     common_exceptionThrown      @ no, handle exception
8650#if defined(WITH_JIT)
8651    /*
8652     * If the JIT is actively building a trace we need to make sure
8653     * that the field is fully resolved before including this instruction.
8654     */
8655    bl      common_verifyField
8656#endif
8657    b       .LOP_SGET_CHAR_finish
8658
8659/* continuation for OP_SGET_SHORT */
8660
8661    /*
8662     * Continuation if the field has not yet been resolved.
8663     *  r1:  BBBB field ref
8664     *  r10: dvmDex->pResFields
8665     */
8666.LOP_SGET_SHORT_resolve:
8667    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8668#if defined(WITH_JIT)
8669    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8670#endif
8671    EXPORT_PC()                         @ resolve() could throw, so export now
8672    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8673    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8674    cmp     r0, #0                      @ success?
8675    beq     common_exceptionThrown      @ no, handle exception
8676#if defined(WITH_JIT)
8677    /*
8678     * If the JIT is actively building a trace we need to make sure
8679     * that the field is fully resolved before including this instruction.
8680     */
8681    bl      common_verifyField
8682#endif
8683    b       .LOP_SGET_SHORT_finish
8684
8685/* continuation for OP_SPUT */
8686
8687    /*
8688     * Continuation if the field has not yet been resolved.
8689     *  r1:  BBBB field ref
8690     *  r10: dvmDex->pResFields
8691     */
8692.LOP_SPUT_resolve:
8693    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8694#if defined(WITH_JIT)
8695    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8696#endif
8697    EXPORT_PC()                         @ resolve() could throw, so export now
8698    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8699    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8700    cmp     r0, #0                      @ success?
8701    beq     common_exceptionThrown      @ no, handle exception
8702#if defined(WITH_JIT)
8703    /*
8704     * If the JIT is actively building a trace we need to make sure
8705     * that the field is fully resolved before including this instruction.
8706     */
8707    bl      common_verifyField
8708#endif
8709    b       .LOP_SPUT_finish          @ resume
8710
8711/* continuation for OP_SPUT_WIDE */
8712
8713    /*
8714     * Continuation if the field has not yet been resolved.
8715     *  r1:  BBBB field ref
8716     *  r9:  &fp[AA]
8717     *  r10: dvmDex->pResFields
8718     *
8719     * Returns StaticField pointer in r2.
8720     */
8721.LOP_SPUT_WIDE_resolve:
8722    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8723#if defined(WITH_JIT)
8724    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8725#endif
8726    EXPORT_PC()                         @ resolve() could throw, so export now
8727    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8728    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8729    cmp     r0, #0                      @ success?
8730    mov     r2, r0                      @ copy to r2
8731    beq     common_exceptionThrown      @ no, handle exception
8732#if defined(WITH_JIT)
8733    /*
8734     * If the JIT is actively building a trace we need to make sure
8735     * that the field is fully resolved before including this instruction.
8736     */
8737    bl      common_verifyField
8738#endif
8739    b       .LOP_SPUT_WIDE_finish          @ resume
8740
8741/* continuation for OP_SPUT_OBJECT */
8742
8743
8744.LOP_SPUT_OBJECT_end:
8745    str     r1, [r0, #offStaticField_value]  @ field<- vAA
8746    @ no-op
8747    cmp     r1, #0                      @ stored a null object?
8748    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
8749    GOTO_OPCODE(ip)                     @ jump to next instruction
8750
8751    /* Continuation if the field has not yet been resolved.
8752     * r1:  BBBB field ref
8753     * r10: dvmDex->pResFields
8754     */
8755.LOP_SPUT_OBJECT_resolve:
8756    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8757#if defined(WITH_JIT)
8758    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8759#endif
8760    EXPORT_PC()                         @ resolve() could throw, so export now
8761    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8762    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8763    cmp     r0, #0                      @ success?
8764    beq     common_exceptionThrown      @ no, handle exception
8765#if defined(WITH_JIT)
8766    /*
8767     * If the JIT is actively building a trace we need to make sure
8768     * that the field is fully resolved before including this instruction.
8769     */
8770    bl      common_verifyField
8771#endif
8772    b       .LOP_SPUT_OBJECT_finish          @ resume
8773
8774
8775/* continuation for OP_SPUT_BOOLEAN */
8776
8777    /*
8778     * Continuation if the field has not yet been resolved.
8779     *  r1:  BBBB field ref
8780     *  r10: dvmDex->pResFields
8781     */
8782.LOP_SPUT_BOOLEAN_resolve:
8783    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8784#if defined(WITH_JIT)
8785    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8786#endif
8787    EXPORT_PC()                         @ resolve() could throw, so export now
8788    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8789    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8790    cmp     r0, #0                      @ success?
8791    beq     common_exceptionThrown      @ no, handle exception
8792#if defined(WITH_JIT)
8793    /*
8794     * If the JIT is actively building a trace we need to make sure
8795     * that the field is fully resolved before including this instruction.
8796     */
8797    bl      common_verifyField
8798#endif
8799    b       .LOP_SPUT_BOOLEAN_finish          @ resume
8800
8801/* continuation for OP_SPUT_BYTE */
8802
8803    /*
8804     * Continuation if the field has not yet been resolved.
8805     *  r1:  BBBB field ref
8806     *  r10: dvmDex->pResFields
8807     */
8808.LOP_SPUT_BYTE_resolve:
8809    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8810#if defined(WITH_JIT)
8811    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8812#endif
8813    EXPORT_PC()                         @ resolve() could throw, so export now
8814    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8815    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8816    cmp     r0, #0                      @ success?
8817    beq     common_exceptionThrown      @ no, handle exception
8818#if defined(WITH_JIT)
8819    /*
8820     * If the JIT is actively building a trace we need to make sure
8821     * that the field is fully resolved before including this instruction.
8822     */
8823    bl      common_verifyField
8824#endif
8825    b       .LOP_SPUT_BYTE_finish          @ resume
8826
8827/* continuation for OP_SPUT_CHAR */
8828
8829    /*
8830     * Continuation if the field has not yet been resolved.
8831     *  r1:  BBBB field ref
8832     *  r10: dvmDex->pResFields
8833     */
8834.LOP_SPUT_CHAR_resolve:
8835    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8836#if defined(WITH_JIT)
8837    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8838#endif
8839    EXPORT_PC()                         @ resolve() could throw, so export now
8840    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8841    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8842    cmp     r0, #0                      @ success?
8843    beq     common_exceptionThrown      @ no, handle exception
8844#if defined(WITH_JIT)
8845    /*
8846     * If the JIT is actively building a trace we need to make sure
8847     * that the field is fully resolved before including this instruction.
8848     */
8849    bl      common_verifyField
8850#endif
8851    b       .LOP_SPUT_CHAR_finish          @ resume
8852
8853/* continuation for OP_SPUT_SHORT */
8854
8855    /*
8856     * Continuation if the field has not yet been resolved.
8857     *  r1:  BBBB field ref
8858     *  r10: dvmDex->pResFields
8859     */
8860.LOP_SPUT_SHORT_resolve:
8861    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
8862#if defined(WITH_JIT)
8863    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
8864#endif
8865    EXPORT_PC()                         @ resolve() could throw, so export now
8866    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
8867    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
8868    cmp     r0, #0                      @ success?
8869    beq     common_exceptionThrown      @ no, handle exception
8870#if defined(WITH_JIT)
8871    /*
8872     * If the JIT is actively building a trace we need to make sure
8873     * that the field is fully resolved before including this instruction.
8874     */
8875    bl      common_verifyField
8876#endif
8877    b       .LOP_SPUT_SHORT_finish          @ resume
8878
8879/* continuation for OP_INVOKE_VIRTUAL */
8880
8881    /*
8882     * At this point:
8883     *  r0 = resolved base method
8884     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
8885     */
8886.LOP_INVOKE_VIRTUAL_continue:
8887    GET_VREG(r9, r10)                   @ r9<- "this" ptr
8888    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
8889    cmp     r9, #0                      @ is "this" null?
8890    beq     common_errNullObject        @ null "this", throw exception
8891    ldr     r3, [r9, #offObject_clazz]  @ r3<- thisPtr->clazz
8892    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
8893    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
8894    bl      common_invokeMethodNoRange @ (r0=method, r9="this")
8895
8896/* continuation for OP_INVOKE_SUPER */
8897
8898    /*
8899     * At this point:
8900     *  r0 = resolved base method
8901     *  r10 = method->clazz
8902     */
8903.LOP_INVOKE_SUPER_continue:
8904    ldr     r1, [r10, #offClassObject_super]    @ r1<- method->clazz->super
8905    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
8906    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
8907    EXPORT_PC()                         @ must export for invoke
8908    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
8909    bcs     .LOP_INVOKE_SUPER_nsm             @ method not present in superclass
8910    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
8911    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
8912    bl      common_invokeMethodNoRange @ continue on
8913
8914.LOP_INVOKE_SUPER_resolve:
8915    mov     r0, r10                     @ r0<- method->clazz
8916    mov     r2, #METHOD_VIRTUAL         @ resolver method type
8917    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8918    cmp     r0, #0                      @ got null?
8919    bne     .LOP_INVOKE_SUPER_continue        @ no, continue
8920    b       common_exceptionThrown      @ yes, handle exception
8921
8922    /*
8923     * Throw a NoSuchMethodError with the method name as the message.
8924     *  r0 = resolved base method
8925     */
8926.LOP_INVOKE_SUPER_nsm:
8927    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
8928    b       common_errNoSuchMethod
8929
8930/* continuation for OP_INVOKE_DIRECT */
8931
8932    /*
8933     * On entry:
8934     *  r1 = reference (BBBB or CCCC)
8935     *  r10 = "this" register
8936     */
8937.LOP_INVOKE_DIRECT_resolve:
8938    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
8939    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8940    mov     r2, #METHOD_DIRECT          @ resolver method type
8941    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8942    cmp     r0, #0                      @ got null?
8943    bne     .LOP_INVOKE_DIRECT_finish          @ no, continue
8944    b       common_exceptionThrown      @ yes, handle exception
8945
8946/* continuation for OP_INVOKE_STATIC */
8947
8948
8949.LOP_INVOKE_STATIC_resolve:
8950    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
8951    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8952    mov     r2, #METHOD_STATIC          @ resolver method type
8953    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
8954    cmp     r0, #0                      @ got null?
8955#if defined(WITH_JIT)
8956    /*
8957     * Check to see if we're actively building a trace.  If so,
8958     * we need to keep this instruction out of it.
8959     * r10: &resolved_methodToCall
8960     */
8961    ldrh    r2, [rSELF, #offThread_subMode]
8962    beq     common_exceptionThrown            @ null, handle exception
8963    ands    r2, #kSubModeJitTraceBuild        @ trace under construction?
8964    beq     common_invokeMethodNoRange     @ no (r0=method, r9="this")
8965    ldr     r1, [r10]                         @ reload resolved method
8966    cmp     r1, #0                            @ finished resolving?
8967    bne     common_invokeMethodNoRange     @ yes (r0=method, r9="this")
8968    mov     r10, r0                           @ preserve method
8969    mov     r0, rSELF
8970    mov     r1, rPC
8971    bl      dvmJitEndTraceSelect              @ (self, pc)
8972    mov     r0, r10
8973    b       common_invokeMethodNoRange     @ whew, finally!
8974#else
8975    bne     common_invokeMethodNoRange     @ (r0=method, r9="this")
8976    b       common_exceptionThrown            @ yes, handle exception
8977#endif
8978
8979/* continuation for OP_INVOKE_VIRTUAL_RANGE */
8980
8981    /*
8982     * At this point:
8983     *  r0 = resolved base method
8984     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
8985     */
8986.LOP_INVOKE_VIRTUAL_RANGE_continue:
8987    GET_VREG(r9, r10)                   @ r9<- "this" ptr
8988    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
8989    cmp     r9, #0                      @ is "this" null?
8990    beq     common_errNullObject        @ null "this", throw exception
8991    ldr     r3, [r9, #offObject_clazz]  @ r3<- thisPtr->clazz
8992    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
8993    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
8994    bl      common_invokeMethodRange @ (r0=method, r9="this")
8995
8996/* continuation for OP_INVOKE_SUPER_RANGE */
8997
8998    /*
8999     * At this point:
9000     *  r0 = resolved base method
9001     *  r10 = method->clazz
9002     */
9003.LOP_INVOKE_SUPER_RANGE_continue:
9004    ldr     r1, [r10, #offClassObject_super]    @ r1<- method->clazz->super
9005    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
9006    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
9007    EXPORT_PC()                         @ must export for invoke
9008    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
9009    bcs     .LOP_INVOKE_SUPER_RANGE_nsm             @ method not present in superclass
9010    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
9011    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
9012    bl      common_invokeMethodRange @ continue on
9013
9014.LOP_INVOKE_SUPER_RANGE_resolve:
9015    mov     r0, r10                     @ r0<- method->clazz
9016    mov     r2, #METHOD_VIRTUAL         @ resolver method type
9017    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
9018    cmp     r0, #0                      @ got null?
9019    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ no, continue
9020    b       common_exceptionThrown      @ yes, handle exception
9021
9022    /*
9023     * Throw a NoSuchMethodError with the method name as the message.
9024     *  r0 = resolved base method
9025     */
9026.LOP_INVOKE_SUPER_RANGE_nsm:
9027    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
9028    b       common_errNoSuchMethod
9029
9030/* continuation for OP_INVOKE_DIRECT_RANGE */
9031
9032    /*
9033     * On entry:
9034     *  r1 = reference (BBBB or CCCC)
9035     *  r10 = "this" register
9036     */
9037.LOP_INVOKE_DIRECT_RANGE_resolve:
9038    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
9039    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
9040    mov     r2, #METHOD_DIRECT          @ resolver method type
9041    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
9042    cmp     r0, #0                      @ got null?
9043    bne     .LOP_INVOKE_DIRECT_RANGE_finish          @ no, continue
9044    b       common_exceptionThrown      @ yes, handle exception
9045
9046/* continuation for OP_INVOKE_STATIC_RANGE */
9047
9048
9049.LOP_INVOKE_STATIC_RANGE_resolve:
9050    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
9051    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
9052    mov     r2, #METHOD_STATIC          @ resolver method type
9053    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
9054    cmp     r0, #0                      @ got null?
9055#if defined(WITH_JIT)
9056    /*
9057     * Check to see if we're actively building a trace.  If so,
9058     * we need to keep this instruction out of it.
9059     * r10: &resolved_methodToCall
9060     */
9061    ldrh    r2, [rSELF, #offThread_subMode]
9062    beq     common_exceptionThrown            @ null, handle exception
9063    ands    r2, #kSubModeJitTraceBuild        @ trace under construction?
9064    beq     common_invokeMethodRange     @ no (r0=method, r9="this")
9065    ldr     r1, [r10]                         @ reload resolved method
9066    cmp     r1, #0                            @ finished resolving?
9067    bne     common_invokeMethodRange     @ yes (r0=method, r9="this")
9068    mov     r10, r0                           @ preserve method
9069    mov     r0, rSELF
9070    mov     r1, rPC
9071    bl      dvmJitEndTraceSelect              @ (self, pc)
9072    mov     r0, r10
9073    b       common_invokeMethodRange     @ whew, finally!
9074#else
9075    bne     common_invokeMethodRange     @ (r0=method, r9="this")
9076    b       common_exceptionThrown            @ yes, handle exception
9077#endif
9078
9079/* continuation for OP_FLOAT_TO_LONG */
9080/*
9081 * Convert the float in r0 to a long in r0/r1.
9082 *
9083 * We have to clip values to long min/max per the specification.  The
9084 * expected common case is a "reasonable" value that converts directly
9085 * to modest integer.  The EABI convert function isn't doing this for us.
9086 */
9087f2l_doconv:
9088    stmfd   sp!, {r4, lr}
9089    mov     r1, #0x5f000000             @ (float)maxlong
9090    mov     r4, r0
9091    bl      __aeabi_fcmpge              @ is arg >= maxlong?
9092    cmp     r0, #0                      @ nonzero == yes
9093    mvnne   r0, #0                      @ return maxlong (7fffffff)
9094    mvnne   r1, #0x80000000
9095    ldmnefd sp!, {r4, pc}
9096
9097    mov     r0, r4                      @ recover arg
9098    mov     r1, #0xdf000000             @ (float)minlong
9099    bl      __aeabi_fcmple              @ is arg <= minlong?
9100    cmp     r0, #0                      @ nonzero == yes
9101    movne   r0, #0                      @ return minlong (80000000)
9102    movne   r1, #0x80000000
9103    ldmnefd sp!, {r4, pc}
9104
9105    mov     r0, r4                      @ recover arg
9106    mov     r1, r4
9107    bl      __aeabi_fcmpeq              @ is arg == self?
9108    cmp     r0, #0                      @ zero == no
9109    moveq   r1, #0                      @ return zero for NaN
9110    ldmeqfd sp!, {r4, pc}
9111
9112    mov     r0, r4                      @ recover arg
9113    bl      __aeabi_f2lz                @ convert float to long
9114    ldmfd   sp!, {r4, pc}
9115
9116/* continuation for OP_DOUBLE_TO_LONG */
9117/*
9118 * Convert the double in r0/r1 to a long in r0/r1.
9119 *
9120 * We have to clip values to long min/max per the specification.  The
9121 * expected common case is a "reasonable" value that converts directly
9122 * to modest integer.  The EABI convert function isn't doing this for us.
9123 */
9124d2l_doconv:
9125    stmfd   sp!, {r4, r5, lr}           @ save regs
9126    mov     r3, #0x43000000             @ maxlong, as a double (high word)
9127    add     r3, #0x00e00000             @  0x43e00000
9128    mov     r2, #0                      @ maxlong, as a double (low word)
9129    sub     sp, sp, #4                  @ align for EABI
9130    mov     r4, r0                      @ save a copy of r0
9131    mov     r5, r1                      @  and r1
9132    bl      __aeabi_dcmpge              @ is arg >= maxlong?
9133    cmp     r0, #0                      @ nonzero == yes
9134    mvnne   r0, #0                      @ return maxlong (7fffffffffffffff)
9135    mvnne   r1, #0x80000000
9136    bne     1f
9137
9138    mov     r0, r4                      @ recover arg
9139    mov     r1, r5
9140    mov     r3, #0xc3000000             @ minlong, as a double (high word)
9141    add     r3, #0x00e00000             @  0xc3e00000
9142    mov     r2, #0                      @ minlong, as a double (low word)
9143    bl      __aeabi_dcmple              @ is arg <= minlong?
9144    cmp     r0, #0                      @ nonzero == yes
9145    movne   r0, #0                      @ return minlong (8000000000000000)
9146    movne   r1, #0x80000000
9147    bne     1f
9148
9149    mov     r0, r4                      @ recover arg
9150    mov     r1, r5
9151    mov     r2, r4                      @ compare against self
9152    mov     r3, r5
9153    bl      __aeabi_dcmpeq              @ is arg == self?
9154    cmp     r0, #0                      @ zero == no
9155    moveq   r1, #0                      @ return zero for NaN
9156    beq     1f
9157
9158    mov     r0, r4                      @ recover arg
9159    mov     r1, r5
9160    bl      __aeabi_d2lz                @ convert double to long
9161
91621:
9163    add     sp, sp, #4
9164    ldmfd   sp!, {r4, r5, pc}
9165
9166/* continuation for OP_MUL_LONG */
9167
9168.LOP_MUL_LONG_finish:
9169    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9170    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
9171    GOTO_OPCODE(ip)                     @ jump to next instruction
9172
9173/* continuation for OP_SHL_LONG */
9174
9175.LOP_SHL_LONG_finish:
9176    mov     r0, r0, asl r2              @  r0<- r0 << r2
9177    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9178    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9179    GOTO_OPCODE(ip)                     @ jump to next instruction
9180
9181/* continuation for OP_SHR_LONG */
9182
9183.LOP_SHR_LONG_finish:
9184    mov     r1, r1, asr r2              @  r1<- r1 >> r2
9185    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9186    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9187    GOTO_OPCODE(ip)                     @ jump to next instruction
9188
9189/* continuation for OP_USHR_LONG */
9190
9191.LOP_USHR_LONG_finish:
9192    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
9193    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9194    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9195    GOTO_OPCODE(ip)                     @ jump to next instruction
9196
9197/* continuation for OP_SHL_LONG_2ADDR */
9198
9199.LOP_SHL_LONG_2ADDR_finish:
9200    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9201    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9202    GOTO_OPCODE(ip)                     @ jump to next instruction
9203
9204/* continuation for OP_SHR_LONG_2ADDR */
9205
9206.LOP_SHR_LONG_2ADDR_finish:
9207    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9208    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9209    GOTO_OPCODE(ip)                     @ jump to next instruction
9210
9211/* continuation for OP_USHR_LONG_2ADDR */
9212
9213.LOP_USHR_LONG_2ADDR_finish:
9214    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9215    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9216    GOTO_OPCODE(ip)                     @ jump to next instruction
9217
9218/* continuation for OP_IGET_VOLATILE */
9219
9220    /*
9221     * Currently:
9222     *  r0 holds resolved field
9223     *  r9 holds object
9224     */
9225.LOP_IGET_VOLATILE_finish:
9226    @bl      common_squeak0
9227    cmp     r9, #0                      @ check object for null
9228    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9229    beq     common_errNullObject        @ object was null
9230    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
9231    SMP_DMB                            @ acquiring load
9232    mov     r2, rINST, lsr #8           @ r2<- A+
9233    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9234    and     r2, r2, #15                 @ r2<- A
9235    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9236    SET_VREG(r0, r2)                    @ fp[A]<- r0
9237    GOTO_OPCODE(ip)                     @ jump to next instruction
9238
9239/* continuation for OP_IPUT_VOLATILE */
9240
9241    /*
9242     * Currently:
9243     *  r0 holds resolved field
9244     *  r9 holds object
9245     */
9246.LOP_IPUT_VOLATILE_finish:
9247    @bl      common_squeak0
9248    mov     r1, rINST, lsr #8           @ r1<- A+
9249    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9250    and     r1, r1, #15                 @ r1<- A
9251    cmp     r9, #0                      @ check object for null
9252    GET_VREG(r0, r1)                    @ r0<- fp[A]
9253    beq     common_errNullObject        @ object was null
9254    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9255    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9256    SMP_DMB_ST                        @ releasing store
9257    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
9258    SMP_DMB
9259    GOTO_OPCODE(ip)                     @ jump to next instruction
9260
9261/* continuation for OP_SGET_VOLATILE */
9262
9263    /*
9264     * Continuation if the field has not yet been resolved.
9265     *  r1:  BBBB field ref
9266     *  r10: dvmDex->pResFields
9267     */
9268.LOP_SGET_VOLATILE_resolve:
9269    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9270#if defined(WITH_JIT)
9271    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9272#endif
9273    EXPORT_PC()                         @ resolve() could throw, so export now
9274    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9275    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9276    cmp     r0, #0                      @ success?
9277    beq     common_exceptionThrown      @ no, handle exception
9278#if defined(WITH_JIT)
9279    /*
9280     * If the JIT is actively building a trace we need to make sure
9281     * that the field is fully resolved before including this instruction.
9282     */
9283    bl      common_verifyField
9284#endif
9285    b       .LOP_SGET_VOLATILE_finish
9286
9287/* continuation for OP_SPUT_VOLATILE */
9288
9289    /*
9290     * Continuation if the field has not yet been resolved.
9291     *  r1:  BBBB field ref
9292     *  r10: dvmDex->pResFields
9293     */
9294.LOP_SPUT_VOLATILE_resolve:
9295    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9296#if defined(WITH_JIT)
9297    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9298#endif
9299    EXPORT_PC()                         @ resolve() could throw, so export now
9300    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9301    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9302    cmp     r0, #0                      @ success?
9303    beq     common_exceptionThrown      @ no, handle exception
9304#if defined(WITH_JIT)
9305    /*
9306     * If the JIT is actively building a trace we need to make sure
9307     * that the field is fully resolved before including this instruction.
9308     */
9309    bl      common_verifyField
9310#endif
9311    b       .LOP_SPUT_VOLATILE_finish          @ resume
9312
9313/* continuation for OP_IGET_OBJECT_VOLATILE */
9314
9315    /*
9316     * Currently:
9317     *  r0 holds resolved field
9318     *  r9 holds object
9319     */
9320.LOP_IGET_OBJECT_VOLATILE_finish:
9321    @bl      common_squeak0
9322    cmp     r9, #0                      @ check object for null
9323    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9324    beq     common_errNullObject        @ object was null
9325    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
9326    SMP_DMB                            @ acquiring load
9327    mov     r2, rINST, lsr #8           @ r2<- A+
9328    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9329    and     r2, r2, #15                 @ r2<- A
9330    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9331    SET_VREG(r0, r2)                    @ fp[A]<- r0
9332    GOTO_OPCODE(ip)                     @ jump to next instruction
9333
9334/* continuation for OP_IGET_WIDE_VOLATILE */
9335
9336    /*
9337     * Currently:
9338     *  r0 holds resolved field
9339     *  r9 holds object
9340     */
9341.LOP_IGET_WIDE_VOLATILE_finish:
9342    cmp     r9, #0                      @ check object for null
9343    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9344    beq     common_errNullObject        @ object was null
9345    .if     1
9346    add     r0, r9, r3                  @ r0<- address of field
9347    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
9348    .else
9349    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
9350    .endif
9351    mov     r2, rINST, lsr #8           @ r2<- A+
9352    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9353    and     r2, r2, #15                 @ r2<- A
9354    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
9355    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9356    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
9357    GOTO_OPCODE(ip)                     @ jump to next instruction
9358
9359/* continuation for OP_IPUT_WIDE_VOLATILE */
9360
9361    /*
9362     * Currently:
9363     *  r0 holds resolved field
9364     *  r9 holds object
9365     */
9366.LOP_IPUT_WIDE_VOLATILE_finish:
9367    mov     r2, rINST, lsr #8           @ r2<- A+
9368    cmp     r9, #0                      @ check object for null
9369    and     r2, r2, #15                 @ r2<- A
9370    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9371    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
9372    beq     common_errNullObject        @ object was null
9373    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9374    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
9375    GET_INST_OPCODE(r10)                @ extract opcode from rINST
9376    .if     1
9377    add     r2, r9, r3                  @ r2<- target address
9378    bl      dvmQuasiAtomicSwap64Sync    @ stores r0/r1 into addr r2
9379    .else
9380    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
9381    .endif
9382    GOTO_OPCODE(r10)                    @ jump to next instruction
9383
9384/* continuation for OP_SGET_WIDE_VOLATILE */
9385
9386    /*
9387     * Continuation if the field has not yet been resolved.
9388     *  r1:  BBBB field ref
9389     *  r10: dvmDex->pResFields
9390     *
9391     * Returns StaticField pointer in r0.
9392     */
9393.LOP_SGET_WIDE_VOLATILE_resolve:
9394    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9395#if defined(WITH_JIT)
9396    add     r10, r10, r1, lsl #2        @ r1<- &dvmDex->pResFields[field]
9397#endif
9398    EXPORT_PC()                         @ resolve() could throw, so export now
9399    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9400    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9401    cmp     r0, #0                      @ success?
9402    beq     common_exceptionThrown      @ no, handle exception
9403#if defined(WITH_JIT)
9404    /*
9405     * If the JIT is actively building a trace we need to make sure
9406     * that the field is fully resolved before including this instruction.
9407     */
9408    bl      common_verifyField
9409#endif
9410    b       .LOP_SGET_WIDE_VOLATILE_finish          @ resume
9411
9412/* continuation for OP_SPUT_WIDE_VOLATILE */
9413
9414    /*
9415     * Continuation if the field has not yet been resolved.
9416     *  r1:  BBBB field ref
9417     *  r9:  &fp[AA]
9418     *  r10: dvmDex->pResFields
9419     *
9420     * Returns StaticField pointer in r2.
9421     */
9422.LOP_SPUT_WIDE_VOLATILE_resolve:
9423    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9424#if defined(WITH_JIT)
9425    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9426#endif
9427    EXPORT_PC()                         @ resolve() could throw, so export now
9428    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9429    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9430    cmp     r0, #0                      @ success?
9431    mov     r2, r0                      @ copy to r2
9432    beq     common_exceptionThrown      @ no, handle exception
9433#if defined(WITH_JIT)
9434    /*
9435     * If the JIT is actively building a trace we need to make sure
9436     * that the field is fully resolved before including this instruction.
9437     */
9438    bl      common_verifyField
9439#endif
9440    b       .LOP_SPUT_WIDE_VOLATILE_finish          @ resume
9441
9442/* continuation for OP_EXECUTE_INLINE */
9443
9444    /*
9445     * Extract args, call function.
9446     *  r0 = #of args (0-4)
9447     *  r10 = call index
9448     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
9449     *
9450     * Other ideas:
9451     * - Use a jump table from the main piece to jump directly into the
9452     *   AND/LDR pairs.  Costs a data load, saves a branch.
9453     * - Have five separate pieces that do the loading, so we can work the
9454     *   interleave a little better.  Increases code size.
9455     */
9456.LOP_EXECUTE_INLINE_continue:
9457    rsb     r0, r0, #4                  @ r0<- 4-r0
9458    FETCH(rINST, 2)                     @ rINST<- FEDC
9459    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
9460    bl      common_abort                @ (skipped due to ARM prefetch)
94614:  and     ip, rINST, #0xf000          @ isolate F
9462    ldr     r3, [rFP, ip, lsr #10]      @ r3<- vF (shift right 12, left 2)
94633:  and     ip, rINST, #0x0f00          @ isolate E
9464    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vE
94652:  and     ip, rINST, #0x00f0          @ isolate D
9466    ldr     r1, [rFP, ip, lsr #2]       @ r1<- vD
94671:  and     ip, rINST, #0x000f          @ isolate C
9468    ldr     r0, [rFP, ip, lsl #2]       @ r0<- vC
94690:
9470    ldr     rINST, .LOP_EXECUTE_INLINE_table    @ table of InlineOperation
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   gDvmInlineOpsTable
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
9531    ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
9532    @ (not reached)
9533
9534
9535    /*
9536     * We're debugging or profiling.
9537     * r10: opIndex
9538     */
9539.LOP_EXECUTE_INLINE_RANGE_debugmode:
9540    mov     r0, r10
9541    bl      dvmResolveInlineNative
9542    cmp     r0, #0                      @ did it resolve?
9543    beq     .LOP_EXECUTE_INLINE_RANGE_resume          @ no, just move on
9544    mov     r9, r0                      @ remember method
9545    mov     r1, rSELF
9546    bl      dvmFastMethodTraceEnter     @ (method, self)
9547    add     r1, rSELF, #offThread_retval@ r1<- &self->retval
9548    sub     sp, sp, #8                  @ make room for arg, +64 bit align
9549    mov     r0, rINST, lsr #8           @ r0<- B
9550    mov     rINST, r9                   @ rINST<- method
9551    str     r1, [sp]                    @ push &self->retval
9552    bl      .LOP_EXECUTE_INLINE_RANGE_continue        @ make call; will return after
9553    mov     r9, r0                      @ save result of inline
9554    add     sp, sp, #8                  @ pop stack
9555    mov     r0, rINST                   @ r0<- method
9556    mov     r1, rSELF
9557    bl      dvmFastNativeMethodTraceExit  @ (method, self)
9558    cmp     r9, #0                      @ test boolean result of inline
9559    beq     common_exceptionThrown      @ returned false, handle exception
9560    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
9561    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9562    GOTO_OPCODE(ip)                     @ jump to next instruction
9563
9564
9565
9566
9567.LOP_EXECUTE_INLINE_RANGE_table:
9568    .word   gDvmInlineOpsTable
9569
9570
9571/* continuation for OP_INVOKE_OBJECT_INIT_RANGE */
9572
9573.LOP_INVOKE_OBJECT_INIT_RANGE_setFinal:
9574    EXPORT_PC()                         @ can throw
9575    bl      dvmSetFinalizable           @ call dvmSetFinalizable(obj)
9576    ldr     r0, [rSELF, #offThread_exception] @ r0<- self->exception
9577    cmp     r0, #0                      @ exception pending?
9578    bne     common_exceptionThrown      @ yes, handle it
9579    b       .LOP_INVOKE_OBJECT_INIT_RANGE_finish
9580
9581    /*
9582     * A debugger is attached, so we need to go ahead and do
9583     * this.  For simplicity, we'll just jump directly to the
9584     * corresponding handler.  Note that we can't use
9585     * rIBASE here because it may be in single-step mode.
9586     * Load the primary table base directly.
9587     */
9588.LOP_INVOKE_OBJECT_INIT_RANGE_debugger:
9589    ldr     r1, [rSELF, #offThread_mainHandlerTable]
9590    mov     ip, #OP_INVOKE_DIRECT_RANGE
9591    GOTO_OPCODE_BASE(r1,ip)             @ execute it
9592
9593/* continuation for OP_IPUT_OBJECT_VOLATILE */
9594
9595    /*
9596     * Currently:
9597     *  r0 holds resolved field
9598     *  r9 holds object
9599     */
9600.LOP_IPUT_OBJECT_VOLATILE_finish:
9601    @bl      common_squeak0
9602    mov     r1, rINST, lsr #8           @ r1<- A+
9603    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9604    and     r1, r1, #15                 @ r1<- A
9605    cmp     r9, #0                      @ check object for null
9606    GET_VREG(r0, r1)                    @ r0<- fp[A]
9607    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
9608    beq     common_errNullObject        @ object was null
9609    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9610    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9611    SMP_DMB_ST                        @ releasing store
9612    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
9613    SMP_DMB
9614    cmp     r0, #0                      @ stored a null reference?
9615    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
9616    GOTO_OPCODE(ip)                     @ jump to next instruction
9617
9618/* continuation for OP_SGET_OBJECT_VOLATILE */
9619
9620    /*
9621     * Continuation if the field has not yet been resolved.
9622     *  r1:  BBBB field ref
9623     *  r10: dvmDex->pResFields
9624     */
9625.LOP_SGET_OBJECT_VOLATILE_resolve:
9626    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9627#if defined(WITH_JIT)
9628    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9629#endif
9630    EXPORT_PC()                         @ resolve() could throw, so export now
9631    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9632    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9633    cmp     r0, #0                      @ success?
9634    beq     common_exceptionThrown      @ no, handle exception
9635#if defined(WITH_JIT)
9636    /*
9637     * If the JIT is actively building a trace we need to make sure
9638     * that the field is fully resolved before including this instruction.
9639     */
9640    bl      common_verifyField
9641#endif
9642    b       .LOP_SGET_OBJECT_VOLATILE_finish
9643
9644/* continuation for OP_SPUT_OBJECT_VOLATILE */
9645
9646
9647.LOP_SPUT_OBJECT_VOLATILE_end:
9648    str     r1, [r0, #offStaticField_value]  @ field<- vAA
9649    SMP_DMB
9650    cmp     r1, #0                      @ stored a null object?
9651    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
9652    GOTO_OPCODE(ip)                     @ jump to next instruction
9653
9654    /* Continuation if the field has not yet been resolved.
9655     * r1:  BBBB field ref
9656     * r10: dvmDex->pResFields
9657     */
9658.LOP_SPUT_OBJECT_VOLATILE_resolve:
9659    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9660#if defined(WITH_JIT)
9661    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9662#endif
9663    EXPORT_PC()                         @ resolve() could throw, so export now
9664    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9665    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9666    cmp     r0, #0                      @ success?
9667    beq     common_exceptionThrown      @ no, handle exception
9668#if defined(WITH_JIT)
9669    /*
9670     * If the JIT is actively building a trace we need to make sure
9671     * that the field is fully resolved before including this instruction.
9672     */
9673    bl      common_verifyField
9674#endif
9675    b       .LOP_SPUT_OBJECT_VOLATILE_finish          @ resume
9676
9677
9678    .size   dvmAsmSisterStart, .-dvmAsmSisterStart
9679    .global dvmAsmSisterEnd
9680dvmAsmSisterEnd:
9681
9682
9683    .global dvmAsmAltInstructionStart
9684    .type   dvmAsmAltInstructionStart, %function
9685    .text
9686
9687dvmAsmAltInstructionStart = .L_ALT_OP_NOP
9688/* ------------------------------ */
9689    .balign 64
9690.L_ALT_OP_NOP: /* 0x00 */
9691/* File: armv5te/alt_stub.S */
9692/*
9693 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9694 * any interesting requests and then jump to the real instruction
9695 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9696 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9697 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9698 * bail to the real handler if breakFlags==0.
9699 */
9700    ldrb   r3, [rSELF, #offThread_breakFlags]
9701    adrl   lr, dvmAsmInstructionStart + (0 * 64)
9702    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9703    cmp    r3, #0
9704    bxeq   lr                   @ nothing to do - jump to real handler
9705    EXPORT_PC()
9706    mov    r0, rPC              @ arg0
9707    mov    r1, rFP              @ arg1
9708    mov    r2, rSELF            @ arg2
9709    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9710
9711/* ------------------------------ */
9712    .balign 64
9713.L_ALT_OP_MOVE: /* 0x01 */
9714/* File: armv5te/alt_stub.S */
9715/*
9716 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9717 * any interesting requests and then jump to the real instruction
9718 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9719 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9720 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9721 * bail to the real handler if breakFlags==0.
9722 */
9723    ldrb   r3, [rSELF, #offThread_breakFlags]
9724    adrl   lr, dvmAsmInstructionStart + (1 * 64)
9725    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9726    cmp    r3, #0
9727    bxeq   lr                   @ nothing to do - jump to real handler
9728    EXPORT_PC()
9729    mov    r0, rPC              @ arg0
9730    mov    r1, rFP              @ arg1
9731    mov    r2, rSELF            @ arg2
9732    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9733
9734/* ------------------------------ */
9735    .balign 64
9736.L_ALT_OP_MOVE_FROM16: /* 0x02 */
9737/* File: armv5te/alt_stub.S */
9738/*
9739 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9740 * any interesting requests and then jump to the real instruction
9741 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9742 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9743 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9744 * bail to the real handler if breakFlags==0.
9745 */
9746    ldrb   r3, [rSELF, #offThread_breakFlags]
9747    adrl   lr, dvmAsmInstructionStart + (2 * 64)
9748    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9749    cmp    r3, #0
9750    bxeq   lr                   @ nothing to do - jump to real handler
9751    EXPORT_PC()
9752    mov    r0, rPC              @ arg0
9753    mov    r1, rFP              @ arg1
9754    mov    r2, rSELF            @ arg2
9755    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9756
9757/* ------------------------------ */
9758    .balign 64
9759.L_ALT_OP_MOVE_16: /* 0x03 */
9760/* File: armv5te/alt_stub.S */
9761/*
9762 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9763 * any interesting requests and then jump to the real instruction
9764 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9765 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9766 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9767 * bail to the real handler if breakFlags==0.
9768 */
9769    ldrb   r3, [rSELF, #offThread_breakFlags]
9770    adrl   lr, dvmAsmInstructionStart + (3 * 64)
9771    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9772    cmp    r3, #0
9773    bxeq   lr                   @ nothing to do - jump to real handler
9774    EXPORT_PC()
9775    mov    r0, rPC              @ arg0
9776    mov    r1, rFP              @ arg1
9777    mov    r2, rSELF            @ arg2
9778    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9779
9780/* ------------------------------ */
9781    .balign 64
9782.L_ALT_OP_MOVE_WIDE: /* 0x04 */
9783/* File: armv5te/alt_stub.S */
9784/*
9785 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9786 * any interesting requests and then jump to the real instruction
9787 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9788 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9789 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9790 * bail to the real handler if breakFlags==0.
9791 */
9792    ldrb   r3, [rSELF, #offThread_breakFlags]
9793    adrl   lr, dvmAsmInstructionStart + (4 * 64)
9794    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9795    cmp    r3, #0
9796    bxeq   lr                   @ nothing to do - jump to real handler
9797    EXPORT_PC()
9798    mov    r0, rPC              @ arg0
9799    mov    r1, rFP              @ arg1
9800    mov    r2, rSELF            @ arg2
9801    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9802
9803/* ------------------------------ */
9804    .balign 64
9805.L_ALT_OP_MOVE_WIDE_FROM16: /* 0x05 */
9806/* File: armv5te/alt_stub.S */
9807/*
9808 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9809 * any interesting requests and then jump to the real instruction
9810 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9811 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9812 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9813 * bail to the real handler if breakFlags==0.
9814 */
9815    ldrb   r3, [rSELF, #offThread_breakFlags]
9816    adrl   lr, dvmAsmInstructionStart + (5 * 64)
9817    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9818    cmp    r3, #0
9819    bxeq   lr                   @ nothing to do - jump to real handler
9820    EXPORT_PC()
9821    mov    r0, rPC              @ arg0
9822    mov    r1, rFP              @ arg1
9823    mov    r2, rSELF            @ arg2
9824    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9825
9826/* ------------------------------ */
9827    .balign 64
9828.L_ALT_OP_MOVE_WIDE_16: /* 0x06 */
9829/* File: armv5te/alt_stub.S */
9830/*
9831 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9832 * any interesting requests and then jump to the real instruction
9833 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9834 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9835 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9836 * bail to the real handler if breakFlags==0.
9837 */
9838    ldrb   r3, [rSELF, #offThread_breakFlags]
9839    adrl   lr, dvmAsmInstructionStart + (6 * 64)
9840    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9841    cmp    r3, #0
9842    bxeq   lr                   @ nothing to do - jump to real handler
9843    EXPORT_PC()
9844    mov    r0, rPC              @ arg0
9845    mov    r1, rFP              @ arg1
9846    mov    r2, rSELF            @ arg2
9847    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9848
9849/* ------------------------------ */
9850    .balign 64
9851.L_ALT_OP_MOVE_OBJECT: /* 0x07 */
9852/* File: armv5te/alt_stub.S */
9853/*
9854 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9855 * any interesting requests and then jump to the real instruction
9856 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9857 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9858 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9859 * bail to the real handler if breakFlags==0.
9860 */
9861    ldrb   r3, [rSELF, #offThread_breakFlags]
9862    adrl   lr, dvmAsmInstructionStart + (7 * 64)
9863    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9864    cmp    r3, #0
9865    bxeq   lr                   @ nothing to do - jump to real handler
9866    EXPORT_PC()
9867    mov    r0, rPC              @ arg0
9868    mov    r1, rFP              @ arg1
9869    mov    r2, rSELF            @ arg2
9870    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9871
9872/* ------------------------------ */
9873    .balign 64
9874.L_ALT_OP_MOVE_OBJECT_FROM16: /* 0x08 */
9875/* File: armv5te/alt_stub.S */
9876/*
9877 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9878 * any interesting requests and then jump to the real instruction
9879 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9880 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9881 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9882 * bail to the real handler if breakFlags==0.
9883 */
9884    ldrb   r3, [rSELF, #offThread_breakFlags]
9885    adrl   lr, dvmAsmInstructionStart + (8 * 64)
9886    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9887    cmp    r3, #0
9888    bxeq   lr                   @ nothing to do - jump to real handler
9889    EXPORT_PC()
9890    mov    r0, rPC              @ arg0
9891    mov    r1, rFP              @ arg1
9892    mov    r2, rSELF            @ arg2
9893    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9894
9895/* ------------------------------ */
9896    .balign 64
9897.L_ALT_OP_MOVE_OBJECT_16: /* 0x09 */
9898/* File: armv5te/alt_stub.S */
9899/*
9900 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9901 * any interesting requests and then jump to the real instruction
9902 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9903 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9904 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9905 * bail to the real handler if breakFlags==0.
9906 */
9907    ldrb   r3, [rSELF, #offThread_breakFlags]
9908    adrl   lr, dvmAsmInstructionStart + (9 * 64)
9909    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9910    cmp    r3, #0
9911    bxeq   lr                   @ nothing to do - jump to real handler
9912    EXPORT_PC()
9913    mov    r0, rPC              @ arg0
9914    mov    r1, rFP              @ arg1
9915    mov    r2, rSELF            @ arg2
9916    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9917
9918/* ------------------------------ */
9919    .balign 64
9920.L_ALT_OP_MOVE_RESULT: /* 0x0a */
9921/* File: armv5te/alt_stub.S */
9922/*
9923 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9924 * any interesting requests and then jump to the real instruction
9925 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9926 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9927 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9928 * bail to the real handler if breakFlags==0.
9929 */
9930    ldrb   r3, [rSELF, #offThread_breakFlags]
9931    adrl   lr, dvmAsmInstructionStart + (10 * 64)
9932    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9933    cmp    r3, #0
9934    bxeq   lr                   @ nothing to do - jump to real handler
9935    EXPORT_PC()
9936    mov    r0, rPC              @ arg0
9937    mov    r1, rFP              @ arg1
9938    mov    r2, rSELF            @ arg2
9939    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9940
9941/* ------------------------------ */
9942    .balign 64
9943.L_ALT_OP_MOVE_RESULT_WIDE: /* 0x0b */
9944/* File: armv5te/alt_stub.S */
9945/*
9946 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9947 * any interesting requests and then jump to the real instruction
9948 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9949 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9950 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9951 * bail to the real handler if breakFlags==0.
9952 */
9953    ldrb   r3, [rSELF, #offThread_breakFlags]
9954    adrl   lr, dvmAsmInstructionStart + (11 * 64)
9955    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9956    cmp    r3, #0
9957    bxeq   lr                   @ nothing to do - jump to real handler
9958    EXPORT_PC()
9959    mov    r0, rPC              @ arg0
9960    mov    r1, rFP              @ arg1
9961    mov    r2, rSELF            @ arg2
9962    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9963
9964/* ------------------------------ */
9965    .balign 64
9966.L_ALT_OP_MOVE_RESULT_OBJECT: /* 0x0c */
9967/* File: armv5te/alt_stub.S */
9968/*
9969 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9970 * any interesting requests and then jump to the real instruction
9971 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9972 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9973 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9974 * bail to the real handler if breakFlags==0.
9975 */
9976    ldrb   r3, [rSELF, #offThread_breakFlags]
9977    adrl   lr, dvmAsmInstructionStart + (12 * 64)
9978    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
9979    cmp    r3, #0
9980    bxeq   lr                   @ nothing to do - jump to real handler
9981    EXPORT_PC()
9982    mov    r0, rPC              @ arg0
9983    mov    r1, rFP              @ arg1
9984    mov    r2, rSELF            @ arg2
9985    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
9986
9987/* ------------------------------ */
9988    .balign 64
9989.L_ALT_OP_MOVE_EXCEPTION: /* 0x0d */
9990/* File: armv5te/alt_stub.S */
9991/*
9992 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
9993 * any interesting requests and then jump to the real instruction
9994 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
9995 * rIBASE updates won't be seen until a refresh, and we can tell we have a
9996 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
9997 * bail to the real handler if breakFlags==0.
9998 */
9999    ldrb   r3, [rSELF, #offThread_breakFlags]
10000    adrl   lr, dvmAsmInstructionStart + (13 * 64)
10001    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10002    cmp    r3, #0
10003    bxeq   lr                   @ nothing to do - jump to real handler
10004    EXPORT_PC()
10005    mov    r0, rPC              @ arg0
10006    mov    r1, rFP              @ arg1
10007    mov    r2, rSELF            @ arg2
10008    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10009
10010/* ------------------------------ */
10011    .balign 64
10012.L_ALT_OP_RETURN_VOID: /* 0x0e */
10013/* File: armv5te/alt_stub.S */
10014/*
10015 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10016 * any interesting requests and then jump to the real instruction
10017 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10018 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10019 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10020 * bail to the real handler if breakFlags==0.
10021 */
10022    ldrb   r3, [rSELF, #offThread_breakFlags]
10023    adrl   lr, dvmAsmInstructionStart + (14 * 64)
10024    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10025    cmp    r3, #0
10026    bxeq   lr                   @ nothing to do - jump to real handler
10027    EXPORT_PC()
10028    mov    r0, rPC              @ arg0
10029    mov    r1, rFP              @ arg1
10030    mov    r2, rSELF            @ arg2
10031    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10032
10033/* ------------------------------ */
10034    .balign 64
10035.L_ALT_OP_RETURN: /* 0x0f */
10036/* File: armv5te/alt_stub.S */
10037/*
10038 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10039 * any interesting requests and then jump to the real instruction
10040 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10041 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10042 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10043 * bail to the real handler if breakFlags==0.
10044 */
10045    ldrb   r3, [rSELF, #offThread_breakFlags]
10046    adrl   lr, dvmAsmInstructionStart + (15 * 64)
10047    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10048    cmp    r3, #0
10049    bxeq   lr                   @ nothing to do - jump to real handler
10050    EXPORT_PC()
10051    mov    r0, rPC              @ arg0
10052    mov    r1, rFP              @ arg1
10053    mov    r2, rSELF            @ arg2
10054    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10055
10056/* ------------------------------ */
10057    .balign 64
10058.L_ALT_OP_RETURN_WIDE: /* 0x10 */
10059/* File: armv5te/alt_stub.S */
10060/*
10061 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10062 * any interesting requests and then jump to the real instruction
10063 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10064 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10065 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10066 * bail to the real handler if breakFlags==0.
10067 */
10068    ldrb   r3, [rSELF, #offThread_breakFlags]
10069    adrl   lr, dvmAsmInstructionStart + (16 * 64)
10070    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10071    cmp    r3, #0
10072    bxeq   lr                   @ nothing to do - jump to real handler
10073    EXPORT_PC()
10074    mov    r0, rPC              @ arg0
10075    mov    r1, rFP              @ arg1
10076    mov    r2, rSELF            @ arg2
10077    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10078
10079/* ------------------------------ */
10080    .balign 64
10081.L_ALT_OP_RETURN_OBJECT: /* 0x11 */
10082/* File: armv5te/alt_stub.S */
10083/*
10084 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10085 * any interesting requests and then jump to the real instruction
10086 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10087 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10088 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10089 * bail to the real handler if breakFlags==0.
10090 */
10091    ldrb   r3, [rSELF, #offThread_breakFlags]
10092    adrl   lr, dvmAsmInstructionStart + (17 * 64)
10093    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10094    cmp    r3, #0
10095    bxeq   lr                   @ nothing to do - jump to real handler
10096    EXPORT_PC()
10097    mov    r0, rPC              @ arg0
10098    mov    r1, rFP              @ arg1
10099    mov    r2, rSELF            @ arg2
10100    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10101
10102/* ------------------------------ */
10103    .balign 64
10104.L_ALT_OP_CONST_4: /* 0x12 */
10105/* File: armv5te/alt_stub.S */
10106/*
10107 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10108 * any interesting requests and then jump to the real instruction
10109 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10110 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10111 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10112 * bail to the real handler if breakFlags==0.
10113 */
10114    ldrb   r3, [rSELF, #offThread_breakFlags]
10115    adrl   lr, dvmAsmInstructionStart + (18 * 64)
10116    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10117    cmp    r3, #0
10118    bxeq   lr                   @ nothing to do - jump to real handler
10119    EXPORT_PC()
10120    mov    r0, rPC              @ arg0
10121    mov    r1, rFP              @ arg1
10122    mov    r2, rSELF            @ arg2
10123    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10124
10125/* ------------------------------ */
10126    .balign 64
10127.L_ALT_OP_CONST_16: /* 0x13 */
10128/* File: armv5te/alt_stub.S */
10129/*
10130 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10131 * any interesting requests and then jump to the real instruction
10132 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10133 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10134 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10135 * bail to the real handler if breakFlags==0.
10136 */
10137    ldrb   r3, [rSELF, #offThread_breakFlags]
10138    adrl   lr, dvmAsmInstructionStart + (19 * 64)
10139    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10140    cmp    r3, #0
10141    bxeq   lr                   @ nothing to do - jump to real handler
10142    EXPORT_PC()
10143    mov    r0, rPC              @ arg0
10144    mov    r1, rFP              @ arg1
10145    mov    r2, rSELF            @ arg2
10146    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10147
10148/* ------------------------------ */
10149    .balign 64
10150.L_ALT_OP_CONST: /* 0x14 */
10151/* File: armv5te/alt_stub.S */
10152/*
10153 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10154 * any interesting requests and then jump to the real instruction
10155 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10156 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10157 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10158 * bail to the real handler if breakFlags==0.
10159 */
10160    ldrb   r3, [rSELF, #offThread_breakFlags]
10161    adrl   lr, dvmAsmInstructionStart + (20 * 64)
10162    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10163    cmp    r3, #0
10164    bxeq   lr                   @ nothing to do - jump to real handler
10165    EXPORT_PC()
10166    mov    r0, rPC              @ arg0
10167    mov    r1, rFP              @ arg1
10168    mov    r2, rSELF            @ arg2
10169    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10170
10171/* ------------------------------ */
10172    .balign 64
10173.L_ALT_OP_CONST_HIGH16: /* 0x15 */
10174/* File: armv5te/alt_stub.S */
10175/*
10176 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10177 * any interesting requests and then jump to the real instruction
10178 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10179 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10180 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10181 * bail to the real handler if breakFlags==0.
10182 */
10183    ldrb   r3, [rSELF, #offThread_breakFlags]
10184    adrl   lr, dvmAsmInstructionStart + (21 * 64)
10185    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10186    cmp    r3, #0
10187    bxeq   lr                   @ nothing to do - jump to real handler
10188    EXPORT_PC()
10189    mov    r0, rPC              @ arg0
10190    mov    r1, rFP              @ arg1
10191    mov    r2, rSELF            @ arg2
10192    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10193
10194/* ------------------------------ */
10195    .balign 64
10196.L_ALT_OP_CONST_WIDE_16: /* 0x16 */
10197/* File: armv5te/alt_stub.S */
10198/*
10199 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10200 * any interesting requests and then jump to the real instruction
10201 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10202 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10203 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10204 * bail to the real handler if breakFlags==0.
10205 */
10206    ldrb   r3, [rSELF, #offThread_breakFlags]
10207    adrl   lr, dvmAsmInstructionStart + (22 * 64)
10208    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10209    cmp    r3, #0
10210    bxeq   lr                   @ nothing to do - jump to real handler
10211    EXPORT_PC()
10212    mov    r0, rPC              @ arg0
10213    mov    r1, rFP              @ arg1
10214    mov    r2, rSELF            @ arg2
10215    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10216
10217/* ------------------------------ */
10218    .balign 64
10219.L_ALT_OP_CONST_WIDE_32: /* 0x17 */
10220/* File: armv5te/alt_stub.S */
10221/*
10222 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10223 * any interesting requests and then jump to the real instruction
10224 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10225 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10226 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10227 * bail to the real handler if breakFlags==0.
10228 */
10229    ldrb   r3, [rSELF, #offThread_breakFlags]
10230    adrl   lr, dvmAsmInstructionStart + (23 * 64)
10231    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10232    cmp    r3, #0
10233    bxeq   lr                   @ nothing to do - jump to real handler
10234    EXPORT_PC()
10235    mov    r0, rPC              @ arg0
10236    mov    r1, rFP              @ arg1
10237    mov    r2, rSELF            @ arg2
10238    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10239
10240/* ------------------------------ */
10241    .balign 64
10242.L_ALT_OP_CONST_WIDE: /* 0x18 */
10243/* File: armv5te/alt_stub.S */
10244/*
10245 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10246 * any interesting requests and then jump to the real instruction
10247 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10248 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10249 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10250 * bail to the real handler if breakFlags==0.
10251 */
10252    ldrb   r3, [rSELF, #offThread_breakFlags]
10253    adrl   lr, dvmAsmInstructionStart + (24 * 64)
10254    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10255    cmp    r3, #0
10256    bxeq   lr                   @ nothing to do - jump to real handler
10257    EXPORT_PC()
10258    mov    r0, rPC              @ arg0
10259    mov    r1, rFP              @ arg1
10260    mov    r2, rSELF            @ arg2
10261    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10262
10263/* ------------------------------ */
10264    .balign 64
10265.L_ALT_OP_CONST_WIDE_HIGH16: /* 0x19 */
10266/* File: armv5te/alt_stub.S */
10267/*
10268 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10269 * any interesting requests and then jump to the real instruction
10270 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10271 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10272 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10273 * bail to the real handler if breakFlags==0.
10274 */
10275    ldrb   r3, [rSELF, #offThread_breakFlags]
10276    adrl   lr, dvmAsmInstructionStart + (25 * 64)
10277    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10278    cmp    r3, #0
10279    bxeq   lr                   @ nothing to do - jump to real handler
10280    EXPORT_PC()
10281    mov    r0, rPC              @ arg0
10282    mov    r1, rFP              @ arg1
10283    mov    r2, rSELF            @ arg2
10284    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10285
10286/* ------------------------------ */
10287    .balign 64
10288.L_ALT_OP_CONST_STRING: /* 0x1a */
10289/* File: armv5te/alt_stub.S */
10290/*
10291 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10292 * any interesting requests and then jump to the real instruction
10293 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10294 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10295 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10296 * bail to the real handler if breakFlags==0.
10297 */
10298    ldrb   r3, [rSELF, #offThread_breakFlags]
10299    adrl   lr, dvmAsmInstructionStart + (26 * 64)
10300    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10301    cmp    r3, #0
10302    bxeq   lr                   @ nothing to do - jump to real handler
10303    EXPORT_PC()
10304    mov    r0, rPC              @ arg0
10305    mov    r1, rFP              @ arg1
10306    mov    r2, rSELF            @ arg2
10307    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10308
10309/* ------------------------------ */
10310    .balign 64
10311.L_ALT_OP_CONST_STRING_JUMBO: /* 0x1b */
10312/* File: armv5te/alt_stub.S */
10313/*
10314 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10315 * any interesting requests and then jump to the real instruction
10316 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10317 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10318 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10319 * bail to the real handler if breakFlags==0.
10320 */
10321    ldrb   r3, [rSELF, #offThread_breakFlags]
10322    adrl   lr, dvmAsmInstructionStart + (27 * 64)
10323    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10324    cmp    r3, #0
10325    bxeq   lr                   @ nothing to do - jump to real handler
10326    EXPORT_PC()
10327    mov    r0, rPC              @ arg0
10328    mov    r1, rFP              @ arg1
10329    mov    r2, rSELF            @ arg2
10330    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10331
10332/* ------------------------------ */
10333    .balign 64
10334.L_ALT_OP_CONST_CLASS: /* 0x1c */
10335/* File: armv5te/alt_stub.S */
10336/*
10337 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10338 * any interesting requests and then jump to the real instruction
10339 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10340 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10341 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10342 * bail to the real handler if breakFlags==0.
10343 */
10344    ldrb   r3, [rSELF, #offThread_breakFlags]
10345    adrl   lr, dvmAsmInstructionStart + (28 * 64)
10346    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10347    cmp    r3, #0
10348    bxeq   lr                   @ nothing to do - jump to real handler
10349    EXPORT_PC()
10350    mov    r0, rPC              @ arg0
10351    mov    r1, rFP              @ arg1
10352    mov    r2, rSELF            @ arg2
10353    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10354
10355/* ------------------------------ */
10356    .balign 64
10357.L_ALT_OP_MONITOR_ENTER: /* 0x1d */
10358/* File: armv5te/alt_stub.S */
10359/*
10360 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10361 * any interesting requests and then jump to the real instruction
10362 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10363 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10364 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10365 * bail to the real handler if breakFlags==0.
10366 */
10367    ldrb   r3, [rSELF, #offThread_breakFlags]
10368    adrl   lr, dvmAsmInstructionStart + (29 * 64)
10369    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10370    cmp    r3, #0
10371    bxeq   lr                   @ nothing to do - jump to real handler
10372    EXPORT_PC()
10373    mov    r0, rPC              @ arg0
10374    mov    r1, rFP              @ arg1
10375    mov    r2, rSELF            @ arg2
10376    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10377
10378/* ------------------------------ */
10379    .balign 64
10380.L_ALT_OP_MONITOR_EXIT: /* 0x1e */
10381/* File: armv5te/alt_stub.S */
10382/*
10383 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10384 * any interesting requests and then jump to the real instruction
10385 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10386 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10387 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10388 * bail to the real handler if breakFlags==0.
10389 */
10390    ldrb   r3, [rSELF, #offThread_breakFlags]
10391    adrl   lr, dvmAsmInstructionStart + (30 * 64)
10392    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10393    cmp    r3, #0
10394    bxeq   lr                   @ nothing to do - jump to real handler
10395    EXPORT_PC()
10396    mov    r0, rPC              @ arg0
10397    mov    r1, rFP              @ arg1
10398    mov    r2, rSELF            @ arg2
10399    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10400
10401/* ------------------------------ */
10402    .balign 64
10403.L_ALT_OP_CHECK_CAST: /* 0x1f */
10404/* File: armv5te/alt_stub.S */
10405/*
10406 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10407 * any interesting requests and then jump to the real instruction
10408 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10409 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10410 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10411 * bail to the real handler if breakFlags==0.
10412 */
10413    ldrb   r3, [rSELF, #offThread_breakFlags]
10414    adrl   lr, dvmAsmInstructionStart + (31 * 64)
10415    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10416    cmp    r3, #0
10417    bxeq   lr                   @ nothing to do - jump to real handler
10418    EXPORT_PC()
10419    mov    r0, rPC              @ arg0
10420    mov    r1, rFP              @ arg1
10421    mov    r2, rSELF            @ arg2
10422    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10423
10424/* ------------------------------ */
10425    .balign 64
10426.L_ALT_OP_INSTANCE_OF: /* 0x20 */
10427/* File: armv5te/alt_stub.S */
10428/*
10429 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10430 * any interesting requests and then jump to the real instruction
10431 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10432 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10433 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10434 * bail to the real handler if breakFlags==0.
10435 */
10436    ldrb   r3, [rSELF, #offThread_breakFlags]
10437    adrl   lr, dvmAsmInstructionStart + (32 * 64)
10438    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10439    cmp    r3, #0
10440    bxeq   lr                   @ nothing to do - jump to real handler
10441    EXPORT_PC()
10442    mov    r0, rPC              @ arg0
10443    mov    r1, rFP              @ arg1
10444    mov    r2, rSELF            @ arg2
10445    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10446
10447/* ------------------------------ */
10448    .balign 64
10449.L_ALT_OP_ARRAY_LENGTH: /* 0x21 */
10450/* File: armv5te/alt_stub.S */
10451/*
10452 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10453 * any interesting requests and then jump to the real instruction
10454 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10455 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10456 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10457 * bail to the real handler if breakFlags==0.
10458 */
10459    ldrb   r3, [rSELF, #offThread_breakFlags]
10460    adrl   lr, dvmAsmInstructionStart + (33 * 64)
10461    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10462    cmp    r3, #0
10463    bxeq   lr                   @ nothing to do - jump to real handler
10464    EXPORT_PC()
10465    mov    r0, rPC              @ arg0
10466    mov    r1, rFP              @ arg1
10467    mov    r2, rSELF            @ arg2
10468    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10469
10470/* ------------------------------ */
10471    .balign 64
10472.L_ALT_OP_NEW_INSTANCE: /* 0x22 */
10473/* File: armv5te/alt_stub.S */
10474/*
10475 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10476 * any interesting requests and then jump to the real instruction
10477 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10478 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10479 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10480 * bail to the real handler if breakFlags==0.
10481 */
10482    ldrb   r3, [rSELF, #offThread_breakFlags]
10483    adrl   lr, dvmAsmInstructionStart + (34 * 64)
10484    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10485    cmp    r3, #0
10486    bxeq   lr                   @ nothing to do - jump to real handler
10487    EXPORT_PC()
10488    mov    r0, rPC              @ arg0
10489    mov    r1, rFP              @ arg1
10490    mov    r2, rSELF            @ arg2
10491    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10492
10493/* ------------------------------ */
10494    .balign 64
10495.L_ALT_OP_NEW_ARRAY: /* 0x23 */
10496/* File: armv5te/alt_stub.S */
10497/*
10498 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10499 * any interesting requests and then jump to the real instruction
10500 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10501 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10502 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10503 * bail to the real handler if breakFlags==0.
10504 */
10505    ldrb   r3, [rSELF, #offThread_breakFlags]
10506    adrl   lr, dvmAsmInstructionStart + (35 * 64)
10507    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10508    cmp    r3, #0
10509    bxeq   lr                   @ nothing to do - jump to real handler
10510    EXPORT_PC()
10511    mov    r0, rPC              @ arg0
10512    mov    r1, rFP              @ arg1
10513    mov    r2, rSELF            @ arg2
10514    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10515
10516/* ------------------------------ */
10517    .balign 64
10518.L_ALT_OP_FILLED_NEW_ARRAY: /* 0x24 */
10519/* File: armv5te/alt_stub.S */
10520/*
10521 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10522 * any interesting requests and then jump to the real instruction
10523 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10524 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10525 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10526 * bail to the real handler if breakFlags==0.
10527 */
10528    ldrb   r3, [rSELF, #offThread_breakFlags]
10529    adrl   lr, dvmAsmInstructionStart + (36 * 64)
10530    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10531    cmp    r3, #0
10532    bxeq   lr                   @ nothing to do - jump to real handler
10533    EXPORT_PC()
10534    mov    r0, rPC              @ arg0
10535    mov    r1, rFP              @ arg1
10536    mov    r2, rSELF            @ arg2
10537    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10538
10539/* ------------------------------ */
10540    .balign 64
10541.L_ALT_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
10542/* File: armv5te/alt_stub.S */
10543/*
10544 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10545 * any interesting requests and then jump to the real instruction
10546 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10547 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10548 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10549 * bail to the real handler if breakFlags==0.
10550 */
10551    ldrb   r3, [rSELF, #offThread_breakFlags]
10552    adrl   lr, dvmAsmInstructionStart + (37 * 64)
10553    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10554    cmp    r3, #0
10555    bxeq   lr                   @ nothing to do - jump to real handler
10556    EXPORT_PC()
10557    mov    r0, rPC              @ arg0
10558    mov    r1, rFP              @ arg1
10559    mov    r2, rSELF            @ arg2
10560    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10561
10562/* ------------------------------ */
10563    .balign 64
10564.L_ALT_OP_FILL_ARRAY_DATA: /* 0x26 */
10565/* File: armv5te/alt_stub.S */
10566/*
10567 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10568 * any interesting requests and then jump to the real instruction
10569 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10570 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10571 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10572 * bail to the real handler if breakFlags==0.
10573 */
10574    ldrb   r3, [rSELF, #offThread_breakFlags]
10575    adrl   lr, dvmAsmInstructionStart + (38 * 64)
10576    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10577    cmp    r3, #0
10578    bxeq   lr                   @ nothing to do - jump to real handler
10579    EXPORT_PC()
10580    mov    r0, rPC              @ arg0
10581    mov    r1, rFP              @ arg1
10582    mov    r2, rSELF            @ arg2
10583    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10584
10585/* ------------------------------ */
10586    .balign 64
10587.L_ALT_OP_THROW: /* 0x27 */
10588/* File: armv5te/alt_stub.S */
10589/*
10590 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10591 * any interesting requests and then jump to the real instruction
10592 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10593 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10594 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10595 * bail to the real handler if breakFlags==0.
10596 */
10597    ldrb   r3, [rSELF, #offThread_breakFlags]
10598    adrl   lr, dvmAsmInstructionStart + (39 * 64)
10599    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10600    cmp    r3, #0
10601    bxeq   lr                   @ nothing to do - jump to real handler
10602    EXPORT_PC()
10603    mov    r0, rPC              @ arg0
10604    mov    r1, rFP              @ arg1
10605    mov    r2, rSELF            @ arg2
10606    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10607
10608/* ------------------------------ */
10609    .balign 64
10610.L_ALT_OP_GOTO: /* 0x28 */
10611/* File: armv5te/alt_stub.S */
10612/*
10613 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10614 * any interesting requests and then jump to the real instruction
10615 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10616 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10617 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10618 * bail to the real handler if breakFlags==0.
10619 */
10620    ldrb   r3, [rSELF, #offThread_breakFlags]
10621    adrl   lr, dvmAsmInstructionStart + (40 * 64)
10622    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10623    cmp    r3, #0
10624    bxeq   lr                   @ nothing to do - jump to real handler
10625    EXPORT_PC()
10626    mov    r0, rPC              @ arg0
10627    mov    r1, rFP              @ arg1
10628    mov    r2, rSELF            @ arg2
10629    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10630
10631/* ------------------------------ */
10632    .balign 64
10633.L_ALT_OP_GOTO_16: /* 0x29 */
10634/* File: armv5te/alt_stub.S */
10635/*
10636 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10637 * any interesting requests and then jump to the real instruction
10638 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10639 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10640 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10641 * bail to the real handler if breakFlags==0.
10642 */
10643    ldrb   r3, [rSELF, #offThread_breakFlags]
10644    adrl   lr, dvmAsmInstructionStart + (41 * 64)
10645    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10646    cmp    r3, #0
10647    bxeq   lr                   @ nothing to do - jump to real handler
10648    EXPORT_PC()
10649    mov    r0, rPC              @ arg0
10650    mov    r1, rFP              @ arg1
10651    mov    r2, rSELF            @ arg2
10652    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10653
10654/* ------------------------------ */
10655    .balign 64
10656.L_ALT_OP_GOTO_32: /* 0x2a */
10657/* File: armv5te/alt_stub.S */
10658/*
10659 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10660 * any interesting requests and then jump to the real instruction
10661 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10662 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10663 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10664 * bail to the real handler if breakFlags==0.
10665 */
10666    ldrb   r3, [rSELF, #offThread_breakFlags]
10667    adrl   lr, dvmAsmInstructionStart + (42 * 64)
10668    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10669    cmp    r3, #0
10670    bxeq   lr                   @ nothing to do - jump to real handler
10671    EXPORT_PC()
10672    mov    r0, rPC              @ arg0
10673    mov    r1, rFP              @ arg1
10674    mov    r2, rSELF            @ arg2
10675    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10676
10677/* ------------------------------ */
10678    .balign 64
10679.L_ALT_OP_PACKED_SWITCH: /* 0x2b */
10680/* File: armv5te/alt_stub.S */
10681/*
10682 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10683 * any interesting requests and then jump to the real instruction
10684 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10685 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10686 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10687 * bail to the real handler if breakFlags==0.
10688 */
10689    ldrb   r3, [rSELF, #offThread_breakFlags]
10690    adrl   lr, dvmAsmInstructionStart + (43 * 64)
10691    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10692    cmp    r3, #0
10693    bxeq   lr                   @ nothing to do - jump to real handler
10694    EXPORT_PC()
10695    mov    r0, rPC              @ arg0
10696    mov    r1, rFP              @ arg1
10697    mov    r2, rSELF            @ arg2
10698    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10699
10700/* ------------------------------ */
10701    .balign 64
10702.L_ALT_OP_SPARSE_SWITCH: /* 0x2c */
10703/* File: armv5te/alt_stub.S */
10704/*
10705 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10706 * any interesting requests and then jump to the real instruction
10707 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10708 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10709 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10710 * bail to the real handler if breakFlags==0.
10711 */
10712    ldrb   r3, [rSELF, #offThread_breakFlags]
10713    adrl   lr, dvmAsmInstructionStart + (44 * 64)
10714    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10715    cmp    r3, #0
10716    bxeq   lr                   @ nothing to do - jump to real handler
10717    EXPORT_PC()
10718    mov    r0, rPC              @ arg0
10719    mov    r1, rFP              @ arg1
10720    mov    r2, rSELF            @ arg2
10721    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10722
10723/* ------------------------------ */
10724    .balign 64
10725.L_ALT_OP_CMPL_FLOAT: /* 0x2d */
10726/* File: armv5te/alt_stub.S */
10727/*
10728 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10729 * any interesting requests and then jump to the real instruction
10730 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10731 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10732 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10733 * bail to the real handler if breakFlags==0.
10734 */
10735    ldrb   r3, [rSELF, #offThread_breakFlags]
10736    adrl   lr, dvmAsmInstructionStart + (45 * 64)
10737    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10738    cmp    r3, #0
10739    bxeq   lr                   @ nothing to do - jump to real handler
10740    EXPORT_PC()
10741    mov    r0, rPC              @ arg0
10742    mov    r1, rFP              @ arg1
10743    mov    r2, rSELF            @ arg2
10744    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10745
10746/* ------------------------------ */
10747    .balign 64
10748.L_ALT_OP_CMPG_FLOAT: /* 0x2e */
10749/* File: armv5te/alt_stub.S */
10750/*
10751 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10752 * any interesting requests and then jump to the real instruction
10753 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10754 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10755 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10756 * bail to the real handler if breakFlags==0.
10757 */
10758    ldrb   r3, [rSELF, #offThread_breakFlags]
10759    adrl   lr, dvmAsmInstructionStart + (46 * 64)
10760    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10761    cmp    r3, #0
10762    bxeq   lr                   @ nothing to do - jump to real handler
10763    EXPORT_PC()
10764    mov    r0, rPC              @ arg0
10765    mov    r1, rFP              @ arg1
10766    mov    r2, rSELF            @ arg2
10767    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10768
10769/* ------------------------------ */
10770    .balign 64
10771.L_ALT_OP_CMPL_DOUBLE: /* 0x2f */
10772/* File: armv5te/alt_stub.S */
10773/*
10774 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10775 * any interesting requests and then jump to the real instruction
10776 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10777 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10778 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10779 * bail to the real handler if breakFlags==0.
10780 */
10781    ldrb   r3, [rSELF, #offThread_breakFlags]
10782    adrl   lr, dvmAsmInstructionStart + (47 * 64)
10783    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10784    cmp    r3, #0
10785    bxeq   lr                   @ nothing to do - jump to real handler
10786    EXPORT_PC()
10787    mov    r0, rPC              @ arg0
10788    mov    r1, rFP              @ arg1
10789    mov    r2, rSELF            @ arg2
10790    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10791
10792/* ------------------------------ */
10793    .balign 64
10794.L_ALT_OP_CMPG_DOUBLE: /* 0x30 */
10795/* File: armv5te/alt_stub.S */
10796/*
10797 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10798 * any interesting requests and then jump to the real instruction
10799 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10800 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10801 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10802 * bail to the real handler if breakFlags==0.
10803 */
10804    ldrb   r3, [rSELF, #offThread_breakFlags]
10805    adrl   lr, dvmAsmInstructionStart + (48 * 64)
10806    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10807    cmp    r3, #0
10808    bxeq   lr                   @ nothing to do - jump to real handler
10809    EXPORT_PC()
10810    mov    r0, rPC              @ arg0
10811    mov    r1, rFP              @ arg1
10812    mov    r2, rSELF            @ arg2
10813    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10814
10815/* ------------------------------ */
10816    .balign 64
10817.L_ALT_OP_CMP_LONG: /* 0x31 */
10818/* File: armv5te/alt_stub.S */
10819/*
10820 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10821 * any interesting requests and then jump to the real instruction
10822 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10823 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10824 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10825 * bail to the real handler if breakFlags==0.
10826 */
10827    ldrb   r3, [rSELF, #offThread_breakFlags]
10828    adrl   lr, dvmAsmInstructionStart + (49 * 64)
10829    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10830    cmp    r3, #0
10831    bxeq   lr                   @ nothing to do - jump to real handler
10832    EXPORT_PC()
10833    mov    r0, rPC              @ arg0
10834    mov    r1, rFP              @ arg1
10835    mov    r2, rSELF            @ arg2
10836    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10837
10838/* ------------------------------ */
10839    .balign 64
10840.L_ALT_OP_IF_EQ: /* 0x32 */
10841/* File: armv5te/alt_stub.S */
10842/*
10843 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10844 * any interesting requests and then jump to the real instruction
10845 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10846 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10847 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10848 * bail to the real handler if breakFlags==0.
10849 */
10850    ldrb   r3, [rSELF, #offThread_breakFlags]
10851    adrl   lr, dvmAsmInstructionStart + (50 * 64)
10852    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10853    cmp    r3, #0
10854    bxeq   lr                   @ nothing to do - jump to real handler
10855    EXPORT_PC()
10856    mov    r0, rPC              @ arg0
10857    mov    r1, rFP              @ arg1
10858    mov    r2, rSELF            @ arg2
10859    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10860
10861/* ------------------------------ */
10862    .balign 64
10863.L_ALT_OP_IF_NE: /* 0x33 */
10864/* File: armv5te/alt_stub.S */
10865/*
10866 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10867 * any interesting requests and then jump to the real instruction
10868 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10869 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10870 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10871 * bail to the real handler if breakFlags==0.
10872 */
10873    ldrb   r3, [rSELF, #offThread_breakFlags]
10874    adrl   lr, dvmAsmInstructionStart + (51 * 64)
10875    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10876    cmp    r3, #0
10877    bxeq   lr                   @ nothing to do - jump to real handler
10878    EXPORT_PC()
10879    mov    r0, rPC              @ arg0
10880    mov    r1, rFP              @ arg1
10881    mov    r2, rSELF            @ arg2
10882    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10883
10884/* ------------------------------ */
10885    .balign 64
10886.L_ALT_OP_IF_LT: /* 0x34 */
10887/* File: armv5te/alt_stub.S */
10888/*
10889 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10890 * any interesting requests and then jump to the real instruction
10891 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10892 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10893 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10894 * bail to the real handler if breakFlags==0.
10895 */
10896    ldrb   r3, [rSELF, #offThread_breakFlags]
10897    adrl   lr, dvmAsmInstructionStart + (52 * 64)
10898    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10899    cmp    r3, #0
10900    bxeq   lr                   @ nothing to do - jump to real handler
10901    EXPORT_PC()
10902    mov    r0, rPC              @ arg0
10903    mov    r1, rFP              @ arg1
10904    mov    r2, rSELF            @ arg2
10905    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10906
10907/* ------------------------------ */
10908    .balign 64
10909.L_ALT_OP_IF_GE: /* 0x35 */
10910/* File: armv5te/alt_stub.S */
10911/*
10912 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10913 * any interesting requests and then jump to the real instruction
10914 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10915 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10916 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10917 * bail to the real handler if breakFlags==0.
10918 */
10919    ldrb   r3, [rSELF, #offThread_breakFlags]
10920    adrl   lr, dvmAsmInstructionStart + (53 * 64)
10921    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10922    cmp    r3, #0
10923    bxeq   lr                   @ nothing to do - jump to real handler
10924    EXPORT_PC()
10925    mov    r0, rPC              @ arg0
10926    mov    r1, rFP              @ arg1
10927    mov    r2, rSELF            @ arg2
10928    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10929
10930/* ------------------------------ */
10931    .balign 64
10932.L_ALT_OP_IF_GT: /* 0x36 */
10933/* File: armv5te/alt_stub.S */
10934/*
10935 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10936 * any interesting requests and then jump to the real instruction
10937 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10938 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10939 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10940 * bail to the real handler if breakFlags==0.
10941 */
10942    ldrb   r3, [rSELF, #offThread_breakFlags]
10943    adrl   lr, dvmAsmInstructionStart + (54 * 64)
10944    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10945    cmp    r3, #0
10946    bxeq   lr                   @ nothing to do - jump to real handler
10947    EXPORT_PC()
10948    mov    r0, rPC              @ arg0
10949    mov    r1, rFP              @ arg1
10950    mov    r2, rSELF            @ arg2
10951    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10952
10953/* ------------------------------ */
10954    .balign 64
10955.L_ALT_OP_IF_LE: /* 0x37 */
10956/* File: armv5te/alt_stub.S */
10957/*
10958 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10959 * any interesting requests and then jump to the real instruction
10960 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10961 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10962 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10963 * bail to the real handler if breakFlags==0.
10964 */
10965    ldrb   r3, [rSELF, #offThread_breakFlags]
10966    adrl   lr, dvmAsmInstructionStart + (55 * 64)
10967    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10968    cmp    r3, #0
10969    bxeq   lr                   @ nothing to do - jump to real handler
10970    EXPORT_PC()
10971    mov    r0, rPC              @ arg0
10972    mov    r1, rFP              @ arg1
10973    mov    r2, rSELF            @ arg2
10974    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10975
10976/* ------------------------------ */
10977    .balign 64
10978.L_ALT_OP_IF_EQZ: /* 0x38 */
10979/* File: armv5te/alt_stub.S */
10980/*
10981 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10982 * any interesting requests and then jump to the real instruction
10983 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10984 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10985 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10986 * bail to the real handler if breakFlags==0.
10987 */
10988    ldrb   r3, [rSELF, #offThread_breakFlags]
10989    adrl   lr, dvmAsmInstructionStart + (56 * 64)
10990    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10991    cmp    r3, #0
10992    bxeq   lr                   @ nothing to do - jump to real handler
10993    EXPORT_PC()
10994    mov    r0, rPC              @ arg0
10995    mov    r1, rFP              @ arg1
10996    mov    r2, rSELF            @ arg2
10997    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10998
10999/* ------------------------------ */
11000    .balign 64
11001.L_ALT_OP_IF_NEZ: /* 0x39 */
11002/* File: armv5te/alt_stub.S */
11003/*
11004 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11005 * any interesting requests and then jump to the real instruction
11006 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11007 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11008 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11009 * bail to the real handler if breakFlags==0.
11010 */
11011    ldrb   r3, [rSELF, #offThread_breakFlags]
11012    adrl   lr, dvmAsmInstructionStart + (57 * 64)
11013    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11014    cmp    r3, #0
11015    bxeq   lr                   @ nothing to do - jump to real handler
11016    EXPORT_PC()
11017    mov    r0, rPC              @ arg0
11018    mov    r1, rFP              @ arg1
11019    mov    r2, rSELF            @ arg2
11020    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11021
11022/* ------------------------------ */
11023    .balign 64
11024.L_ALT_OP_IF_LTZ: /* 0x3a */
11025/* File: armv5te/alt_stub.S */
11026/*
11027 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11028 * any interesting requests and then jump to the real instruction
11029 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11030 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11031 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11032 * bail to the real handler if breakFlags==0.
11033 */
11034    ldrb   r3, [rSELF, #offThread_breakFlags]
11035    adrl   lr, dvmAsmInstructionStart + (58 * 64)
11036    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11037    cmp    r3, #0
11038    bxeq   lr                   @ nothing to do - jump to real handler
11039    EXPORT_PC()
11040    mov    r0, rPC              @ arg0
11041    mov    r1, rFP              @ arg1
11042    mov    r2, rSELF            @ arg2
11043    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11044
11045/* ------------------------------ */
11046    .balign 64
11047.L_ALT_OP_IF_GEZ: /* 0x3b */
11048/* File: armv5te/alt_stub.S */
11049/*
11050 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11051 * any interesting requests and then jump to the real instruction
11052 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11053 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11054 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11055 * bail to the real handler if breakFlags==0.
11056 */
11057    ldrb   r3, [rSELF, #offThread_breakFlags]
11058    adrl   lr, dvmAsmInstructionStart + (59 * 64)
11059    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11060    cmp    r3, #0
11061    bxeq   lr                   @ nothing to do - jump to real handler
11062    EXPORT_PC()
11063    mov    r0, rPC              @ arg0
11064    mov    r1, rFP              @ arg1
11065    mov    r2, rSELF            @ arg2
11066    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11067
11068/* ------------------------------ */
11069    .balign 64
11070.L_ALT_OP_IF_GTZ: /* 0x3c */
11071/* File: armv5te/alt_stub.S */
11072/*
11073 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11074 * any interesting requests and then jump to the real instruction
11075 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11076 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11077 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11078 * bail to the real handler if breakFlags==0.
11079 */
11080    ldrb   r3, [rSELF, #offThread_breakFlags]
11081    adrl   lr, dvmAsmInstructionStart + (60 * 64)
11082    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11083    cmp    r3, #0
11084    bxeq   lr                   @ nothing to do - jump to real handler
11085    EXPORT_PC()
11086    mov    r0, rPC              @ arg0
11087    mov    r1, rFP              @ arg1
11088    mov    r2, rSELF            @ arg2
11089    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11090
11091/* ------------------------------ */
11092    .balign 64
11093.L_ALT_OP_IF_LEZ: /* 0x3d */
11094/* File: armv5te/alt_stub.S */
11095/*
11096 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11097 * any interesting requests and then jump to the real instruction
11098 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11099 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11100 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11101 * bail to the real handler if breakFlags==0.
11102 */
11103    ldrb   r3, [rSELF, #offThread_breakFlags]
11104    adrl   lr, dvmAsmInstructionStart + (61 * 64)
11105    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11106    cmp    r3, #0
11107    bxeq   lr                   @ nothing to do - jump to real handler
11108    EXPORT_PC()
11109    mov    r0, rPC              @ arg0
11110    mov    r1, rFP              @ arg1
11111    mov    r2, rSELF            @ arg2
11112    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11113
11114/* ------------------------------ */
11115    .balign 64
11116.L_ALT_OP_UNUSED_3E: /* 0x3e */
11117/* File: armv5te/alt_stub.S */
11118/*
11119 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11120 * any interesting requests and then jump to the real instruction
11121 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11122 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11123 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11124 * bail to the real handler if breakFlags==0.
11125 */
11126    ldrb   r3, [rSELF, #offThread_breakFlags]
11127    adrl   lr, dvmAsmInstructionStart + (62 * 64)
11128    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11129    cmp    r3, #0
11130    bxeq   lr                   @ nothing to do - jump to real handler
11131    EXPORT_PC()
11132    mov    r0, rPC              @ arg0
11133    mov    r1, rFP              @ arg1
11134    mov    r2, rSELF            @ arg2
11135    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11136
11137/* ------------------------------ */
11138    .balign 64
11139.L_ALT_OP_UNUSED_3F: /* 0x3f */
11140/* File: armv5te/alt_stub.S */
11141/*
11142 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11143 * any interesting requests and then jump to the real instruction
11144 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11145 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11146 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11147 * bail to the real handler if breakFlags==0.
11148 */
11149    ldrb   r3, [rSELF, #offThread_breakFlags]
11150    adrl   lr, dvmAsmInstructionStart + (63 * 64)
11151    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11152    cmp    r3, #0
11153    bxeq   lr                   @ nothing to do - jump to real handler
11154    EXPORT_PC()
11155    mov    r0, rPC              @ arg0
11156    mov    r1, rFP              @ arg1
11157    mov    r2, rSELF            @ arg2
11158    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11159
11160/* ------------------------------ */
11161    .balign 64
11162.L_ALT_OP_UNUSED_40: /* 0x40 */
11163/* File: armv5te/alt_stub.S */
11164/*
11165 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11166 * any interesting requests and then jump to the real instruction
11167 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11168 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11169 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11170 * bail to the real handler if breakFlags==0.
11171 */
11172    ldrb   r3, [rSELF, #offThread_breakFlags]
11173    adrl   lr, dvmAsmInstructionStart + (64 * 64)
11174    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11175    cmp    r3, #0
11176    bxeq   lr                   @ nothing to do - jump to real handler
11177    EXPORT_PC()
11178    mov    r0, rPC              @ arg0
11179    mov    r1, rFP              @ arg1
11180    mov    r2, rSELF            @ arg2
11181    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11182
11183/* ------------------------------ */
11184    .balign 64
11185.L_ALT_OP_UNUSED_41: /* 0x41 */
11186/* File: armv5te/alt_stub.S */
11187/*
11188 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11189 * any interesting requests and then jump to the real instruction
11190 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11191 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11192 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11193 * bail to the real handler if breakFlags==0.
11194 */
11195    ldrb   r3, [rSELF, #offThread_breakFlags]
11196    adrl   lr, dvmAsmInstructionStart + (65 * 64)
11197    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11198    cmp    r3, #0
11199    bxeq   lr                   @ nothing to do - jump to real handler
11200    EXPORT_PC()
11201    mov    r0, rPC              @ arg0
11202    mov    r1, rFP              @ arg1
11203    mov    r2, rSELF            @ arg2
11204    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11205
11206/* ------------------------------ */
11207    .balign 64
11208.L_ALT_OP_UNUSED_42: /* 0x42 */
11209/* File: armv5te/alt_stub.S */
11210/*
11211 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11212 * any interesting requests and then jump to the real instruction
11213 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11214 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11215 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11216 * bail to the real handler if breakFlags==0.
11217 */
11218    ldrb   r3, [rSELF, #offThread_breakFlags]
11219    adrl   lr, dvmAsmInstructionStart + (66 * 64)
11220    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11221    cmp    r3, #0
11222    bxeq   lr                   @ nothing to do - jump to real handler
11223    EXPORT_PC()
11224    mov    r0, rPC              @ arg0
11225    mov    r1, rFP              @ arg1
11226    mov    r2, rSELF            @ arg2
11227    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11228
11229/* ------------------------------ */
11230    .balign 64
11231.L_ALT_OP_UNUSED_43: /* 0x43 */
11232/* File: armv5te/alt_stub.S */
11233/*
11234 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11235 * any interesting requests and then jump to the real instruction
11236 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11237 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11238 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11239 * bail to the real handler if breakFlags==0.
11240 */
11241    ldrb   r3, [rSELF, #offThread_breakFlags]
11242    adrl   lr, dvmAsmInstructionStart + (67 * 64)
11243    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11244    cmp    r3, #0
11245    bxeq   lr                   @ nothing to do - jump to real handler
11246    EXPORT_PC()
11247    mov    r0, rPC              @ arg0
11248    mov    r1, rFP              @ arg1
11249    mov    r2, rSELF            @ arg2
11250    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11251
11252/* ------------------------------ */
11253    .balign 64
11254.L_ALT_OP_AGET: /* 0x44 */
11255/* File: armv5te/alt_stub.S */
11256/*
11257 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11258 * any interesting requests and then jump to the real instruction
11259 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11260 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11261 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11262 * bail to the real handler if breakFlags==0.
11263 */
11264    ldrb   r3, [rSELF, #offThread_breakFlags]
11265    adrl   lr, dvmAsmInstructionStart + (68 * 64)
11266    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11267    cmp    r3, #0
11268    bxeq   lr                   @ nothing to do - jump to real handler
11269    EXPORT_PC()
11270    mov    r0, rPC              @ arg0
11271    mov    r1, rFP              @ arg1
11272    mov    r2, rSELF            @ arg2
11273    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11274
11275/* ------------------------------ */
11276    .balign 64
11277.L_ALT_OP_AGET_WIDE: /* 0x45 */
11278/* File: armv5te/alt_stub.S */
11279/*
11280 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11281 * any interesting requests and then jump to the real instruction
11282 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11283 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11284 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11285 * bail to the real handler if breakFlags==0.
11286 */
11287    ldrb   r3, [rSELF, #offThread_breakFlags]
11288    adrl   lr, dvmAsmInstructionStart + (69 * 64)
11289    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11290    cmp    r3, #0
11291    bxeq   lr                   @ nothing to do - jump to real handler
11292    EXPORT_PC()
11293    mov    r0, rPC              @ arg0
11294    mov    r1, rFP              @ arg1
11295    mov    r2, rSELF            @ arg2
11296    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11297
11298/* ------------------------------ */
11299    .balign 64
11300.L_ALT_OP_AGET_OBJECT: /* 0x46 */
11301/* File: armv5te/alt_stub.S */
11302/*
11303 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11304 * any interesting requests and then jump to the real instruction
11305 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11306 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11307 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11308 * bail to the real handler if breakFlags==0.
11309 */
11310    ldrb   r3, [rSELF, #offThread_breakFlags]
11311    adrl   lr, dvmAsmInstructionStart + (70 * 64)
11312    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11313    cmp    r3, #0
11314    bxeq   lr                   @ nothing to do - jump to real handler
11315    EXPORT_PC()
11316    mov    r0, rPC              @ arg0
11317    mov    r1, rFP              @ arg1
11318    mov    r2, rSELF            @ arg2
11319    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11320
11321/* ------------------------------ */
11322    .balign 64
11323.L_ALT_OP_AGET_BOOLEAN: /* 0x47 */
11324/* File: armv5te/alt_stub.S */
11325/*
11326 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11327 * any interesting requests and then jump to the real instruction
11328 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11329 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11330 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11331 * bail to the real handler if breakFlags==0.
11332 */
11333    ldrb   r3, [rSELF, #offThread_breakFlags]
11334    adrl   lr, dvmAsmInstructionStart + (71 * 64)
11335    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11336    cmp    r3, #0
11337    bxeq   lr                   @ nothing to do - jump to real handler
11338    EXPORT_PC()
11339    mov    r0, rPC              @ arg0
11340    mov    r1, rFP              @ arg1
11341    mov    r2, rSELF            @ arg2
11342    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11343
11344/* ------------------------------ */
11345    .balign 64
11346.L_ALT_OP_AGET_BYTE: /* 0x48 */
11347/* File: armv5te/alt_stub.S */
11348/*
11349 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11350 * any interesting requests and then jump to the real instruction
11351 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11352 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11353 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11354 * bail to the real handler if breakFlags==0.
11355 */
11356    ldrb   r3, [rSELF, #offThread_breakFlags]
11357    adrl   lr, dvmAsmInstructionStart + (72 * 64)
11358    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11359    cmp    r3, #0
11360    bxeq   lr                   @ nothing to do - jump to real handler
11361    EXPORT_PC()
11362    mov    r0, rPC              @ arg0
11363    mov    r1, rFP              @ arg1
11364    mov    r2, rSELF            @ arg2
11365    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11366
11367/* ------------------------------ */
11368    .balign 64
11369.L_ALT_OP_AGET_CHAR: /* 0x49 */
11370/* File: armv5te/alt_stub.S */
11371/*
11372 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11373 * any interesting requests and then jump to the real instruction
11374 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11375 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11376 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11377 * bail to the real handler if breakFlags==0.
11378 */
11379    ldrb   r3, [rSELF, #offThread_breakFlags]
11380    adrl   lr, dvmAsmInstructionStart + (73 * 64)
11381    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11382    cmp    r3, #0
11383    bxeq   lr                   @ nothing to do - jump to real handler
11384    EXPORT_PC()
11385    mov    r0, rPC              @ arg0
11386    mov    r1, rFP              @ arg1
11387    mov    r2, rSELF            @ arg2
11388    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11389
11390/* ------------------------------ */
11391    .balign 64
11392.L_ALT_OP_AGET_SHORT: /* 0x4a */
11393/* File: armv5te/alt_stub.S */
11394/*
11395 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11396 * any interesting requests and then jump to the real instruction
11397 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11398 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11399 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11400 * bail to the real handler if breakFlags==0.
11401 */
11402    ldrb   r3, [rSELF, #offThread_breakFlags]
11403    adrl   lr, dvmAsmInstructionStart + (74 * 64)
11404    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11405    cmp    r3, #0
11406    bxeq   lr                   @ nothing to do - jump to real handler
11407    EXPORT_PC()
11408    mov    r0, rPC              @ arg0
11409    mov    r1, rFP              @ arg1
11410    mov    r2, rSELF            @ arg2
11411    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11412
11413/* ------------------------------ */
11414    .balign 64
11415.L_ALT_OP_APUT: /* 0x4b */
11416/* File: armv5te/alt_stub.S */
11417/*
11418 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11419 * any interesting requests and then jump to the real instruction
11420 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11421 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11422 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11423 * bail to the real handler if breakFlags==0.
11424 */
11425    ldrb   r3, [rSELF, #offThread_breakFlags]
11426    adrl   lr, dvmAsmInstructionStart + (75 * 64)
11427    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11428    cmp    r3, #0
11429    bxeq   lr                   @ nothing to do - jump to real handler
11430    EXPORT_PC()
11431    mov    r0, rPC              @ arg0
11432    mov    r1, rFP              @ arg1
11433    mov    r2, rSELF            @ arg2
11434    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11435
11436/* ------------------------------ */
11437    .balign 64
11438.L_ALT_OP_APUT_WIDE: /* 0x4c */
11439/* File: armv5te/alt_stub.S */
11440/*
11441 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11442 * any interesting requests and then jump to the real instruction
11443 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11444 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11445 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11446 * bail to the real handler if breakFlags==0.
11447 */
11448    ldrb   r3, [rSELF, #offThread_breakFlags]
11449    adrl   lr, dvmAsmInstructionStart + (76 * 64)
11450    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11451    cmp    r3, #0
11452    bxeq   lr                   @ nothing to do - jump to real handler
11453    EXPORT_PC()
11454    mov    r0, rPC              @ arg0
11455    mov    r1, rFP              @ arg1
11456    mov    r2, rSELF            @ arg2
11457    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11458
11459/* ------------------------------ */
11460    .balign 64
11461.L_ALT_OP_APUT_OBJECT: /* 0x4d */
11462/* File: armv5te/alt_stub.S */
11463/*
11464 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11465 * any interesting requests and then jump to the real instruction
11466 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11467 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11468 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11469 * bail to the real handler if breakFlags==0.
11470 */
11471    ldrb   r3, [rSELF, #offThread_breakFlags]
11472    adrl   lr, dvmAsmInstructionStart + (77 * 64)
11473    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11474    cmp    r3, #0
11475    bxeq   lr                   @ nothing to do - jump to real handler
11476    EXPORT_PC()
11477    mov    r0, rPC              @ arg0
11478    mov    r1, rFP              @ arg1
11479    mov    r2, rSELF            @ arg2
11480    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11481
11482/* ------------------------------ */
11483    .balign 64
11484.L_ALT_OP_APUT_BOOLEAN: /* 0x4e */
11485/* File: armv5te/alt_stub.S */
11486/*
11487 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11488 * any interesting requests and then jump to the real instruction
11489 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11490 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11491 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11492 * bail to the real handler if breakFlags==0.
11493 */
11494    ldrb   r3, [rSELF, #offThread_breakFlags]
11495    adrl   lr, dvmAsmInstructionStart + (78 * 64)
11496    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11497    cmp    r3, #0
11498    bxeq   lr                   @ nothing to do - jump to real handler
11499    EXPORT_PC()
11500    mov    r0, rPC              @ arg0
11501    mov    r1, rFP              @ arg1
11502    mov    r2, rSELF            @ arg2
11503    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11504
11505/* ------------------------------ */
11506    .balign 64
11507.L_ALT_OP_APUT_BYTE: /* 0x4f */
11508/* File: armv5te/alt_stub.S */
11509/*
11510 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11511 * any interesting requests and then jump to the real instruction
11512 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11513 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11514 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11515 * bail to the real handler if breakFlags==0.
11516 */
11517    ldrb   r3, [rSELF, #offThread_breakFlags]
11518    adrl   lr, dvmAsmInstructionStart + (79 * 64)
11519    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11520    cmp    r3, #0
11521    bxeq   lr                   @ nothing to do - jump to real handler
11522    EXPORT_PC()
11523    mov    r0, rPC              @ arg0
11524    mov    r1, rFP              @ arg1
11525    mov    r2, rSELF            @ arg2
11526    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11527
11528/* ------------------------------ */
11529    .balign 64
11530.L_ALT_OP_APUT_CHAR: /* 0x50 */
11531/* File: armv5te/alt_stub.S */
11532/*
11533 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11534 * any interesting requests and then jump to the real instruction
11535 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11536 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11537 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11538 * bail to the real handler if breakFlags==0.
11539 */
11540    ldrb   r3, [rSELF, #offThread_breakFlags]
11541    adrl   lr, dvmAsmInstructionStart + (80 * 64)
11542    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11543    cmp    r3, #0
11544    bxeq   lr                   @ nothing to do - jump to real handler
11545    EXPORT_PC()
11546    mov    r0, rPC              @ arg0
11547    mov    r1, rFP              @ arg1
11548    mov    r2, rSELF            @ arg2
11549    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11550
11551/* ------------------------------ */
11552    .balign 64
11553.L_ALT_OP_APUT_SHORT: /* 0x51 */
11554/* File: armv5te/alt_stub.S */
11555/*
11556 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11557 * any interesting requests and then jump to the real instruction
11558 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11559 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11560 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11561 * bail to the real handler if breakFlags==0.
11562 */
11563    ldrb   r3, [rSELF, #offThread_breakFlags]
11564    adrl   lr, dvmAsmInstructionStart + (81 * 64)
11565    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11566    cmp    r3, #0
11567    bxeq   lr                   @ nothing to do - jump to real handler
11568    EXPORT_PC()
11569    mov    r0, rPC              @ arg0
11570    mov    r1, rFP              @ arg1
11571    mov    r2, rSELF            @ arg2
11572    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11573
11574/* ------------------------------ */
11575    .balign 64
11576.L_ALT_OP_IGET: /* 0x52 */
11577/* File: armv5te/alt_stub.S */
11578/*
11579 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11580 * any interesting requests and then jump to the real instruction
11581 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11582 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11583 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11584 * bail to the real handler if breakFlags==0.
11585 */
11586    ldrb   r3, [rSELF, #offThread_breakFlags]
11587    adrl   lr, dvmAsmInstructionStart + (82 * 64)
11588    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11589    cmp    r3, #0
11590    bxeq   lr                   @ nothing to do - jump to real handler
11591    EXPORT_PC()
11592    mov    r0, rPC              @ arg0
11593    mov    r1, rFP              @ arg1
11594    mov    r2, rSELF            @ arg2
11595    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11596
11597/* ------------------------------ */
11598    .balign 64
11599.L_ALT_OP_IGET_WIDE: /* 0x53 */
11600/* File: armv5te/alt_stub.S */
11601/*
11602 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11603 * any interesting requests and then jump to the real instruction
11604 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11605 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11606 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11607 * bail to the real handler if breakFlags==0.
11608 */
11609    ldrb   r3, [rSELF, #offThread_breakFlags]
11610    adrl   lr, dvmAsmInstructionStart + (83 * 64)
11611    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11612    cmp    r3, #0
11613    bxeq   lr                   @ nothing to do - jump to real handler
11614    EXPORT_PC()
11615    mov    r0, rPC              @ arg0
11616    mov    r1, rFP              @ arg1
11617    mov    r2, rSELF            @ arg2
11618    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11619
11620/* ------------------------------ */
11621    .balign 64
11622.L_ALT_OP_IGET_OBJECT: /* 0x54 */
11623/* File: armv5te/alt_stub.S */
11624/*
11625 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11626 * any interesting requests and then jump to the real instruction
11627 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11628 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11629 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11630 * bail to the real handler if breakFlags==0.
11631 */
11632    ldrb   r3, [rSELF, #offThread_breakFlags]
11633    adrl   lr, dvmAsmInstructionStart + (84 * 64)
11634    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11635    cmp    r3, #0
11636    bxeq   lr                   @ nothing to do - jump to real handler
11637    EXPORT_PC()
11638    mov    r0, rPC              @ arg0
11639    mov    r1, rFP              @ arg1
11640    mov    r2, rSELF            @ arg2
11641    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11642
11643/* ------------------------------ */
11644    .balign 64
11645.L_ALT_OP_IGET_BOOLEAN: /* 0x55 */
11646/* File: armv5te/alt_stub.S */
11647/*
11648 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11649 * any interesting requests and then jump to the real instruction
11650 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11651 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11652 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11653 * bail to the real handler if breakFlags==0.
11654 */
11655    ldrb   r3, [rSELF, #offThread_breakFlags]
11656    adrl   lr, dvmAsmInstructionStart + (85 * 64)
11657    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11658    cmp    r3, #0
11659    bxeq   lr                   @ nothing to do - jump to real handler
11660    EXPORT_PC()
11661    mov    r0, rPC              @ arg0
11662    mov    r1, rFP              @ arg1
11663    mov    r2, rSELF            @ arg2
11664    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11665
11666/* ------------------------------ */
11667    .balign 64
11668.L_ALT_OP_IGET_BYTE: /* 0x56 */
11669/* File: armv5te/alt_stub.S */
11670/*
11671 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11672 * any interesting requests and then jump to the real instruction
11673 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11674 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11675 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11676 * bail to the real handler if breakFlags==0.
11677 */
11678    ldrb   r3, [rSELF, #offThread_breakFlags]
11679    adrl   lr, dvmAsmInstructionStart + (86 * 64)
11680    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11681    cmp    r3, #0
11682    bxeq   lr                   @ nothing to do - jump to real handler
11683    EXPORT_PC()
11684    mov    r0, rPC              @ arg0
11685    mov    r1, rFP              @ arg1
11686    mov    r2, rSELF            @ arg2
11687    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11688
11689/* ------------------------------ */
11690    .balign 64
11691.L_ALT_OP_IGET_CHAR: /* 0x57 */
11692/* File: armv5te/alt_stub.S */
11693/*
11694 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11695 * any interesting requests and then jump to the real instruction
11696 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11697 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11698 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11699 * bail to the real handler if breakFlags==0.
11700 */
11701    ldrb   r3, [rSELF, #offThread_breakFlags]
11702    adrl   lr, dvmAsmInstructionStart + (87 * 64)
11703    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11704    cmp    r3, #0
11705    bxeq   lr                   @ nothing to do - jump to real handler
11706    EXPORT_PC()
11707    mov    r0, rPC              @ arg0
11708    mov    r1, rFP              @ arg1
11709    mov    r2, rSELF            @ arg2
11710    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11711
11712/* ------------------------------ */
11713    .balign 64
11714.L_ALT_OP_IGET_SHORT: /* 0x58 */
11715/* File: armv5te/alt_stub.S */
11716/*
11717 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11718 * any interesting requests and then jump to the real instruction
11719 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11720 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11721 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11722 * bail to the real handler if breakFlags==0.
11723 */
11724    ldrb   r3, [rSELF, #offThread_breakFlags]
11725    adrl   lr, dvmAsmInstructionStart + (88 * 64)
11726    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11727    cmp    r3, #0
11728    bxeq   lr                   @ nothing to do - jump to real handler
11729    EXPORT_PC()
11730    mov    r0, rPC              @ arg0
11731    mov    r1, rFP              @ arg1
11732    mov    r2, rSELF            @ arg2
11733    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11734
11735/* ------------------------------ */
11736    .balign 64
11737.L_ALT_OP_IPUT: /* 0x59 */
11738/* File: armv5te/alt_stub.S */
11739/*
11740 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11741 * any interesting requests and then jump to the real instruction
11742 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11743 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11744 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11745 * bail to the real handler if breakFlags==0.
11746 */
11747    ldrb   r3, [rSELF, #offThread_breakFlags]
11748    adrl   lr, dvmAsmInstructionStart + (89 * 64)
11749    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11750    cmp    r3, #0
11751    bxeq   lr                   @ nothing to do - jump to real handler
11752    EXPORT_PC()
11753    mov    r0, rPC              @ arg0
11754    mov    r1, rFP              @ arg1
11755    mov    r2, rSELF            @ arg2
11756    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11757
11758/* ------------------------------ */
11759    .balign 64
11760.L_ALT_OP_IPUT_WIDE: /* 0x5a */
11761/* File: armv5te/alt_stub.S */
11762/*
11763 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11764 * any interesting requests and then jump to the real instruction
11765 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11766 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11767 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11768 * bail to the real handler if breakFlags==0.
11769 */
11770    ldrb   r3, [rSELF, #offThread_breakFlags]
11771    adrl   lr, dvmAsmInstructionStart + (90 * 64)
11772    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11773    cmp    r3, #0
11774    bxeq   lr                   @ nothing to do - jump to real handler
11775    EXPORT_PC()
11776    mov    r0, rPC              @ arg0
11777    mov    r1, rFP              @ arg1
11778    mov    r2, rSELF            @ arg2
11779    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11780
11781/* ------------------------------ */
11782    .balign 64
11783.L_ALT_OP_IPUT_OBJECT: /* 0x5b */
11784/* File: armv5te/alt_stub.S */
11785/*
11786 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11787 * any interesting requests and then jump to the real instruction
11788 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11789 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11790 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11791 * bail to the real handler if breakFlags==0.
11792 */
11793    ldrb   r3, [rSELF, #offThread_breakFlags]
11794    adrl   lr, dvmAsmInstructionStart + (91 * 64)
11795    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11796    cmp    r3, #0
11797    bxeq   lr                   @ nothing to do - jump to real handler
11798    EXPORT_PC()
11799    mov    r0, rPC              @ arg0
11800    mov    r1, rFP              @ arg1
11801    mov    r2, rSELF            @ arg2
11802    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11803
11804/* ------------------------------ */
11805    .balign 64
11806.L_ALT_OP_IPUT_BOOLEAN: /* 0x5c */
11807/* File: armv5te/alt_stub.S */
11808/*
11809 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11810 * any interesting requests and then jump to the real instruction
11811 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11812 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11813 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11814 * bail to the real handler if breakFlags==0.
11815 */
11816    ldrb   r3, [rSELF, #offThread_breakFlags]
11817    adrl   lr, dvmAsmInstructionStart + (92 * 64)
11818    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11819    cmp    r3, #0
11820    bxeq   lr                   @ nothing to do - jump to real handler
11821    EXPORT_PC()
11822    mov    r0, rPC              @ arg0
11823    mov    r1, rFP              @ arg1
11824    mov    r2, rSELF            @ arg2
11825    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11826
11827/* ------------------------------ */
11828    .balign 64
11829.L_ALT_OP_IPUT_BYTE: /* 0x5d */
11830/* File: armv5te/alt_stub.S */
11831/*
11832 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11833 * any interesting requests and then jump to the real instruction
11834 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11835 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11836 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11837 * bail to the real handler if breakFlags==0.
11838 */
11839    ldrb   r3, [rSELF, #offThread_breakFlags]
11840    adrl   lr, dvmAsmInstructionStart + (93 * 64)
11841    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11842    cmp    r3, #0
11843    bxeq   lr                   @ nothing to do - jump to real handler
11844    EXPORT_PC()
11845    mov    r0, rPC              @ arg0
11846    mov    r1, rFP              @ arg1
11847    mov    r2, rSELF            @ arg2
11848    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11849
11850/* ------------------------------ */
11851    .balign 64
11852.L_ALT_OP_IPUT_CHAR: /* 0x5e */
11853/* File: armv5te/alt_stub.S */
11854/*
11855 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11856 * any interesting requests and then jump to the real instruction
11857 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11858 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11859 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11860 * bail to the real handler if breakFlags==0.
11861 */
11862    ldrb   r3, [rSELF, #offThread_breakFlags]
11863    adrl   lr, dvmAsmInstructionStart + (94 * 64)
11864    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11865    cmp    r3, #0
11866    bxeq   lr                   @ nothing to do - jump to real handler
11867    EXPORT_PC()
11868    mov    r0, rPC              @ arg0
11869    mov    r1, rFP              @ arg1
11870    mov    r2, rSELF            @ arg2
11871    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11872
11873/* ------------------------------ */
11874    .balign 64
11875.L_ALT_OP_IPUT_SHORT: /* 0x5f */
11876/* File: armv5te/alt_stub.S */
11877/*
11878 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11879 * any interesting requests and then jump to the real instruction
11880 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11881 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11882 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11883 * bail to the real handler if breakFlags==0.
11884 */
11885    ldrb   r3, [rSELF, #offThread_breakFlags]
11886    adrl   lr, dvmAsmInstructionStart + (95 * 64)
11887    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11888    cmp    r3, #0
11889    bxeq   lr                   @ nothing to do - jump to real handler
11890    EXPORT_PC()
11891    mov    r0, rPC              @ arg0
11892    mov    r1, rFP              @ arg1
11893    mov    r2, rSELF            @ arg2
11894    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11895
11896/* ------------------------------ */
11897    .balign 64
11898.L_ALT_OP_SGET: /* 0x60 */
11899/* File: armv5te/alt_stub.S */
11900/*
11901 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11902 * any interesting requests and then jump to the real instruction
11903 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11904 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11905 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11906 * bail to the real handler if breakFlags==0.
11907 */
11908    ldrb   r3, [rSELF, #offThread_breakFlags]
11909    adrl   lr, dvmAsmInstructionStart + (96 * 64)
11910    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11911    cmp    r3, #0
11912    bxeq   lr                   @ nothing to do - jump to real handler
11913    EXPORT_PC()
11914    mov    r0, rPC              @ arg0
11915    mov    r1, rFP              @ arg1
11916    mov    r2, rSELF            @ arg2
11917    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11918
11919/* ------------------------------ */
11920    .balign 64
11921.L_ALT_OP_SGET_WIDE: /* 0x61 */
11922/* File: armv5te/alt_stub.S */
11923/*
11924 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11925 * any interesting requests and then jump to the real instruction
11926 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11927 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11928 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11929 * bail to the real handler if breakFlags==0.
11930 */
11931    ldrb   r3, [rSELF, #offThread_breakFlags]
11932    adrl   lr, dvmAsmInstructionStart + (97 * 64)
11933    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11934    cmp    r3, #0
11935    bxeq   lr                   @ nothing to do - jump to real handler
11936    EXPORT_PC()
11937    mov    r0, rPC              @ arg0
11938    mov    r1, rFP              @ arg1
11939    mov    r2, rSELF            @ arg2
11940    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11941
11942/* ------------------------------ */
11943    .balign 64
11944.L_ALT_OP_SGET_OBJECT: /* 0x62 */
11945/* File: armv5te/alt_stub.S */
11946/*
11947 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11948 * any interesting requests and then jump to the real instruction
11949 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11950 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11951 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11952 * bail to the real handler if breakFlags==0.
11953 */
11954    ldrb   r3, [rSELF, #offThread_breakFlags]
11955    adrl   lr, dvmAsmInstructionStart + (98 * 64)
11956    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11957    cmp    r3, #0
11958    bxeq   lr                   @ nothing to do - jump to real handler
11959    EXPORT_PC()
11960    mov    r0, rPC              @ arg0
11961    mov    r1, rFP              @ arg1
11962    mov    r2, rSELF            @ arg2
11963    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11964
11965/* ------------------------------ */
11966    .balign 64
11967.L_ALT_OP_SGET_BOOLEAN: /* 0x63 */
11968/* File: armv5te/alt_stub.S */
11969/*
11970 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11971 * any interesting requests and then jump to the real instruction
11972 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11973 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11974 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11975 * bail to the real handler if breakFlags==0.
11976 */
11977    ldrb   r3, [rSELF, #offThread_breakFlags]
11978    adrl   lr, dvmAsmInstructionStart + (99 * 64)
11979    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11980    cmp    r3, #0
11981    bxeq   lr                   @ nothing to do - jump to real handler
11982    EXPORT_PC()
11983    mov    r0, rPC              @ arg0
11984    mov    r1, rFP              @ arg1
11985    mov    r2, rSELF            @ arg2
11986    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11987
11988/* ------------------------------ */
11989    .balign 64
11990.L_ALT_OP_SGET_BYTE: /* 0x64 */
11991/* File: armv5te/alt_stub.S */
11992/*
11993 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11994 * any interesting requests and then jump to the real instruction
11995 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11996 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11997 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11998 * bail to the real handler if breakFlags==0.
11999 */
12000    ldrb   r3, [rSELF, #offThread_breakFlags]
12001    adrl   lr, dvmAsmInstructionStart + (100 * 64)
12002    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12003    cmp    r3, #0
12004    bxeq   lr                   @ nothing to do - jump to real handler
12005    EXPORT_PC()
12006    mov    r0, rPC              @ arg0
12007    mov    r1, rFP              @ arg1
12008    mov    r2, rSELF            @ arg2
12009    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12010
12011/* ------------------------------ */
12012    .balign 64
12013.L_ALT_OP_SGET_CHAR: /* 0x65 */
12014/* File: armv5te/alt_stub.S */
12015/*
12016 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12017 * any interesting requests and then jump to the real instruction
12018 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12019 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12020 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12021 * bail to the real handler if breakFlags==0.
12022 */
12023    ldrb   r3, [rSELF, #offThread_breakFlags]
12024    adrl   lr, dvmAsmInstructionStart + (101 * 64)
12025    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12026    cmp    r3, #0
12027    bxeq   lr                   @ nothing to do - jump to real handler
12028    EXPORT_PC()
12029    mov    r0, rPC              @ arg0
12030    mov    r1, rFP              @ arg1
12031    mov    r2, rSELF            @ arg2
12032    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12033
12034/* ------------------------------ */
12035    .balign 64
12036.L_ALT_OP_SGET_SHORT: /* 0x66 */
12037/* File: armv5te/alt_stub.S */
12038/*
12039 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12040 * any interesting requests and then jump to the real instruction
12041 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12042 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12043 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12044 * bail to the real handler if breakFlags==0.
12045 */
12046    ldrb   r3, [rSELF, #offThread_breakFlags]
12047    adrl   lr, dvmAsmInstructionStart + (102 * 64)
12048    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12049    cmp    r3, #0
12050    bxeq   lr                   @ nothing to do - jump to real handler
12051    EXPORT_PC()
12052    mov    r0, rPC              @ arg0
12053    mov    r1, rFP              @ arg1
12054    mov    r2, rSELF            @ arg2
12055    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12056
12057/* ------------------------------ */
12058    .balign 64
12059.L_ALT_OP_SPUT: /* 0x67 */
12060/* File: armv5te/alt_stub.S */
12061/*
12062 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12063 * any interesting requests and then jump to the real instruction
12064 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12065 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12066 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12067 * bail to the real handler if breakFlags==0.
12068 */
12069    ldrb   r3, [rSELF, #offThread_breakFlags]
12070    adrl   lr, dvmAsmInstructionStart + (103 * 64)
12071    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12072    cmp    r3, #0
12073    bxeq   lr                   @ nothing to do - jump to real handler
12074    EXPORT_PC()
12075    mov    r0, rPC              @ arg0
12076    mov    r1, rFP              @ arg1
12077    mov    r2, rSELF            @ arg2
12078    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12079
12080/* ------------------------------ */
12081    .balign 64
12082.L_ALT_OP_SPUT_WIDE: /* 0x68 */
12083/* File: armv5te/alt_stub.S */
12084/*
12085 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12086 * any interesting requests and then jump to the real instruction
12087 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12088 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12089 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12090 * bail to the real handler if breakFlags==0.
12091 */
12092    ldrb   r3, [rSELF, #offThread_breakFlags]
12093    adrl   lr, dvmAsmInstructionStart + (104 * 64)
12094    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12095    cmp    r3, #0
12096    bxeq   lr                   @ nothing to do - jump to real handler
12097    EXPORT_PC()
12098    mov    r0, rPC              @ arg0
12099    mov    r1, rFP              @ arg1
12100    mov    r2, rSELF            @ arg2
12101    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12102
12103/* ------------------------------ */
12104    .balign 64
12105.L_ALT_OP_SPUT_OBJECT: /* 0x69 */
12106/* File: armv5te/alt_stub.S */
12107/*
12108 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12109 * any interesting requests and then jump to the real instruction
12110 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12111 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12112 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12113 * bail to the real handler if breakFlags==0.
12114 */
12115    ldrb   r3, [rSELF, #offThread_breakFlags]
12116    adrl   lr, dvmAsmInstructionStart + (105 * 64)
12117    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12118    cmp    r3, #0
12119    bxeq   lr                   @ nothing to do - jump to real handler
12120    EXPORT_PC()
12121    mov    r0, rPC              @ arg0
12122    mov    r1, rFP              @ arg1
12123    mov    r2, rSELF            @ arg2
12124    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12125
12126/* ------------------------------ */
12127    .balign 64
12128.L_ALT_OP_SPUT_BOOLEAN: /* 0x6a */
12129/* File: armv5te/alt_stub.S */
12130/*
12131 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12132 * any interesting requests and then jump to the real instruction
12133 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12134 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12135 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12136 * bail to the real handler if breakFlags==0.
12137 */
12138    ldrb   r3, [rSELF, #offThread_breakFlags]
12139    adrl   lr, dvmAsmInstructionStart + (106 * 64)
12140    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12141    cmp    r3, #0
12142    bxeq   lr                   @ nothing to do - jump to real handler
12143    EXPORT_PC()
12144    mov    r0, rPC              @ arg0
12145    mov    r1, rFP              @ arg1
12146    mov    r2, rSELF            @ arg2
12147    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12148
12149/* ------------------------------ */
12150    .balign 64
12151.L_ALT_OP_SPUT_BYTE: /* 0x6b */
12152/* File: armv5te/alt_stub.S */
12153/*
12154 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12155 * any interesting requests and then jump to the real instruction
12156 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12157 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12158 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12159 * bail to the real handler if breakFlags==0.
12160 */
12161    ldrb   r3, [rSELF, #offThread_breakFlags]
12162    adrl   lr, dvmAsmInstructionStart + (107 * 64)
12163    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12164    cmp    r3, #0
12165    bxeq   lr                   @ nothing to do - jump to real handler
12166    EXPORT_PC()
12167    mov    r0, rPC              @ arg0
12168    mov    r1, rFP              @ arg1
12169    mov    r2, rSELF            @ arg2
12170    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12171
12172/* ------------------------------ */
12173    .balign 64
12174.L_ALT_OP_SPUT_CHAR: /* 0x6c */
12175/* File: armv5te/alt_stub.S */
12176/*
12177 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12178 * any interesting requests and then jump to the real instruction
12179 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12180 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12181 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12182 * bail to the real handler if breakFlags==0.
12183 */
12184    ldrb   r3, [rSELF, #offThread_breakFlags]
12185    adrl   lr, dvmAsmInstructionStart + (108 * 64)
12186    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12187    cmp    r3, #0
12188    bxeq   lr                   @ nothing to do - jump to real handler
12189    EXPORT_PC()
12190    mov    r0, rPC              @ arg0
12191    mov    r1, rFP              @ arg1
12192    mov    r2, rSELF            @ arg2
12193    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12194
12195/* ------------------------------ */
12196    .balign 64
12197.L_ALT_OP_SPUT_SHORT: /* 0x6d */
12198/* File: armv5te/alt_stub.S */
12199/*
12200 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12201 * any interesting requests and then jump to the real instruction
12202 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12203 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12204 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12205 * bail to the real handler if breakFlags==0.
12206 */
12207    ldrb   r3, [rSELF, #offThread_breakFlags]
12208    adrl   lr, dvmAsmInstructionStart + (109 * 64)
12209    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12210    cmp    r3, #0
12211    bxeq   lr                   @ nothing to do - jump to real handler
12212    EXPORT_PC()
12213    mov    r0, rPC              @ arg0
12214    mov    r1, rFP              @ arg1
12215    mov    r2, rSELF            @ arg2
12216    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12217
12218/* ------------------------------ */
12219    .balign 64
12220.L_ALT_OP_INVOKE_VIRTUAL: /* 0x6e */
12221/* File: armv5te/alt_stub.S */
12222/*
12223 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12224 * any interesting requests and then jump to the real instruction
12225 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12226 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12227 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12228 * bail to the real handler if breakFlags==0.
12229 */
12230    ldrb   r3, [rSELF, #offThread_breakFlags]
12231    adrl   lr, dvmAsmInstructionStart + (110 * 64)
12232    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12233    cmp    r3, #0
12234    bxeq   lr                   @ nothing to do - jump to real handler
12235    EXPORT_PC()
12236    mov    r0, rPC              @ arg0
12237    mov    r1, rFP              @ arg1
12238    mov    r2, rSELF            @ arg2
12239    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12240
12241/* ------------------------------ */
12242    .balign 64
12243.L_ALT_OP_INVOKE_SUPER: /* 0x6f */
12244/* File: armv5te/alt_stub.S */
12245/*
12246 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12247 * any interesting requests and then jump to the real instruction
12248 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12249 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12250 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12251 * bail to the real handler if breakFlags==0.
12252 */
12253    ldrb   r3, [rSELF, #offThread_breakFlags]
12254    adrl   lr, dvmAsmInstructionStart + (111 * 64)
12255    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12256    cmp    r3, #0
12257    bxeq   lr                   @ nothing to do - jump to real handler
12258    EXPORT_PC()
12259    mov    r0, rPC              @ arg0
12260    mov    r1, rFP              @ arg1
12261    mov    r2, rSELF            @ arg2
12262    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12263
12264/* ------------------------------ */
12265    .balign 64
12266.L_ALT_OP_INVOKE_DIRECT: /* 0x70 */
12267/* File: armv5te/alt_stub.S */
12268/*
12269 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12270 * any interesting requests and then jump to the real instruction
12271 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12272 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12273 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12274 * bail to the real handler if breakFlags==0.
12275 */
12276    ldrb   r3, [rSELF, #offThread_breakFlags]
12277    adrl   lr, dvmAsmInstructionStart + (112 * 64)
12278    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12279    cmp    r3, #0
12280    bxeq   lr                   @ nothing to do - jump to real handler
12281    EXPORT_PC()
12282    mov    r0, rPC              @ arg0
12283    mov    r1, rFP              @ arg1
12284    mov    r2, rSELF            @ arg2
12285    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12286
12287/* ------------------------------ */
12288    .balign 64
12289.L_ALT_OP_INVOKE_STATIC: /* 0x71 */
12290/* File: armv5te/alt_stub.S */
12291/*
12292 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12293 * any interesting requests and then jump to the real instruction
12294 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12295 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12296 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12297 * bail to the real handler if breakFlags==0.
12298 */
12299    ldrb   r3, [rSELF, #offThread_breakFlags]
12300    adrl   lr, dvmAsmInstructionStart + (113 * 64)
12301    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12302    cmp    r3, #0
12303    bxeq   lr                   @ nothing to do - jump to real handler
12304    EXPORT_PC()
12305    mov    r0, rPC              @ arg0
12306    mov    r1, rFP              @ arg1
12307    mov    r2, rSELF            @ arg2
12308    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12309
12310/* ------------------------------ */
12311    .balign 64
12312.L_ALT_OP_INVOKE_INTERFACE: /* 0x72 */
12313/* File: armv5te/alt_stub.S */
12314/*
12315 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12316 * any interesting requests and then jump to the real instruction
12317 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12318 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12319 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12320 * bail to the real handler if breakFlags==0.
12321 */
12322    ldrb   r3, [rSELF, #offThread_breakFlags]
12323    adrl   lr, dvmAsmInstructionStart + (114 * 64)
12324    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12325    cmp    r3, #0
12326    bxeq   lr                   @ nothing to do - jump to real handler
12327    EXPORT_PC()
12328    mov    r0, rPC              @ arg0
12329    mov    r1, rFP              @ arg1
12330    mov    r2, rSELF            @ arg2
12331    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12332
12333/* ------------------------------ */
12334    .balign 64
12335.L_ALT_OP_UNUSED_73: /* 0x73 */
12336/* File: armv5te/alt_stub.S */
12337/*
12338 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12339 * any interesting requests and then jump to the real instruction
12340 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12341 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12342 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12343 * bail to the real handler if breakFlags==0.
12344 */
12345    ldrb   r3, [rSELF, #offThread_breakFlags]
12346    adrl   lr, dvmAsmInstructionStart + (115 * 64)
12347    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12348    cmp    r3, #0
12349    bxeq   lr                   @ nothing to do - jump to real handler
12350    EXPORT_PC()
12351    mov    r0, rPC              @ arg0
12352    mov    r1, rFP              @ arg1
12353    mov    r2, rSELF            @ arg2
12354    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12355
12356/* ------------------------------ */
12357    .balign 64
12358.L_ALT_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
12359/* File: armv5te/alt_stub.S */
12360/*
12361 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12362 * any interesting requests and then jump to the real instruction
12363 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12364 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12365 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12366 * bail to the real handler if breakFlags==0.
12367 */
12368    ldrb   r3, [rSELF, #offThread_breakFlags]
12369    adrl   lr, dvmAsmInstructionStart + (116 * 64)
12370    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12371    cmp    r3, #0
12372    bxeq   lr                   @ nothing to do - jump to real handler
12373    EXPORT_PC()
12374    mov    r0, rPC              @ arg0
12375    mov    r1, rFP              @ arg1
12376    mov    r2, rSELF            @ arg2
12377    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12378
12379/* ------------------------------ */
12380    .balign 64
12381.L_ALT_OP_INVOKE_SUPER_RANGE: /* 0x75 */
12382/* File: armv5te/alt_stub.S */
12383/*
12384 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12385 * any interesting requests and then jump to the real instruction
12386 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12387 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12388 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12389 * bail to the real handler if breakFlags==0.
12390 */
12391    ldrb   r3, [rSELF, #offThread_breakFlags]
12392    adrl   lr, dvmAsmInstructionStart + (117 * 64)
12393    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12394    cmp    r3, #0
12395    bxeq   lr                   @ nothing to do - jump to real handler
12396    EXPORT_PC()
12397    mov    r0, rPC              @ arg0
12398    mov    r1, rFP              @ arg1
12399    mov    r2, rSELF            @ arg2
12400    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12401
12402/* ------------------------------ */
12403    .balign 64
12404.L_ALT_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
12405/* File: armv5te/alt_stub.S */
12406/*
12407 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12408 * any interesting requests and then jump to the real instruction
12409 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12410 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12411 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12412 * bail to the real handler if breakFlags==0.
12413 */
12414    ldrb   r3, [rSELF, #offThread_breakFlags]
12415    adrl   lr, dvmAsmInstructionStart + (118 * 64)
12416    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12417    cmp    r3, #0
12418    bxeq   lr                   @ nothing to do - jump to real handler
12419    EXPORT_PC()
12420    mov    r0, rPC              @ arg0
12421    mov    r1, rFP              @ arg1
12422    mov    r2, rSELF            @ arg2
12423    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12424
12425/* ------------------------------ */
12426    .balign 64
12427.L_ALT_OP_INVOKE_STATIC_RANGE: /* 0x77 */
12428/* File: armv5te/alt_stub.S */
12429/*
12430 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12431 * any interesting requests and then jump to the real instruction
12432 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12433 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12434 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12435 * bail to the real handler if breakFlags==0.
12436 */
12437    ldrb   r3, [rSELF, #offThread_breakFlags]
12438    adrl   lr, dvmAsmInstructionStart + (119 * 64)
12439    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12440    cmp    r3, #0
12441    bxeq   lr                   @ nothing to do - jump to real handler
12442    EXPORT_PC()
12443    mov    r0, rPC              @ arg0
12444    mov    r1, rFP              @ arg1
12445    mov    r2, rSELF            @ arg2
12446    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12447
12448/* ------------------------------ */
12449    .balign 64
12450.L_ALT_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
12451/* File: armv5te/alt_stub.S */
12452/*
12453 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12454 * any interesting requests and then jump to the real instruction
12455 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12456 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12457 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12458 * bail to the real handler if breakFlags==0.
12459 */
12460    ldrb   r3, [rSELF, #offThread_breakFlags]
12461    adrl   lr, dvmAsmInstructionStart + (120 * 64)
12462    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12463    cmp    r3, #0
12464    bxeq   lr                   @ nothing to do - jump to real handler
12465    EXPORT_PC()
12466    mov    r0, rPC              @ arg0
12467    mov    r1, rFP              @ arg1
12468    mov    r2, rSELF            @ arg2
12469    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12470
12471/* ------------------------------ */
12472    .balign 64
12473.L_ALT_OP_UNUSED_79: /* 0x79 */
12474/* File: armv5te/alt_stub.S */
12475/*
12476 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12477 * any interesting requests and then jump to the real instruction
12478 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12479 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12480 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12481 * bail to the real handler if breakFlags==0.
12482 */
12483    ldrb   r3, [rSELF, #offThread_breakFlags]
12484    adrl   lr, dvmAsmInstructionStart + (121 * 64)
12485    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12486    cmp    r3, #0
12487    bxeq   lr                   @ nothing to do - jump to real handler
12488    EXPORT_PC()
12489    mov    r0, rPC              @ arg0
12490    mov    r1, rFP              @ arg1
12491    mov    r2, rSELF            @ arg2
12492    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12493
12494/* ------------------------------ */
12495    .balign 64
12496.L_ALT_OP_UNUSED_7A: /* 0x7a */
12497/* File: armv5te/alt_stub.S */
12498/*
12499 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12500 * any interesting requests and then jump to the real instruction
12501 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12502 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12503 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12504 * bail to the real handler if breakFlags==0.
12505 */
12506    ldrb   r3, [rSELF, #offThread_breakFlags]
12507    adrl   lr, dvmAsmInstructionStart + (122 * 64)
12508    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12509    cmp    r3, #0
12510    bxeq   lr                   @ nothing to do - jump to real handler
12511    EXPORT_PC()
12512    mov    r0, rPC              @ arg0
12513    mov    r1, rFP              @ arg1
12514    mov    r2, rSELF            @ arg2
12515    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12516
12517/* ------------------------------ */
12518    .balign 64
12519.L_ALT_OP_NEG_INT: /* 0x7b */
12520/* File: armv5te/alt_stub.S */
12521/*
12522 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12523 * any interesting requests and then jump to the real instruction
12524 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12525 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12526 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12527 * bail to the real handler if breakFlags==0.
12528 */
12529    ldrb   r3, [rSELF, #offThread_breakFlags]
12530    adrl   lr, dvmAsmInstructionStart + (123 * 64)
12531    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12532    cmp    r3, #0
12533    bxeq   lr                   @ nothing to do - jump to real handler
12534    EXPORT_PC()
12535    mov    r0, rPC              @ arg0
12536    mov    r1, rFP              @ arg1
12537    mov    r2, rSELF            @ arg2
12538    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12539
12540/* ------------------------------ */
12541    .balign 64
12542.L_ALT_OP_NOT_INT: /* 0x7c */
12543/* File: armv5te/alt_stub.S */
12544/*
12545 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12546 * any interesting requests and then jump to the real instruction
12547 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12548 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12549 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12550 * bail to the real handler if breakFlags==0.
12551 */
12552    ldrb   r3, [rSELF, #offThread_breakFlags]
12553    adrl   lr, dvmAsmInstructionStart + (124 * 64)
12554    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12555    cmp    r3, #0
12556    bxeq   lr                   @ nothing to do - jump to real handler
12557    EXPORT_PC()
12558    mov    r0, rPC              @ arg0
12559    mov    r1, rFP              @ arg1
12560    mov    r2, rSELF            @ arg2
12561    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12562
12563/* ------------------------------ */
12564    .balign 64
12565.L_ALT_OP_NEG_LONG: /* 0x7d */
12566/* File: armv5te/alt_stub.S */
12567/*
12568 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12569 * any interesting requests and then jump to the real instruction
12570 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12571 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12572 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12573 * bail to the real handler if breakFlags==0.
12574 */
12575    ldrb   r3, [rSELF, #offThread_breakFlags]
12576    adrl   lr, dvmAsmInstructionStart + (125 * 64)
12577    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12578    cmp    r3, #0
12579    bxeq   lr                   @ nothing to do - jump to real handler
12580    EXPORT_PC()
12581    mov    r0, rPC              @ arg0
12582    mov    r1, rFP              @ arg1
12583    mov    r2, rSELF            @ arg2
12584    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12585
12586/* ------------------------------ */
12587    .balign 64
12588.L_ALT_OP_NOT_LONG: /* 0x7e */
12589/* File: armv5te/alt_stub.S */
12590/*
12591 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12592 * any interesting requests and then jump to the real instruction
12593 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12594 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12595 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12596 * bail to the real handler if breakFlags==0.
12597 */
12598    ldrb   r3, [rSELF, #offThread_breakFlags]
12599    adrl   lr, dvmAsmInstructionStart + (126 * 64)
12600    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12601    cmp    r3, #0
12602    bxeq   lr                   @ nothing to do - jump to real handler
12603    EXPORT_PC()
12604    mov    r0, rPC              @ arg0
12605    mov    r1, rFP              @ arg1
12606    mov    r2, rSELF            @ arg2
12607    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12608
12609/* ------------------------------ */
12610    .balign 64
12611.L_ALT_OP_NEG_FLOAT: /* 0x7f */
12612/* File: armv5te/alt_stub.S */
12613/*
12614 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12615 * any interesting requests and then jump to the real instruction
12616 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12617 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12618 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12619 * bail to the real handler if breakFlags==0.
12620 */
12621    ldrb   r3, [rSELF, #offThread_breakFlags]
12622    adrl   lr, dvmAsmInstructionStart + (127 * 64)
12623    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12624    cmp    r3, #0
12625    bxeq   lr                   @ nothing to do - jump to real handler
12626    EXPORT_PC()
12627    mov    r0, rPC              @ arg0
12628    mov    r1, rFP              @ arg1
12629    mov    r2, rSELF            @ arg2
12630    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12631
12632/* ------------------------------ */
12633    .balign 64
12634.L_ALT_OP_NEG_DOUBLE: /* 0x80 */
12635/* File: armv5te/alt_stub.S */
12636/*
12637 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12638 * any interesting requests and then jump to the real instruction
12639 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12640 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12641 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12642 * bail to the real handler if breakFlags==0.
12643 */
12644    ldrb   r3, [rSELF, #offThread_breakFlags]
12645    adrl   lr, dvmAsmInstructionStart + (128 * 64)
12646    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12647    cmp    r3, #0
12648    bxeq   lr                   @ nothing to do - jump to real handler
12649    EXPORT_PC()
12650    mov    r0, rPC              @ arg0
12651    mov    r1, rFP              @ arg1
12652    mov    r2, rSELF            @ arg2
12653    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12654
12655/* ------------------------------ */
12656    .balign 64
12657.L_ALT_OP_INT_TO_LONG: /* 0x81 */
12658/* File: armv5te/alt_stub.S */
12659/*
12660 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12661 * any interesting requests and then jump to the real instruction
12662 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12663 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12664 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12665 * bail to the real handler if breakFlags==0.
12666 */
12667    ldrb   r3, [rSELF, #offThread_breakFlags]
12668    adrl   lr, dvmAsmInstructionStart + (129 * 64)
12669    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12670    cmp    r3, #0
12671    bxeq   lr                   @ nothing to do - jump to real handler
12672    EXPORT_PC()
12673    mov    r0, rPC              @ arg0
12674    mov    r1, rFP              @ arg1
12675    mov    r2, rSELF            @ arg2
12676    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12677
12678/* ------------------------------ */
12679    .balign 64
12680.L_ALT_OP_INT_TO_FLOAT: /* 0x82 */
12681/* File: armv5te/alt_stub.S */
12682/*
12683 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12684 * any interesting requests and then jump to the real instruction
12685 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12686 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12687 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12688 * bail to the real handler if breakFlags==0.
12689 */
12690    ldrb   r3, [rSELF, #offThread_breakFlags]
12691    adrl   lr, dvmAsmInstructionStart + (130 * 64)
12692    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12693    cmp    r3, #0
12694    bxeq   lr                   @ nothing to do - jump to real handler
12695    EXPORT_PC()
12696    mov    r0, rPC              @ arg0
12697    mov    r1, rFP              @ arg1
12698    mov    r2, rSELF            @ arg2
12699    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12700
12701/* ------------------------------ */
12702    .balign 64
12703.L_ALT_OP_INT_TO_DOUBLE: /* 0x83 */
12704/* File: armv5te/alt_stub.S */
12705/*
12706 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12707 * any interesting requests and then jump to the real instruction
12708 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12709 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12710 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12711 * bail to the real handler if breakFlags==0.
12712 */
12713    ldrb   r3, [rSELF, #offThread_breakFlags]
12714    adrl   lr, dvmAsmInstructionStart + (131 * 64)
12715    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12716    cmp    r3, #0
12717    bxeq   lr                   @ nothing to do - jump to real handler
12718    EXPORT_PC()
12719    mov    r0, rPC              @ arg0
12720    mov    r1, rFP              @ arg1
12721    mov    r2, rSELF            @ arg2
12722    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12723
12724/* ------------------------------ */
12725    .balign 64
12726.L_ALT_OP_LONG_TO_INT: /* 0x84 */
12727/* File: armv5te/alt_stub.S */
12728/*
12729 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12730 * any interesting requests and then jump to the real instruction
12731 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12732 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12733 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12734 * bail to the real handler if breakFlags==0.
12735 */
12736    ldrb   r3, [rSELF, #offThread_breakFlags]
12737    adrl   lr, dvmAsmInstructionStart + (132 * 64)
12738    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12739    cmp    r3, #0
12740    bxeq   lr                   @ nothing to do - jump to real handler
12741    EXPORT_PC()
12742    mov    r0, rPC              @ arg0
12743    mov    r1, rFP              @ arg1
12744    mov    r2, rSELF            @ arg2
12745    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12746
12747/* ------------------------------ */
12748    .balign 64
12749.L_ALT_OP_LONG_TO_FLOAT: /* 0x85 */
12750/* File: armv5te/alt_stub.S */
12751/*
12752 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12753 * any interesting requests and then jump to the real instruction
12754 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12755 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12756 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12757 * bail to the real handler if breakFlags==0.
12758 */
12759    ldrb   r3, [rSELF, #offThread_breakFlags]
12760    adrl   lr, dvmAsmInstructionStart + (133 * 64)
12761    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12762    cmp    r3, #0
12763    bxeq   lr                   @ nothing to do - jump to real handler
12764    EXPORT_PC()
12765    mov    r0, rPC              @ arg0
12766    mov    r1, rFP              @ arg1
12767    mov    r2, rSELF            @ arg2
12768    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12769
12770/* ------------------------------ */
12771    .balign 64
12772.L_ALT_OP_LONG_TO_DOUBLE: /* 0x86 */
12773/* File: armv5te/alt_stub.S */
12774/*
12775 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12776 * any interesting requests and then jump to the real instruction
12777 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12778 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12779 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12780 * bail to the real handler if breakFlags==0.
12781 */
12782    ldrb   r3, [rSELF, #offThread_breakFlags]
12783    adrl   lr, dvmAsmInstructionStart + (134 * 64)
12784    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12785    cmp    r3, #0
12786    bxeq   lr                   @ nothing to do - jump to real handler
12787    EXPORT_PC()
12788    mov    r0, rPC              @ arg0
12789    mov    r1, rFP              @ arg1
12790    mov    r2, rSELF            @ arg2
12791    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12792
12793/* ------------------------------ */
12794    .balign 64
12795.L_ALT_OP_FLOAT_TO_INT: /* 0x87 */
12796/* File: armv5te/alt_stub.S */
12797/*
12798 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12799 * any interesting requests and then jump to the real instruction
12800 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12801 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12802 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12803 * bail to the real handler if breakFlags==0.
12804 */
12805    ldrb   r3, [rSELF, #offThread_breakFlags]
12806    adrl   lr, dvmAsmInstructionStart + (135 * 64)
12807    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12808    cmp    r3, #0
12809    bxeq   lr                   @ nothing to do - jump to real handler
12810    EXPORT_PC()
12811    mov    r0, rPC              @ arg0
12812    mov    r1, rFP              @ arg1
12813    mov    r2, rSELF            @ arg2
12814    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12815
12816/* ------------------------------ */
12817    .balign 64
12818.L_ALT_OP_FLOAT_TO_LONG: /* 0x88 */
12819/* File: armv5te/alt_stub.S */
12820/*
12821 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12822 * any interesting requests and then jump to the real instruction
12823 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12824 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12825 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12826 * bail to the real handler if breakFlags==0.
12827 */
12828    ldrb   r3, [rSELF, #offThread_breakFlags]
12829    adrl   lr, dvmAsmInstructionStart + (136 * 64)
12830    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12831    cmp    r3, #0
12832    bxeq   lr                   @ nothing to do - jump to real handler
12833    EXPORT_PC()
12834    mov    r0, rPC              @ arg0
12835    mov    r1, rFP              @ arg1
12836    mov    r2, rSELF            @ arg2
12837    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12838
12839/* ------------------------------ */
12840    .balign 64
12841.L_ALT_OP_FLOAT_TO_DOUBLE: /* 0x89 */
12842/* File: armv5te/alt_stub.S */
12843/*
12844 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12845 * any interesting requests and then jump to the real instruction
12846 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12847 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12848 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12849 * bail to the real handler if breakFlags==0.
12850 */
12851    ldrb   r3, [rSELF, #offThread_breakFlags]
12852    adrl   lr, dvmAsmInstructionStart + (137 * 64)
12853    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12854    cmp    r3, #0
12855    bxeq   lr                   @ nothing to do - jump to real handler
12856    EXPORT_PC()
12857    mov    r0, rPC              @ arg0
12858    mov    r1, rFP              @ arg1
12859    mov    r2, rSELF            @ arg2
12860    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12861
12862/* ------------------------------ */
12863    .balign 64
12864.L_ALT_OP_DOUBLE_TO_INT: /* 0x8a */
12865/* File: armv5te/alt_stub.S */
12866/*
12867 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12868 * any interesting requests and then jump to the real instruction
12869 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12870 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12871 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12872 * bail to the real handler if breakFlags==0.
12873 */
12874    ldrb   r3, [rSELF, #offThread_breakFlags]
12875    adrl   lr, dvmAsmInstructionStart + (138 * 64)
12876    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12877    cmp    r3, #0
12878    bxeq   lr                   @ nothing to do - jump to real handler
12879    EXPORT_PC()
12880    mov    r0, rPC              @ arg0
12881    mov    r1, rFP              @ arg1
12882    mov    r2, rSELF            @ arg2
12883    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12884
12885/* ------------------------------ */
12886    .balign 64
12887.L_ALT_OP_DOUBLE_TO_LONG: /* 0x8b */
12888/* File: armv5te/alt_stub.S */
12889/*
12890 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12891 * any interesting requests and then jump to the real instruction
12892 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12893 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12894 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12895 * bail to the real handler if breakFlags==0.
12896 */
12897    ldrb   r3, [rSELF, #offThread_breakFlags]
12898    adrl   lr, dvmAsmInstructionStart + (139 * 64)
12899    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12900    cmp    r3, #0
12901    bxeq   lr                   @ nothing to do - jump to real handler
12902    EXPORT_PC()
12903    mov    r0, rPC              @ arg0
12904    mov    r1, rFP              @ arg1
12905    mov    r2, rSELF            @ arg2
12906    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12907
12908/* ------------------------------ */
12909    .balign 64
12910.L_ALT_OP_DOUBLE_TO_FLOAT: /* 0x8c */
12911/* File: armv5te/alt_stub.S */
12912/*
12913 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12914 * any interesting requests and then jump to the real instruction
12915 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12916 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12917 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12918 * bail to the real handler if breakFlags==0.
12919 */
12920    ldrb   r3, [rSELF, #offThread_breakFlags]
12921    adrl   lr, dvmAsmInstructionStart + (140 * 64)
12922    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12923    cmp    r3, #0
12924    bxeq   lr                   @ nothing to do - jump to real handler
12925    EXPORT_PC()
12926    mov    r0, rPC              @ arg0
12927    mov    r1, rFP              @ arg1
12928    mov    r2, rSELF            @ arg2
12929    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12930
12931/* ------------------------------ */
12932    .balign 64
12933.L_ALT_OP_INT_TO_BYTE: /* 0x8d */
12934/* File: armv5te/alt_stub.S */
12935/*
12936 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12937 * any interesting requests and then jump to the real instruction
12938 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12939 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12940 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12941 * bail to the real handler if breakFlags==0.
12942 */
12943    ldrb   r3, [rSELF, #offThread_breakFlags]
12944    adrl   lr, dvmAsmInstructionStart + (141 * 64)
12945    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12946    cmp    r3, #0
12947    bxeq   lr                   @ nothing to do - jump to real handler
12948    EXPORT_PC()
12949    mov    r0, rPC              @ arg0
12950    mov    r1, rFP              @ arg1
12951    mov    r2, rSELF            @ arg2
12952    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12953
12954/* ------------------------------ */
12955    .balign 64
12956.L_ALT_OP_INT_TO_CHAR: /* 0x8e */
12957/* File: armv5te/alt_stub.S */
12958/*
12959 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12960 * any interesting requests and then jump to the real instruction
12961 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12962 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12963 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12964 * bail to the real handler if breakFlags==0.
12965 */
12966    ldrb   r3, [rSELF, #offThread_breakFlags]
12967    adrl   lr, dvmAsmInstructionStart + (142 * 64)
12968    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12969    cmp    r3, #0
12970    bxeq   lr                   @ nothing to do - jump to real handler
12971    EXPORT_PC()
12972    mov    r0, rPC              @ arg0
12973    mov    r1, rFP              @ arg1
12974    mov    r2, rSELF            @ arg2
12975    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12976
12977/* ------------------------------ */
12978    .balign 64
12979.L_ALT_OP_INT_TO_SHORT: /* 0x8f */
12980/* File: armv5te/alt_stub.S */
12981/*
12982 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12983 * any interesting requests and then jump to the real instruction
12984 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12985 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12986 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12987 * bail to the real handler if breakFlags==0.
12988 */
12989    ldrb   r3, [rSELF, #offThread_breakFlags]
12990    adrl   lr, dvmAsmInstructionStart + (143 * 64)
12991    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12992    cmp    r3, #0
12993    bxeq   lr                   @ nothing to do - jump to real handler
12994    EXPORT_PC()
12995    mov    r0, rPC              @ arg0
12996    mov    r1, rFP              @ arg1
12997    mov    r2, rSELF            @ arg2
12998    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12999
13000/* ------------------------------ */
13001    .balign 64
13002.L_ALT_OP_ADD_INT: /* 0x90 */
13003/* File: armv5te/alt_stub.S */
13004/*
13005 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13006 * any interesting requests and then jump to the real instruction
13007 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13008 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13009 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13010 * bail to the real handler if breakFlags==0.
13011 */
13012    ldrb   r3, [rSELF, #offThread_breakFlags]
13013    adrl   lr, dvmAsmInstructionStart + (144 * 64)
13014    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13015    cmp    r3, #0
13016    bxeq   lr                   @ nothing to do - jump to real handler
13017    EXPORT_PC()
13018    mov    r0, rPC              @ arg0
13019    mov    r1, rFP              @ arg1
13020    mov    r2, rSELF            @ arg2
13021    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13022
13023/* ------------------------------ */
13024    .balign 64
13025.L_ALT_OP_SUB_INT: /* 0x91 */
13026/* File: armv5te/alt_stub.S */
13027/*
13028 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13029 * any interesting requests and then jump to the real instruction
13030 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13031 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13032 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13033 * bail to the real handler if breakFlags==0.
13034 */
13035    ldrb   r3, [rSELF, #offThread_breakFlags]
13036    adrl   lr, dvmAsmInstructionStart + (145 * 64)
13037    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13038    cmp    r3, #0
13039    bxeq   lr                   @ nothing to do - jump to real handler
13040    EXPORT_PC()
13041    mov    r0, rPC              @ arg0
13042    mov    r1, rFP              @ arg1
13043    mov    r2, rSELF            @ arg2
13044    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13045
13046/* ------------------------------ */
13047    .balign 64
13048.L_ALT_OP_MUL_INT: /* 0x92 */
13049/* File: armv5te/alt_stub.S */
13050/*
13051 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13052 * any interesting requests and then jump to the real instruction
13053 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13054 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13055 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13056 * bail to the real handler if breakFlags==0.
13057 */
13058    ldrb   r3, [rSELF, #offThread_breakFlags]
13059    adrl   lr, dvmAsmInstructionStart + (146 * 64)
13060    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13061    cmp    r3, #0
13062    bxeq   lr                   @ nothing to do - jump to real handler
13063    EXPORT_PC()
13064    mov    r0, rPC              @ arg0
13065    mov    r1, rFP              @ arg1
13066    mov    r2, rSELF            @ arg2
13067    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13068
13069/* ------------------------------ */
13070    .balign 64
13071.L_ALT_OP_DIV_INT: /* 0x93 */
13072/* File: armv5te/alt_stub.S */
13073/*
13074 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13075 * any interesting requests and then jump to the real instruction
13076 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13077 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13078 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13079 * bail to the real handler if breakFlags==0.
13080 */
13081    ldrb   r3, [rSELF, #offThread_breakFlags]
13082    adrl   lr, dvmAsmInstructionStart + (147 * 64)
13083    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13084    cmp    r3, #0
13085    bxeq   lr                   @ nothing to do - jump to real handler
13086    EXPORT_PC()
13087    mov    r0, rPC              @ arg0
13088    mov    r1, rFP              @ arg1
13089    mov    r2, rSELF            @ arg2
13090    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13091
13092/* ------------------------------ */
13093    .balign 64
13094.L_ALT_OP_REM_INT: /* 0x94 */
13095/* File: armv5te/alt_stub.S */
13096/*
13097 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13098 * any interesting requests and then jump to the real instruction
13099 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13100 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13101 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13102 * bail to the real handler if breakFlags==0.
13103 */
13104    ldrb   r3, [rSELF, #offThread_breakFlags]
13105    adrl   lr, dvmAsmInstructionStart + (148 * 64)
13106    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13107    cmp    r3, #0
13108    bxeq   lr                   @ nothing to do - jump to real handler
13109    EXPORT_PC()
13110    mov    r0, rPC              @ arg0
13111    mov    r1, rFP              @ arg1
13112    mov    r2, rSELF            @ arg2
13113    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13114
13115/* ------------------------------ */
13116    .balign 64
13117.L_ALT_OP_AND_INT: /* 0x95 */
13118/* File: armv5te/alt_stub.S */
13119/*
13120 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13121 * any interesting requests and then jump to the real instruction
13122 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13123 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13124 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13125 * bail to the real handler if breakFlags==0.
13126 */
13127    ldrb   r3, [rSELF, #offThread_breakFlags]
13128    adrl   lr, dvmAsmInstructionStart + (149 * 64)
13129    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13130    cmp    r3, #0
13131    bxeq   lr                   @ nothing to do - jump to real handler
13132    EXPORT_PC()
13133    mov    r0, rPC              @ arg0
13134    mov    r1, rFP              @ arg1
13135    mov    r2, rSELF            @ arg2
13136    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13137
13138/* ------------------------------ */
13139    .balign 64
13140.L_ALT_OP_OR_INT: /* 0x96 */
13141/* File: armv5te/alt_stub.S */
13142/*
13143 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13144 * any interesting requests and then jump to the real instruction
13145 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13146 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13147 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13148 * bail to the real handler if breakFlags==0.
13149 */
13150    ldrb   r3, [rSELF, #offThread_breakFlags]
13151    adrl   lr, dvmAsmInstructionStart + (150 * 64)
13152    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13153    cmp    r3, #0
13154    bxeq   lr                   @ nothing to do - jump to real handler
13155    EXPORT_PC()
13156    mov    r0, rPC              @ arg0
13157    mov    r1, rFP              @ arg1
13158    mov    r2, rSELF            @ arg2
13159    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13160
13161/* ------------------------------ */
13162    .balign 64
13163.L_ALT_OP_XOR_INT: /* 0x97 */
13164/* File: armv5te/alt_stub.S */
13165/*
13166 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13167 * any interesting requests and then jump to the real instruction
13168 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13169 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13170 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13171 * bail to the real handler if breakFlags==0.
13172 */
13173    ldrb   r3, [rSELF, #offThread_breakFlags]
13174    adrl   lr, dvmAsmInstructionStart + (151 * 64)
13175    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13176    cmp    r3, #0
13177    bxeq   lr                   @ nothing to do - jump to real handler
13178    EXPORT_PC()
13179    mov    r0, rPC              @ arg0
13180    mov    r1, rFP              @ arg1
13181    mov    r2, rSELF            @ arg2
13182    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13183
13184/* ------------------------------ */
13185    .balign 64
13186.L_ALT_OP_SHL_INT: /* 0x98 */
13187/* File: armv5te/alt_stub.S */
13188/*
13189 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13190 * any interesting requests and then jump to the real instruction
13191 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13192 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13193 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13194 * bail to the real handler if breakFlags==0.
13195 */
13196    ldrb   r3, [rSELF, #offThread_breakFlags]
13197    adrl   lr, dvmAsmInstructionStart + (152 * 64)
13198    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13199    cmp    r3, #0
13200    bxeq   lr                   @ nothing to do - jump to real handler
13201    EXPORT_PC()
13202    mov    r0, rPC              @ arg0
13203    mov    r1, rFP              @ arg1
13204    mov    r2, rSELF            @ arg2
13205    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13206
13207/* ------------------------------ */
13208    .balign 64
13209.L_ALT_OP_SHR_INT: /* 0x99 */
13210/* File: armv5te/alt_stub.S */
13211/*
13212 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13213 * any interesting requests and then jump to the real instruction
13214 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13215 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13216 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13217 * bail to the real handler if breakFlags==0.
13218 */
13219    ldrb   r3, [rSELF, #offThread_breakFlags]
13220    adrl   lr, dvmAsmInstructionStart + (153 * 64)
13221    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13222    cmp    r3, #0
13223    bxeq   lr                   @ nothing to do - jump to real handler
13224    EXPORT_PC()
13225    mov    r0, rPC              @ arg0
13226    mov    r1, rFP              @ arg1
13227    mov    r2, rSELF            @ arg2
13228    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13229
13230/* ------------------------------ */
13231    .balign 64
13232.L_ALT_OP_USHR_INT: /* 0x9a */
13233/* File: armv5te/alt_stub.S */
13234/*
13235 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13236 * any interesting requests and then jump to the real instruction
13237 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13238 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13239 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13240 * bail to the real handler if breakFlags==0.
13241 */
13242    ldrb   r3, [rSELF, #offThread_breakFlags]
13243    adrl   lr, dvmAsmInstructionStart + (154 * 64)
13244    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13245    cmp    r3, #0
13246    bxeq   lr                   @ nothing to do - jump to real handler
13247    EXPORT_PC()
13248    mov    r0, rPC              @ arg0
13249    mov    r1, rFP              @ arg1
13250    mov    r2, rSELF            @ arg2
13251    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13252
13253/* ------------------------------ */
13254    .balign 64
13255.L_ALT_OP_ADD_LONG: /* 0x9b */
13256/* File: armv5te/alt_stub.S */
13257/*
13258 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13259 * any interesting requests and then jump to the real instruction
13260 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13261 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13262 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13263 * bail to the real handler if breakFlags==0.
13264 */
13265    ldrb   r3, [rSELF, #offThread_breakFlags]
13266    adrl   lr, dvmAsmInstructionStart + (155 * 64)
13267    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13268    cmp    r3, #0
13269    bxeq   lr                   @ nothing to do - jump to real handler
13270    EXPORT_PC()
13271    mov    r0, rPC              @ arg0
13272    mov    r1, rFP              @ arg1
13273    mov    r2, rSELF            @ arg2
13274    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13275
13276/* ------------------------------ */
13277    .balign 64
13278.L_ALT_OP_SUB_LONG: /* 0x9c */
13279/* File: armv5te/alt_stub.S */
13280/*
13281 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13282 * any interesting requests and then jump to the real instruction
13283 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13284 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13285 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13286 * bail to the real handler if breakFlags==0.
13287 */
13288    ldrb   r3, [rSELF, #offThread_breakFlags]
13289    adrl   lr, dvmAsmInstructionStart + (156 * 64)
13290    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13291    cmp    r3, #0
13292    bxeq   lr                   @ nothing to do - jump to real handler
13293    EXPORT_PC()
13294    mov    r0, rPC              @ arg0
13295    mov    r1, rFP              @ arg1
13296    mov    r2, rSELF            @ arg2
13297    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13298
13299/* ------------------------------ */
13300    .balign 64
13301.L_ALT_OP_MUL_LONG: /* 0x9d */
13302/* File: armv5te/alt_stub.S */
13303/*
13304 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13305 * any interesting requests and then jump to the real instruction
13306 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13307 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13308 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13309 * bail to the real handler if breakFlags==0.
13310 */
13311    ldrb   r3, [rSELF, #offThread_breakFlags]
13312    adrl   lr, dvmAsmInstructionStart + (157 * 64)
13313    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13314    cmp    r3, #0
13315    bxeq   lr                   @ nothing to do - jump to real handler
13316    EXPORT_PC()
13317    mov    r0, rPC              @ arg0
13318    mov    r1, rFP              @ arg1
13319    mov    r2, rSELF            @ arg2
13320    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13321
13322/* ------------------------------ */
13323    .balign 64
13324.L_ALT_OP_DIV_LONG: /* 0x9e */
13325/* File: armv5te/alt_stub.S */
13326/*
13327 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13328 * any interesting requests and then jump to the real instruction
13329 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13330 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13331 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13332 * bail to the real handler if breakFlags==0.
13333 */
13334    ldrb   r3, [rSELF, #offThread_breakFlags]
13335    adrl   lr, dvmAsmInstructionStart + (158 * 64)
13336    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13337    cmp    r3, #0
13338    bxeq   lr                   @ nothing to do - jump to real handler
13339    EXPORT_PC()
13340    mov    r0, rPC              @ arg0
13341    mov    r1, rFP              @ arg1
13342    mov    r2, rSELF            @ arg2
13343    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13344
13345/* ------------------------------ */
13346    .balign 64
13347.L_ALT_OP_REM_LONG: /* 0x9f */
13348/* File: armv5te/alt_stub.S */
13349/*
13350 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13351 * any interesting requests and then jump to the real instruction
13352 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13353 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13354 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13355 * bail to the real handler if breakFlags==0.
13356 */
13357    ldrb   r3, [rSELF, #offThread_breakFlags]
13358    adrl   lr, dvmAsmInstructionStart + (159 * 64)
13359    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13360    cmp    r3, #0
13361    bxeq   lr                   @ nothing to do - jump to real handler
13362    EXPORT_PC()
13363    mov    r0, rPC              @ arg0
13364    mov    r1, rFP              @ arg1
13365    mov    r2, rSELF            @ arg2
13366    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13367
13368/* ------------------------------ */
13369    .balign 64
13370.L_ALT_OP_AND_LONG: /* 0xa0 */
13371/* File: armv5te/alt_stub.S */
13372/*
13373 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13374 * any interesting requests and then jump to the real instruction
13375 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13376 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13377 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13378 * bail to the real handler if breakFlags==0.
13379 */
13380    ldrb   r3, [rSELF, #offThread_breakFlags]
13381    adrl   lr, dvmAsmInstructionStart + (160 * 64)
13382    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13383    cmp    r3, #0
13384    bxeq   lr                   @ nothing to do - jump to real handler
13385    EXPORT_PC()
13386    mov    r0, rPC              @ arg0
13387    mov    r1, rFP              @ arg1
13388    mov    r2, rSELF            @ arg2
13389    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13390
13391/* ------------------------------ */
13392    .balign 64
13393.L_ALT_OP_OR_LONG: /* 0xa1 */
13394/* File: armv5te/alt_stub.S */
13395/*
13396 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13397 * any interesting requests and then jump to the real instruction
13398 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13399 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13400 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13401 * bail to the real handler if breakFlags==0.
13402 */
13403    ldrb   r3, [rSELF, #offThread_breakFlags]
13404    adrl   lr, dvmAsmInstructionStart + (161 * 64)
13405    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13406    cmp    r3, #0
13407    bxeq   lr                   @ nothing to do - jump to real handler
13408    EXPORT_PC()
13409    mov    r0, rPC              @ arg0
13410    mov    r1, rFP              @ arg1
13411    mov    r2, rSELF            @ arg2
13412    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13413
13414/* ------------------------------ */
13415    .balign 64
13416.L_ALT_OP_XOR_LONG: /* 0xa2 */
13417/* File: armv5te/alt_stub.S */
13418/*
13419 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13420 * any interesting requests and then jump to the real instruction
13421 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13422 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13423 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13424 * bail to the real handler if breakFlags==0.
13425 */
13426    ldrb   r3, [rSELF, #offThread_breakFlags]
13427    adrl   lr, dvmAsmInstructionStart + (162 * 64)
13428    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13429    cmp    r3, #0
13430    bxeq   lr                   @ nothing to do - jump to real handler
13431    EXPORT_PC()
13432    mov    r0, rPC              @ arg0
13433    mov    r1, rFP              @ arg1
13434    mov    r2, rSELF            @ arg2
13435    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13436
13437/* ------------------------------ */
13438    .balign 64
13439.L_ALT_OP_SHL_LONG: /* 0xa3 */
13440/* File: armv5te/alt_stub.S */
13441/*
13442 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13443 * any interesting requests and then jump to the real instruction
13444 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13445 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13446 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13447 * bail to the real handler if breakFlags==0.
13448 */
13449    ldrb   r3, [rSELF, #offThread_breakFlags]
13450    adrl   lr, dvmAsmInstructionStart + (163 * 64)
13451    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13452    cmp    r3, #0
13453    bxeq   lr                   @ nothing to do - jump to real handler
13454    EXPORT_PC()
13455    mov    r0, rPC              @ arg0
13456    mov    r1, rFP              @ arg1
13457    mov    r2, rSELF            @ arg2
13458    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13459
13460/* ------------------------------ */
13461    .balign 64
13462.L_ALT_OP_SHR_LONG: /* 0xa4 */
13463/* File: armv5te/alt_stub.S */
13464/*
13465 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13466 * any interesting requests and then jump to the real instruction
13467 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13468 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13469 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13470 * bail to the real handler if breakFlags==0.
13471 */
13472    ldrb   r3, [rSELF, #offThread_breakFlags]
13473    adrl   lr, dvmAsmInstructionStart + (164 * 64)
13474    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13475    cmp    r3, #0
13476    bxeq   lr                   @ nothing to do - jump to real handler
13477    EXPORT_PC()
13478    mov    r0, rPC              @ arg0
13479    mov    r1, rFP              @ arg1
13480    mov    r2, rSELF            @ arg2
13481    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13482
13483/* ------------------------------ */
13484    .balign 64
13485.L_ALT_OP_USHR_LONG: /* 0xa5 */
13486/* File: armv5te/alt_stub.S */
13487/*
13488 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13489 * any interesting requests and then jump to the real instruction
13490 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13491 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13492 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13493 * bail to the real handler if breakFlags==0.
13494 */
13495    ldrb   r3, [rSELF, #offThread_breakFlags]
13496    adrl   lr, dvmAsmInstructionStart + (165 * 64)
13497    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13498    cmp    r3, #0
13499    bxeq   lr                   @ nothing to do - jump to real handler
13500    EXPORT_PC()
13501    mov    r0, rPC              @ arg0
13502    mov    r1, rFP              @ arg1
13503    mov    r2, rSELF            @ arg2
13504    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13505
13506/* ------------------------------ */
13507    .balign 64
13508.L_ALT_OP_ADD_FLOAT: /* 0xa6 */
13509/* File: armv5te/alt_stub.S */
13510/*
13511 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13512 * any interesting requests and then jump to the real instruction
13513 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13514 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13515 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13516 * bail to the real handler if breakFlags==0.
13517 */
13518    ldrb   r3, [rSELF, #offThread_breakFlags]
13519    adrl   lr, dvmAsmInstructionStart + (166 * 64)
13520    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13521    cmp    r3, #0
13522    bxeq   lr                   @ nothing to do - jump to real handler
13523    EXPORT_PC()
13524    mov    r0, rPC              @ arg0
13525    mov    r1, rFP              @ arg1
13526    mov    r2, rSELF            @ arg2
13527    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13528
13529/* ------------------------------ */
13530    .balign 64
13531.L_ALT_OP_SUB_FLOAT: /* 0xa7 */
13532/* File: armv5te/alt_stub.S */
13533/*
13534 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13535 * any interesting requests and then jump to the real instruction
13536 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13537 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13538 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13539 * bail to the real handler if breakFlags==0.
13540 */
13541    ldrb   r3, [rSELF, #offThread_breakFlags]
13542    adrl   lr, dvmAsmInstructionStart + (167 * 64)
13543    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13544    cmp    r3, #0
13545    bxeq   lr                   @ nothing to do - jump to real handler
13546    EXPORT_PC()
13547    mov    r0, rPC              @ arg0
13548    mov    r1, rFP              @ arg1
13549    mov    r2, rSELF            @ arg2
13550    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13551
13552/* ------------------------------ */
13553    .balign 64
13554.L_ALT_OP_MUL_FLOAT: /* 0xa8 */
13555/* File: armv5te/alt_stub.S */
13556/*
13557 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13558 * any interesting requests and then jump to the real instruction
13559 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13560 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13561 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13562 * bail to the real handler if breakFlags==0.
13563 */
13564    ldrb   r3, [rSELF, #offThread_breakFlags]
13565    adrl   lr, dvmAsmInstructionStart + (168 * 64)
13566    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13567    cmp    r3, #0
13568    bxeq   lr                   @ nothing to do - jump to real handler
13569    EXPORT_PC()
13570    mov    r0, rPC              @ arg0
13571    mov    r1, rFP              @ arg1
13572    mov    r2, rSELF            @ arg2
13573    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13574
13575/* ------------------------------ */
13576    .balign 64
13577.L_ALT_OP_DIV_FLOAT: /* 0xa9 */
13578/* File: armv5te/alt_stub.S */
13579/*
13580 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13581 * any interesting requests and then jump to the real instruction
13582 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13583 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13584 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13585 * bail to the real handler if breakFlags==0.
13586 */
13587    ldrb   r3, [rSELF, #offThread_breakFlags]
13588    adrl   lr, dvmAsmInstructionStart + (169 * 64)
13589    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13590    cmp    r3, #0
13591    bxeq   lr                   @ nothing to do - jump to real handler
13592    EXPORT_PC()
13593    mov    r0, rPC              @ arg0
13594    mov    r1, rFP              @ arg1
13595    mov    r2, rSELF            @ arg2
13596    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13597
13598/* ------------------------------ */
13599    .balign 64
13600.L_ALT_OP_REM_FLOAT: /* 0xaa */
13601/* File: armv5te/alt_stub.S */
13602/*
13603 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13604 * any interesting requests and then jump to the real instruction
13605 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13606 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13607 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13608 * bail to the real handler if breakFlags==0.
13609 */
13610    ldrb   r3, [rSELF, #offThread_breakFlags]
13611    adrl   lr, dvmAsmInstructionStart + (170 * 64)
13612    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13613    cmp    r3, #0
13614    bxeq   lr                   @ nothing to do - jump to real handler
13615    EXPORT_PC()
13616    mov    r0, rPC              @ arg0
13617    mov    r1, rFP              @ arg1
13618    mov    r2, rSELF            @ arg2
13619    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13620
13621/* ------------------------------ */
13622    .balign 64
13623.L_ALT_OP_ADD_DOUBLE: /* 0xab */
13624/* File: armv5te/alt_stub.S */
13625/*
13626 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13627 * any interesting requests and then jump to the real instruction
13628 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13629 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13630 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13631 * bail to the real handler if breakFlags==0.
13632 */
13633    ldrb   r3, [rSELF, #offThread_breakFlags]
13634    adrl   lr, dvmAsmInstructionStart + (171 * 64)
13635    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13636    cmp    r3, #0
13637    bxeq   lr                   @ nothing to do - jump to real handler
13638    EXPORT_PC()
13639    mov    r0, rPC              @ arg0
13640    mov    r1, rFP              @ arg1
13641    mov    r2, rSELF            @ arg2
13642    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13643
13644/* ------------------------------ */
13645    .balign 64
13646.L_ALT_OP_SUB_DOUBLE: /* 0xac */
13647/* File: armv5te/alt_stub.S */
13648/*
13649 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13650 * any interesting requests and then jump to the real instruction
13651 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13652 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13653 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13654 * bail to the real handler if breakFlags==0.
13655 */
13656    ldrb   r3, [rSELF, #offThread_breakFlags]
13657    adrl   lr, dvmAsmInstructionStart + (172 * 64)
13658    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13659    cmp    r3, #0
13660    bxeq   lr                   @ nothing to do - jump to real handler
13661    EXPORT_PC()
13662    mov    r0, rPC              @ arg0
13663    mov    r1, rFP              @ arg1
13664    mov    r2, rSELF            @ arg2
13665    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13666
13667/* ------------------------------ */
13668    .balign 64
13669.L_ALT_OP_MUL_DOUBLE: /* 0xad */
13670/* File: armv5te/alt_stub.S */
13671/*
13672 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13673 * any interesting requests and then jump to the real instruction
13674 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13675 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13676 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13677 * bail to the real handler if breakFlags==0.
13678 */
13679    ldrb   r3, [rSELF, #offThread_breakFlags]
13680    adrl   lr, dvmAsmInstructionStart + (173 * 64)
13681    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13682    cmp    r3, #0
13683    bxeq   lr                   @ nothing to do - jump to real handler
13684    EXPORT_PC()
13685    mov    r0, rPC              @ arg0
13686    mov    r1, rFP              @ arg1
13687    mov    r2, rSELF            @ arg2
13688    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13689
13690/* ------------------------------ */
13691    .balign 64
13692.L_ALT_OP_DIV_DOUBLE: /* 0xae */
13693/* File: armv5te/alt_stub.S */
13694/*
13695 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13696 * any interesting requests and then jump to the real instruction
13697 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13698 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13699 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13700 * bail to the real handler if breakFlags==0.
13701 */
13702    ldrb   r3, [rSELF, #offThread_breakFlags]
13703    adrl   lr, dvmAsmInstructionStart + (174 * 64)
13704    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13705    cmp    r3, #0
13706    bxeq   lr                   @ nothing to do - jump to real handler
13707    EXPORT_PC()
13708    mov    r0, rPC              @ arg0
13709    mov    r1, rFP              @ arg1
13710    mov    r2, rSELF            @ arg2
13711    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13712
13713/* ------------------------------ */
13714    .balign 64
13715.L_ALT_OP_REM_DOUBLE: /* 0xaf */
13716/* File: armv5te/alt_stub.S */
13717/*
13718 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13719 * any interesting requests and then jump to the real instruction
13720 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13721 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13722 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13723 * bail to the real handler if breakFlags==0.
13724 */
13725    ldrb   r3, [rSELF, #offThread_breakFlags]
13726    adrl   lr, dvmAsmInstructionStart + (175 * 64)
13727    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13728    cmp    r3, #0
13729    bxeq   lr                   @ nothing to do - jump to real handler
13730    EXPORT_PC()
13731    mov    r0, rPC              @ arg0
13732    mov    r1, rFP              @ arg1
13733    mov    r2, rSELF            @ arg2
13734    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13735
13736/* ------------------------------ */
13737    .balign 64
13738.L_ALT_OP_ADD_INT_2ADDR: /* 0xb0 */
13739/* File: armv5te/alt_stub.S */
13740/*
13741 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13742 * any interesting requests and then jump to the real instruction
13743 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13744 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13745 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13746 * bail to the real handler if breakFlags==0.
13747 */
13748    ldrb   r3, [rSELF, #offThread_breakFlags]
13749    adrl   lr, dvmAsmInstructionStart + (176 * 64)
13750    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13751    cmp    r3, #0
13752    bxeq   lr                   @ nothing to do - jump to real handler
13753    EXPORT_PC()
13754    mov    r0, rPC              @ arg0
13755    mov    r1, rFP              @ arg1
13756    mov    r2, rSELF            @ arg2
13757    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13758
13759/* ------------------------------ */
13760    .balign 64
13761.L_ALT_OP_SUB_INT_2ADDR: /* 0xb1 */
13762/* File: armv5te/alt_stub.S */
13763/*
13764 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13765 * any interesting requests and then jump to the real instruction
13766 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13767 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13768 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13769 * bail to the real handler if breakFlags==0.
13770 */
13771    ldrb   r3, [rSELF, #offThread_breakFlags]
13772    adrl   lr, dvmAsmInstructionStart + (177 * 64)
13773    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13774    cmp    r3, #0
13775    bxeq   lr                   @ nothing to do - jump to real handler
13776    EXPORT_PC()
13777    mov    r0, rPC              @ arg0
13778    mov    r1, rFP              @ arg1
13779    mov    r2, rSELF            @ arg2
13780    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13781
13782/* ------------------------------ */
13783    .balign 64
13784.L_ALT_OP_MUL_INT_2ADDR: /* 0xb2 */
13785/* File: armv5te/alt_stub.S */
13786/*
13787 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13788 * any interesting requests and then jump to the real instruction
13789 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13790 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13791 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13792 * bail to the real handler if breakFlags==0.
13793 */
13794    ldrb   r3, [rSELF, #offThread_breakFlags]
13795    adrl   lr, dvmAsmInstructionStart + (178 * 64)
13796    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13797    cmp    r3, #0
13798    bxeq   lr                   @ nothing to do - jump to real handler
13799    EXPORT_PC()
13800    mov    r0, rPC              @ arg0
13801    mov    r1, rFP              @ arg1
13802    mov    r2, rSELF            @ arg2
13803    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13804
13805/* ------------------------------ */
13806    .balign 64
13807.L_ALT_OP_DIV_INT_2ADDR: /* 0xb3 */
13808/* File: armv5te/alt_stub.S */
13809/*
13810 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13811 * any interesting requests and then jump to the real instruction
13812 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13813 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13814 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13815 * bail to the real handler if breakFlags==0.
13816 */
13817    ldrb   r3, [rSELF, #offThread_breakFlags]
13818    adrl   lr, dvmAsmInstructionStart + (179 * 64)
13819    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13820    cmp    r3, #0
13821    bxeq   lr                   @ nothing to do - jump to real handler
13822    EXPORT_PC()
13823    mov    r0, rPC              @ arg0
13824    mov    r1, rFP              @ arg1
13825    mov    r2, rSELF            @ arg2
13826    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13827
13828/* ------------------------------ */
13829    .balign 64
13830.L_ALT_OP_REM_INT_2ADDR: /* 0xb4 */
13831/* File: armv5te/alt_stub.S */
13832/*
13833 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13834 * any interesting requests and then jump to the real instruction
13835 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13836 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13837 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13838 * bail to the real handler if breakFlags==0.
13839 */
13840    ldrb   r3, [rSELF, #offThread_breakFlags]
13841    adrl   lr, dvmAsmInstructionStart + (180 * 64)
13842    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13843    cmp    r3, #0
13844    bxeq   lr                   @ nothing to do - jump to real handler
13845    EXPORT_PC()
13846    mov    r0, rPC              @ arg0
13847    mov    r1, rFP              @ arg1
13848    mov    r2, rSELF            @ arg2
13849    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13850
13851/* ------------------------------ */
13852    .balign 64
13853.L_ALT_OP_AND_INT_2ADDR: /* 0xb5 */
13854/* File: armv5te/alt_stub.S */
13855/*
13856 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13857 * any interesting requests and then jump to the real instruction
13858 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13859 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13860 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13861 * bail to the real handler if breakFlags==0.
13862 */
13863    ldrb   r3, [rSELF, #offThread_breakFlags]
13864    adrl   lr, dvmAsmInstructionStart + (181 * 64)
13865    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13866    cmp    r3, #0
13867    bxeq   lr                   @ nothing to do - jump to real handler
13868    EXPORT_PC()
13869    mov    r0, rPC              @ arg0
13870    mov    r1, rFP              @ arg1
13871    mov    r2, rSELF            @ arg2
13872    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13873
13874/* ------------------------------ */
13875    .balign 64
13876.L_ALT_OP_OR_INT_2ADDR: /* 0xb6 */
13877/* File: armv5te/alt_stub.S */
13878/*
13879 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13880 * any interesting requests and then jump to the real instruction
13881 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13882 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13883 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13884 * bail to the real handler if breakFlags==0.
13885 */
13886    ldrb   r3, [rSELF, #offThread_breakFlags]
13887    adrl   lr, dvmAsmInstructionStart + (182 * 64)
13888    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13889    cmp    r3, #0
13890    bxeq   lr                   @ nothing to do - jump to real handler
13891    EXPORT_PC()
13892    mov    r0, rPC              @ arg0
13893    mov    r1, rFP              @ arg1
13894    mov    r2, rSELF            @ arg2
13895    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13896
13897/* ------------------------------ */
13898    .balign 64
13899.L_ALT_OP_XOR_INT_2ADDR: /* 0xb7 */
13900/* File: armv5te/alt_stub.S */
13901/*
13902 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13903 * any interesting requests and then jump to the real instruction
13904 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13905 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13906 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13907 * bail to the real handler if breakFlags==0.
13908 */
13909    ldrb   r3, [rSELF, #offThread_breakFlags]
13910    adrl   lr, dvmAsmInstructionStart + (183 * 64)
13911    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13912    cmp    r3, #0
13913    bxeq   lr                   @ nothing to do - jump to real handler
13914    EXPORT_PC()
13915    mov    r0, rPC              @ arg0
13916    mov    r1, rFP              @ arg1
13917    mov    r2, rSELF            @ arg2
13918    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13919
13920/* ------------------------------ */
13921    .balign 64
13922.L_ALT_OP_SHL_INT_2ADDR: /* 0xb8 */
13923/* File: armv5te/alt_stub.S */
13924/*
13925 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13926 * any interesting requests and then jump to the real instruction
13927 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13928 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13929 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13930 * bail to the real handler if breakFlags==0.
13931 */
13932    ldrb   r3, [rSELF, #offThread_breakFlags]
13933    adrl   lr, dvmAsmInstructionStart + (184 * 64)
13934    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13935    cmp    r3, #0
13936    bxeq   lr                   @ nothing to do - jump to real handler
13937    EXPORT_PC()
13938    mov    r0, rPC              @ arg0
13939    mov    r1, rFP              @ arg1
13940    mov    r2, rSELF            @ arg2
13941    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13942
13943/* ------------------------------ */
13944    .balign 64
13945.L_ALT_OP_SHR_INT_2ADDR: /* 0xb9 */
13946/* File: armv5te/alt_stub.S */
13947/*
13948 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13949 * any interesting requests and then jump to the real instruction
13950 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13951 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13952 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13953 * bail to the real handler if breakFlags==0.
13954 */
13955    ldrb   r3, [rSELF, #offThread_breakFlags]
13956    adrl   lr, dvmAsmInstructionStart + (185 * 64)
13957    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13958    cmp    r3, #0
13959    bxeq   lr                   @ nothing to do - jump to real handler
13960    EXPORT_PC()
13961    mov    r0, rPC              @ arg0
13962    mov    r1, rFP              @ arg1
13963    mov    r2, rSELF            @ arg2
13964    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13965
13966/* ------------------------------ */
13967    .balign 64
13968.L_ALT_OP_USHR_INT_2ADDR: /* 0xba */
13969/* File: armv5te/alt_stub.S */
13970/*
13971 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13972 * any interesting requests and then jump to the real instruction
13973 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13974 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13975 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13976 * bail to the real handler if breakFlags==0.
13977 */
13978    ldrb   r3, [rSELF, #offThread_breakFlags]
13979    adrl   lr, dvmAsmInstructionStart + (186 * 64)
13980    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13981    cmp    r3, #0
13982    bxeq   lr                   @ nothing to do - jump to real handler
13983    EXPORT_PC()
13984    mov    r0, rPC              @ arg0
13985    mov    r1, rFP              @ arg1
13986    mov    r2, rSELF            @ arg2
13987    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13988
13989/* ------------------------------ */
13990    .balign 64
13991.L_ALT_OP_ADD_LONG_2ADDR: /* 0xbb */
13992/* File: armv5te/alt_stub.S */
13993/*
13994 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13995 * any interesting requests and then jump to the real instruction
13996 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13997 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13998 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13999 * bail to the real handler if breakFlags==0.
14000 */
14001    ldrb   r3, [rSELF, #offThread_breakFlags]
14002    adrl   lr, dvmAsmInstructionStart + (187 * 64)
14003    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14004    cmp    r3, #0
14005    bxeq   lr                   @ nothing to do - jump to real handler
14006    EXPORT_PC()
14007    mov    r0, rPC              @ arg0
14008    mov    r1, rFP              @ arg1
14009    mov    r2, rSELF            @ arg2
14010    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14011
14012/* ------------------------------ */
14013    .balign 64
14014.L_ALT_OP_SUB_LONG_2ADDR: /* 0xbc */
14015/* File: armv5te/alt_stub.S */
14016/*
14017 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14018 * any interesting requests and then jump to the real instruction
14019 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14020 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14021 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14022 * bail to the real handler if breakFlags==0.
14023 */
14024    ldrb   r3, [rSELF, #offThread_breakFlags]
14025    adrl   lr, dvmAsmInstructionStart + (188 * 64)
14026    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14027    cmp    r3, #0
14028    bxeq   lr                   @ nothing to do - jump to real handler
14029    EXPORT_PC()
14030    mov    r0, rPC              @ arg0
14031    mov    r1, rFP              @ arg1
14032    mov    r2, rSELF            @ arg2
14033    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14034
14035/* ------------------------------ */
14036    .balign 64
14037.L_ALT_OP_MUL_LONG_2ADDR: /* 0xbd */
14038/* File: armv5te/alt_stub.S */
14039/*
14040 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14041 * any interesting requests and then jump to the real instruction
14042 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14043 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14044 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14045 * bail to the real handler if breakFlags==0.
14046 */
14047    ldrb   r3, [rSELF, #offThread_breakFlags]
14048    adrl   lr, dvmAsmInstructionStart + (189 * 64)
14049    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14050    cmp    r3, #0
14051    bxeq   lr                   @ nothing to do - jump to real handler
14052    EXPORT_PC()
14053    mov    r0, rPC              @ arg0
14054    mov    r1, rFP              @ arg1
14055    mov    r2, rSELF            @ arg2
14056    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14057
14058/* ------------------------------ */
14059    .balign 64
14060.L_ALT_OP_DIV_LONG_2ADDR: /* 0xbe */
14061/* File: armv5te/alt_stub.S */
14062/*
14063 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14064 * any interesting requests and then jump to the real instruction
14065 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14066 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14067 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14068 * bail to the real handler if breakFlags==0.
14069 */
14070    ldrb   r3, [rSELF, #offThread_breakFlags]
14071    adrl   lr, dvmAsmInstructionStart + (190 * 64)
14072    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14073    cmp    r3, #0
14074    bxeq   lr                   @ nothing to do - jump to real handler
14075    EXPORT_PC()
14076    mov    r0, rPC              @ arg0
14077    mov    r1, rFP              @ arg1
14078    mov    r2, rSELF            @ arg2
14079    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14080
14081/* ------------------------------ */
14082    .balign 64
14083.L_ALT_OP_REM_LONG_2ADDR: /* 0xbf */
14084/* File: armv5te/alt_stub.S */
14085/*
14086 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14087 * any interesting requests and then jump to the real instruction
14088 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14089 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14090 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14091 * bail to the real handler if breakFlags==0.
14092 */
14093    ldrb   r3, [rSELF, #offThread_breakFlags]
14094    adrl   lr, dvmAsmInstructionStart + (191 * 64)
14095    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14096    cmp    r3, #0
14097    bxeq   lr                   @ nothing to do - jump to real handler
14098    EXPORT_PC()
14099    mov    r0, rPC              @ arg0
14100    mov    r1, rFP              @ arg1
14101    mov    r2, rSELF            @ arg2
14102    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14103
14104/* ------------------------------ */
14105    .balign 64
14106.L_ALT_OP_AND_LONG_2ADDR: /* 0xc0 */
14107/* File: armv5te/alt_stub.S */
14108/*
14109 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14110 * any interesting requests and then jump to the real instruction
14111 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14112 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14113 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14114 * bail to the real handler if breakFlags==0.
14115 */
14116    ldrb   r3, [rSELF, #offThread_breakFlags]
14117    adrl   lr, dvmAsmInstructionStart + (192 * 64)
14118    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14119    cmp    r3, #0
14120    bxeq   lr                   @ nothing to do - jump to real handler
14121    EXPORT_PC()
14122    mov    r0, rPC              @ arg0
14123    mov    r1, rFP              @ arg1
14124    mov    r2, rSELF            @ arg2
14125    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14126
14127/* ------------------------------ */
14128    .balign 64
14129.L_ALT_OP_OR_LONG_2ADDR: /* 0xc1 */
14130/* File: armv5te/alt_stub.S */
14131/*
14132 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14133 * any interesting requests and then jump to the real instruction
14134 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14135 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14136 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14137 * bail to the real handler if breakFlags==0.
14138 */
14139    ldrb   r3, [rSELF, #offThread_breakFlags]
14140    adrl   lr, dvmAsmInstructionStart + (193 * 64)
14141    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14142    cmp    r3, #0
14143    bxeq   lr                   @ nothing to do - jump to real handler
14144    EXPORT_PC()
14145    mov    r0, rPC              @ arg0
14146    mov    r1, rFP              @ arg1
14147    mov    r2, rSELF            @ arg2
14148    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14149
14150/* ------------------------------ */
14151    .balign 64
14152.L_ALT_OP_XOR_LONG_2ADDR: /* 0xc2 */
14153/* File: armv5te/alt_stub.S */
14154/*
14155 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14156 * any interesting requests and then jump to the real instruction
14157 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14158 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14159 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14160 * bail to the real handler if breakFlags==0.
14161 */
14162    ldrb   r3, [rSELF, #offThread_breakFlags]
14163    adrl   lr, dvmAsmInstructionStart + (194 * 64)
14164    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14165    cmp    r3, #0
14166    bxeq   lr                   @ nothing to do - jump to real handler
14167    EXPORT_PC()
14168    mov    r0, rPC              @ arg0
14169    mov    r1, rFP              @ arg1
14170    mov    r2, rSELF            @ arg2
14171    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14172
14173/* ------------------------------ */
14174    .balign 64
14175.L_ALT_OP_SHL_LONG_2ADDR: /* 0xc3 */
14176/* File: armv5te/alt_stub.S */
14177/*
14178 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14179 * any interesting requests and then jump to the real instruction
14180 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14181 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14182 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14183 * bail to the real handler if breakFlags==0.
14184 */
14185    ldrb   r3, [rSELF, #offThread_breakFlags]
14186    adrl   lr, dvmAsmInstructionStart + (195 * 64)
14187    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14188    cmp    r3, #0
14189    bxeq   lr                   @ nothing to do - jump to real handler
14190    EXPORT_PC()
14191    mov    r0, rPC              @ arg0
14192    mov    r1, rFP              @ arg1
14193    mov    r2, rSELF            @ arg2
14194    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14195
14196/* ------------------------------ */
14197    .balign 64
14198.L_ALT_OP_SHR_LONG_2ADDR: /* 0xc4 */
14199/* File: armv5te/alt_stub.S */
14200/*
14201 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14202 * any interesting requests and then jump to the real instruction
14203 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14204 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14205 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14206 * bail to the real handler if breakFlags==0.
14207 */
14208    ldrb   r3, [rSELF, #offThread_breakFlags]
14209    adrl   lr, dvmAsmInstructionStart + (196 * 64)
14210    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14211    cmp    r3, #0
14212    bxeq   lr                   @ nothing to do - jump to real handler
14213    EXPORT_PC()
14214    mov    r0, rPC              @ arg0
14215    mov    r1, rFP              @ arg1
14216    mov    r2, rSELF            @ arg2
14217    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14218
14219/* ------------------------------ */
14220    .balign 64
14221.L_ALT_OP_USHR_LONG_2ADDR: /* 0xc5 */
14222/* File: armv5te/alt_stub.S */
14223/*
14224 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14225 * any interesting requests and then jump to the real instruction
14226 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14227 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14228 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14229 * bail to the real handler if breakFlags==0.
14230 */
14231    ldrb   r3, [rSELF, #offThread_breakFlags]
14232    adrl   lr, dvmAsmInstructionStart + (197 * 64)
14233    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14234    cmp    r3, #0
14235    bxeq   lr                   @ nothing to do - jump to real handler
14236    EXPORT_PC()
14237    mov    r0, rPC              @ arg0
14238    mov    r1, rFP              @ arg1
14239    mov    r2, rSELF            @ arg2
14240    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14241
14242/* ------------------------------ */
14243    .balign 64
14244.L_ALT_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
14245/* File: armv5te/alt_stub.S */
14246/*
14247 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14248 * any interesting requests and then jump to the real instruction
14249 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14250 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14251 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14252 * bail to the real handler if breakFlags==0.
14253 */
14254    ldrb   r3, [rSELF, #offThread_breakFlags]
14255    adrl   lr, dvmAsmInstructionStart + (198 * 64)
14256    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14257    cmp    r3, #0
14258    bxeq   lr                   @ nothing to do - jump to real handler
14259    EXPORT_PC()
14260    mov    r0, rPC              @ arg0
14261    mov    r1, rFP              @ arg1
14262    mov    r2, rSELF            @ arg2
14263    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14264
14265/* ------------------------------ */
14266    .balign 64
14267.L_ALT_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
14268/* File: armv5te/alt_stub.S */
14269/*
14270 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14271 * any interesting requests and then jump to the real instruction
14272 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14273 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14274 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14275 * bail to the real handler if breakFlags==0.
14276 */
14277    ldrb   r3, [rSELF, #offThread_breakFlags]
14278    adrl   lr, dvmAsmInstructionStart + (199 * 64)
14279    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14280    cmp    r3, #0
14281    bxeq   lr                   @ nothing to do - jump to real handler
14282    EXPORT_PC()
14283    mov    r0, rPC              @ arg0
14284    mov    r1, rFP              @ arg1
14285    mov    r2, rSELF            @ arg2
14286    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14287
14288/* ------------------------------ */
14289    .balign 64
14290.L_ALT_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
14291/* File: armv5te/alt_stub.S */
14292/*
14293 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14294 * any interesting requests and then jump to the real instruction
14295 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14296 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14297 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14298 * bail to the real handler if breakFlags==0.
14299 */
14300    ldrb   r3, [rSELF, #offThread_breakFlags]
14301    adrl   lr, dvmAsmInstructionStart + (200 * 64)
14302    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14303    cmp    r3, #0
14304    bxeq   lr                   @ nothing to do - jump to real handler
14305    EXPORT_PC()
14306    mov    r0, rPC              @ arg0
14307    mov    r1, rFP              @ arg1
14308    mov    r2, rSELF            @ arg2
14309    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14310
14311/* ------------------------------ */
14312    .balign 64
14313.L_ALT_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
14314/* File: armv5te/alt_stub.S */
14315/*
14316 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14317 * any interesting requests and then jump to the real instruction
14318 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14319 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14320 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14321 * bail to the real handler if breakFlags==0.
14322 */
14323    ldrb   r3, [rSELF, #offThread_breakFlags]
14324    adrl   lr, dvmAsmInstructionStart + (201 * 64)
14325    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14326    cmp    r3, #0
14327    bxeq   lr                   @ nothing to do - jump to real handler
14328    EXPORT_PC()
14329    mov    r0, rPC              @ arg0
14330    mov    r1, rFP              @ arg1
14331    mov    r2, rSELF            @ arg2
14332    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14333
14334/* ------------------------------ */
14335    .balign 64
14336.L_ALT_OP_REM_FLOAT_2ADDR: /* 0xca */
14337/* File: armv5te/alt_stub.S */
14338/*
14339 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14340 * any interesting requests and then jump to the real instruction
14341 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14342 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14343 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14344 * bail to the real handler if breakFlags==0.
14345 */
14346    ldrb   r3, [rSELF, #offThread_breakFlags]
14347    adrl   lr, dvmAsmInstructionStart + (202 * 64)
14348    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14349    cmp    r3, #0
14350    bxeq   lr                   @ nothing to do - jump to real handler
14351    EXPORT_PC()
14352    mov    r0, rPC              @ arg0
14353    mov    r1, rFP              @ arg1
14354    mov    r2, rSELF            @ arg2
14355    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14356
14357/* ------------------------------ */
14358    .balign 64
14359.L_ALT_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
14360/* File: armv5te/alt_stub.S */
14361/*
14362 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14363 * any interesting requests and then jump to the real instruction
14364 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14365 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14366 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14367 * bail to the real handler if breakFlags==0.
14368 */
14369    ldrb   r3, [rSELF, #offThread_breakFlags]
14370    adrl   lr, dvmAsmInstructionStart + (203 * 64)
14371    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14372    cmp    r3, #0
14373    bxeq   lr                   @ nothing to do - jump to real handler
14374    EXPORT_PC()
14375    mov    r0, rPC              @ arg0
14376    mov    r1, rFP              @ arg1
14377    mov    r2, rSELF            @ arg2
14378    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14379
14380/* ------------------------------ */
14381    .balign 64
14382.L_ALT_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
14383/* File: armv5te/alt_stub.S */
14384/*
14385 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14386 * any interesting requests and then jump to the real instruction
14387 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14388 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14389 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14390 * bail to the real handler if breakFlags==0.
14391 */
14392    ldrb   r3, [rSELF, #offThread_breakFlags]
14393    adrl   lr, dvmAsmInstructionStart + (204 * 64)
14394    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14395    cmp    r3, #0
14396    bxeq   lr                   @ nothing to do - jump to real handler
14397    EXPORT_PC()
14398    mov    r0, rPC              @ arg0
14399    mov    r1, rFP              @ arg1
14400    mov    r2, rSELF            @ arg2
14401    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14402
14403/* ------------------------------ */
14404    .balign 64
14405.L_ALT_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
14406/* File: armv5te/alt_stub.S */
14407/*
14408 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14409 * any interesting requests and then jump to the real instruction
14410 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14411 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14412 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14413 * bail to the real handler if breakFlags==0.
14414 */
14415    ldrb   r3, [rSELF, #offThread_breakFlags]
14416    adrl   lr, dvmAsmInstructionStart + (205 * 64)
14417    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14418    cmp    r3, #0
14419    bxeq   lr                   @ nothing to do - jump to real handler
14420    EXPORT_PC()
14421    mov    r0, rPC              @ arg0
14422    mov    r1, rFP              @ arg1
14423    mov    r2, rSELF            @ arg2
14424    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14425
14426/* ------------------------------ */
14427    .balign 64
14428.L_ALT_OP_DIV_DOUBLE_2ADDR: /* 0xce */
14429/* File: armv5te/alt_stub.S */
14430/*
14431 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14432 * any interesting requests and then jump to the real instruction
14433 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14434 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14435 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14436 * bail to the real handler if breakFlags==0.
14437 */
14438    ldrb   r3, [rSELF, #offThread_breakFlags]
14439    adrl   lr, dvmAsmInstructionStart + (206 * 64)
14440    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14441    cmp    r3, #0
14442    bxeq   lr                   @ nothing to do - jump to real handler
14443    EXPORT_PC()
14444    mov    r0, rPC              @ arg0
14445    mov    r1, rFP              @ arg1
14446    mov    r2, rSELF            @ arg2
14447    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14448
14449/* ------------------------------ */
14450    .balign 64
14451.L_ALT_OP_REM_DOUBLE_2ADDR: /* 0xcf */
14452/* File: armv5te/alt_stub.S */
14453/*
14454 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14455 * any interesting requests and then jump to the real instruction
14456 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14457 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14458 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14459 * bail to the real handler if breakFlags==0.
14460 */
14461    ldrb   r3, [rSELF, #offThread_breakFlags]
14462    adrl   lr, dvmAsmInstructionStart + (207 * 64)
14463    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14464    cmp    r3, #0
14465    bxeq   lr                   @ nothing to do - jump to real handler
14466    EXPORT_PC()
14467    mov    r0, rPC              @ arg0
14468    mov    r1, rFP              @ arg1
14469    mov    r2, rSELF            @ arg2
14470    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14471
14472/* ------------------------------ */
14473    .balign 64
14474.L_ALT_OP_ADD_INT_LIT16: /* 0xd0 */
14475/* File: armv5te/alt_stub.S */
14476/*
14477 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14478 * any interesting requests and then jump to the real instruction
14479 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14480 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14481 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14482 * bail to the real handler if breakFlags==0.
14483 */
14484    ldrb   r3, [rSELF, #offThread_breakFlags]
14485    adrl   lr, dvmAsmInstructionStart + (208 * 64)
14486    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14487    cmp    r3, #0
14488    bxeq   lr                   @ nothing to do - jump to real handler
14489    EXPORT_PC()
14490    mov    r0, rPC              @ arg0
14491    mov    r1, rFP              @ arg1
14492    mov    r2, rSELF            @ arg2
14493    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14494
14495/* ------------------------------ */
14496    .balign 64
14497.L_ALT_OP_RSUB_INT: /* 0xd1 */
14498/* File: armv5te/alt_stub.S */
14499/*
14500 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14501 * any interesting requests and then jump to the real instruction
14502 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14503 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14504 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14505 * bail to the real handler if breakFlags==0.
14506 */
14507    ldrb   r3, [rSELF, #offThread_breakFlags]
14508    adrl   lr, dvmAsmInstructionStart + (209 * 64)
14509    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14510    cmp    r3, #0
14511    bxeq   lr                   @ nothing to do - jump to real handler
14512    EXPORT_PC()
14513    mov    r0, rPC              @ arg0
14514    mov    r1, rFP              @ arg1
14515    mov    r2, rSELF            @ arg2
14516    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14517
14518/* ------------------------------ */
14519    .balign 64
14520.L_ALT_OP_MUL_INT_LIT16: /* 0xd2 */
14521/* File: armv5te/alt_stub.S */
14522/*
14523 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14524 * any interesting requests and then jump to the real instruction
14525 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14526 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14527 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14528 * bail to the real handler if breakFlags==0.
14529 */
14530    ldrb   r3, [rSELF, #offThread_breakFlags]
14531    adrl   lr, dvmAsmInstructionStart + (210 * 64)
14532    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14533    cmp    r3, #0
14534    bxeq   lr                   @ nothing to do - jump to real handler
14535    EXPORT_PC()
14536    mov    r0, rPC              @ arg0
14537    mov    r1, rFP              @ arg1
14538    mov    r2, rSELF            @ arg2
14539    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14540
14541/* ------------------------------ */
14542    .balign 64
14543.L_ALT_OP_DIV_INT_LIT16: /* 0xd3 */
14544/* File: armv5te/alt_stub.S */
14545/*
14546 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14547 * any interesting requests and then jump to the real instruction
14548 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14549 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14550 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14551 * bail to the real handler if breakFlags==0.
14552 */
14553    ldrb   r3, [rSELF, #offThread_breakFlags]
14554    adrl   lr, dvmAsmInstructionStart + (211 * 64)
14555    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14556    cmp    r3, #0
14557    bxeq   lr                   @ nothing to do - jump to real handler
14558    EXPORT_PC()
14559    mov    r0, rPC              @ arg0
14560    mov    r1, rFP              @ arg1
14561    mov    r2, rSELF            @ arg2
14562    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14563
14564/* ------------------------------ */
14565    .balign 64
14566.L_ALT_OP_REM_INT_LIT16: /* 0xd4 */
14567/* File: armv5te/alt_stub.S */
14568/*
14569 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14570 * any interesting requests and then jump to the real instruction
14571 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14572 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14573 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14574 * bail to the real handler if breakFlags==0.
14575 */
14576    ldrb   r3, [rSELF, #offThread_breakFlags]
14577    adrl   lr, dvmAsmInstructionStart + (212 * 64)
14578    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14579    cmp    r3, #0
14580    bxeq   lr                   @ nothing to do - jump to real handler
14581    EXPORT_PC()
14582    mov    r0, rPC              @ arg0
14583    mov    r1, rFP              @ arg1
14584    mov    r2, rSELF            @ arg2
14585    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14586
14587/* ------------------------------ */
14588    .balign 64
14589.L_ALT_OP_AND_INT_LIT16: /* 0xd5 */
14590/* File: armv5te/alt_stub.S */
14591/*
14592 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14593 * any interesting requests and then jump to the real instruction
14594 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14595 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14596 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14597 * bail to the real handler if breakFlags==0.
14598 */
14599    ldrb   r3, [rSELF, #offThread_breakFlags]
14600    adrl   lr, dvmAsmInstructionStart + (213 * 64)
14601    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14602    cmp    r3, #0
14603    bxeq   lr                   @ nothing to do - jump to real handler
14604    EXPORT_PC()
14605    mov    r0, rPC              @ arg0
14606    mov    r1, rFP              @ arg1
14607    mov    r2, rSELF            @ arg2
14608    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14609
14610/* ------------------------------ */
14611    .balign 64
14612.L_ALT_OP_OR_INT_LIT16: /* 0xd6 */
14613/* File: armv5te/alt_stub.S */
14614/*
14615 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14616 * any interesting requests and then jump to the real instruction
14617 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14618 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14619 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14620 * bail to the real handler if breakFlags==0.
14621 */
14622    ldrb   r3, [rSELF, #offThread_breakFlags]
14623    adrl   lr, dvmAsmInstructionStart + (214 * 64)
14624    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14625    cmp    r3, #0
14626    bxeq   lr                   @ nothing to do - jump to real handler
14627    EXPORT_PC()
14628    mov    r0, rPC              @ arg0
14629    mov    r1, rFP              @ arg1
14630    mov    r2, rSELF            @ arg2
14631    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14632
14633/* ------------------------------ */
14634    .balign 64
14635.L_ALT_OP_XOR_INT_LIT16: /* 0xd7 */
14636/* File: armv5te/alt_stub.S */
14637/*
14638 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14639 * any interesting requests and then jump to the real instruction
14640 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14641 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14642 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14643 * bail to the real handler if breakFlags==0.
14644 */
14645    ldrb   r3, [rSELF, #offThread_breakFlags]
14646    adrl   lr, dvmAsmInstructionStart + (215 * 64)
14647    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14648    cmp    r3, #0
14649    bxeq   lr                   @ nothing to do - jump to real handler
14650    EXPORT_PC()
14651    mov    r0, rPC              @ arg0
14652    mov    r1, rFP              @ arg1
14653    mov    r2, rSELF            @ arg2
14654    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14655
14656/* ------------------------------ */
14657    .balign 64
14658.L_ALT_OP_ADD_INT_LIT8: /* 0xd8 */
14659/* File: armv5te/alt_stub.S */
14660/*
14661 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14662 * any interesting requests and then jump to the real instruction
14663 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14664 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14665 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14666 * bail to the real handler if breakFlags==0.
14667 */
14668    ldrb   r3, [rSELF, #offThread_breakFlags]
14669    adrl   lr, dvmAsmInstructionStart + (216 * 64)
14670    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14671    cmp    r3, #0
14672    bxeq   lr                   @ nothing to do - jump to real handler
14673    EXPORT_PC()
14674    mov    r0, rPC              @ arg0
14675    mov    r1, rFP              @ arg1
14676    mov    r2, rSELF            @ arg2
14677    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14678
14679/* ------------------------------ */
14680    .balign 64
14681.L_ALT_OP_RSUB_INT_LIT8: /* 0xd9 */
14682/* File: armv5te/alt_stub.S */
14683/*
14684 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14685 * any interesting requests and then jump to the real instruction
14686 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14687 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14688 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14689 * bail to the real handler if breakFlags==0.
14690 */
14691    ldrb   r3, [rSELF, #offThread_breakFlags]
14692    adrl   lr, dvmAsmInstructionStart + (217 * 64)
14693    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14694    cmp    r3, #0
14695    bxeq   lr                   @ nothing to do - jump to real handler
14696    EXPORT_PC()
14697    mov    r0, rPC              @ arg0
14698    mov    r1, rFP              @ arg1
14699    mov    r2, rSELF            @ arg2
14700    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14701
14702/* ------------------------------ */
14703    .balign 64
14704.L_ALT_OP_MUL_INT_LIT8: /* 0xda */
14705/* File: armv5te/alt_stub.S */
14706/*
14707 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14708 * any interesting requests and then jump to the real instruction
14709 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14710 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14711 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14712 * bail to the real handler if breakFlags==0.
14713 */
14714    ldrb   r3, [rSELF, #offThread_breakFlags]
14715    adrl   lr, dvmAsmInstructionStart + (218 * 64)
14716    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14717    cmp    r3, #0
14718    bxeq   lr                   @ nothing to do - jump to real handler
14719    EXPORT_PC()
14720    mov    r0, rPC              @ arg0
14721    mov    r1, rFP              @ arg1
14722    mov    r2, rSELF            @ arg2
14723    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14724
14725/* ------------------------------ */
14726    .balign 64
14727.L_ALT_OP_DIV_INT_LIT8: /* 0xdb */
14728/* File: armv5te/alt_stub.S */
14729/*
14730 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14731 * any interesting requests and then jump to the real instruction
14732 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14733 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14734 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14735 * bail to the real handler if breakFlags==0.
14736 */
14737    ldrb   r3, [rSELF, #offThread_breakFlags]
14738    adrl   lr, dvmAsmInstructionStart + (219 * 64)
14739    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14740    cmp    r3, #0
14741    bxeq   lr                   @ nothing to do - jump to real handler
14742    EXPORT_PC()
14743    mov    r0, rPC              @ arg0
14744    mov    r1, rFP              @ arg1
14745    mov    r2, rSELF            @ arg2
14746    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14747
14748/* ------------------------------ */
14749    .balign 64
14750.L_ALT_OP_REM_INT_LIT8: /* 0xdc */
14751/* File: armv5te/alt_stub.S */
14752/*
14753 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14754 * any interesting requests and then jump to the real instruction
14755 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14756 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14757 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14758 * bail to the real handler if breakFlags==0.
14759 */
14760    ldrb   r3, [rSELF, #offThread_breakFlags]
14761    adrl   lr, dvmAsmInstructionStart + (220 * 64)
14762    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14763    cmp    r3, #0
14764    bxeq   lr                   @ nothing to do - jump to real handler
14765    EXPORT_PC()
14766    mov    r0, rPC              @ arg0
14767    mov    r1, rFP              @ arg1
14768    mov    r2, rSELF            @ arg2
14769    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14770
14771/* ------------------------------ */
14772    .balign 64
14773.L_ALT_OP_AND_INT_LIT8: /* 0xdd */
14774/* File: armv5te/alt_stub.S */
14775/*
14776 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14777 * any interesting requests and then jump to the real instruction
14778 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14779 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14780 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14781 * bail to the real handler if breakFlags==0.
14782 */
14783    ldrb   r3, [rSELF, #offThread_breakFlags]
14784    adrl   lr, dvmAsmInstructionStart + (221 * 64)
14785    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14786    cmp    r3, #0
14787    bxeq   lr                   @ nothing to do - jump to real handler
14788    EXPORT_PC()
14789    mov    r0, rPC              @ arg0
14790    mov    r1, rFP              @ arg1
14791    mov    r2, rSELF            @ arg2
14792    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14793
14794/* ------------------------------ */
14795    .balign 64
14796.L_ALT_OP_OR_INT_LIT8: /* 0xde */
14797/* File: armv5te/alt_stub.S */
14798/*
14799 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14800 * any interesting requests and then jump to the real instruction
14801 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14802 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14803 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14804 * bail to the real handler if breakFlags==0.
14805 */
14806    ldrb   r3, [rSELF, #offThread_breakFlags]
14807    adrl   lr, dvmAsmInstructionStart + (222 * 64)
14808    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14809    cmp    r3, #0
14810    bxeq   lr                   @ nothing to do - jump to real handler
14811    EXPORT_PC()
14812    mov    r0, rPC              @ arg0
14813    mov    r1, rFP              @ arg1
14814    mov    r2, rSELF            @ arg2
14815    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14816
14817/* ------------------------------ */
14818    .balign 64
14819.L_ALT_OP_XOR_INT_LIT8: /* 0xdf */
14820/* File: armv5te/alt_stub.S */
14821/*
14822 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14823 * any interesting requests and then jump to the real instruction
14824 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14825 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14826 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14827 * bail to the real handler if breakFlags==0.
14828 */
14829    ldrb   r3, [rSELF, #offThread_breakFlags]
14830    adrl   lr, dvmAsmInstructionStart + (223 * 64)
14831    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14832    cmp    r3, #0
14833    bxeq   lr                   @ nothing to do - jump to real handler
14834    EXPORT_PC()
14835    mov    r0, rPC              @ arg0
14836    mov    r1, rFP              @ arg1
14837    mov    r2, rSELF            @ arg2
14838    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14839
14840/* ------------------------------ */
14841    .balign 64
14842.L_ALT_OP_SHL_INT_LIT8: /* 0xe0 */
14843/* File: armv5te/alt_stub.S */
14844/*
14845 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14846 * any interesting requests and then jump to the real instruction
14847 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14848 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14849 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14850 * bail to the real handler if breakFlags==0.
14851 */
14852    ldrb   r3, [rSELF, #offThread_breakFlags]
14853    adrl   lr, dvmAsmInstructionStart + (224 * 64)
14854    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14855    cmp    r3, #0
14856    bxeq   lr                   @ nothing to do - jump to real handler
14857    EXPORT_PC()
14858    mov    r0, rPC              @ arg0
14859    mov    r1, rFP              @ arg1
14860    mov    r2, rSELF            @ arg2
14861    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14862
14863/* ------------------------------ */
14864    .balign 64
14865.L_ALT_OP_SHR_INT_LIT8: /* 0xe1 */
14866/* File: armv5te/alt_stub.S */
14867/*
14868 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14869 * any interesting requests and then jump to the real instruction
14870 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14871 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14872 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14873 * bail to the real handler if breakFlags==0.
14874 */
14875    ldrb   r3, [rSELF, #offThread_breakFlags]
14876    adrl   lr, dvmAsmInstructionStart + (225 * 64)
14877    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14878    cmp    r3, #0
14879    bxeq   lr                   @ nothing to do - jump to real handler
14880    EXPORT_PC()
14881    mov    r0, rPC              @ arg0
14882    mov    r1, rFP              @ arg1
14883    mov    r2, rSELF            @ arg2
14884    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14885
14886/* ------------------------------ */
14887    .balign 64
14888.L_ALT_OP_USHR_INT_LIT8: /* 0xe2 */
14889/* File: armv5te/alt_stub.S */
14890/*
14891 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14892 * any interesting requests and then jump to the real instruction
14893 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14894 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14895 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14896 * bail to the real handler if breakFlags==0.
14897 */
14898    ldrb   r3, [rSELF, #offThread_breakFlags]
14899    adrl   lr, dvmAsmInstructionStart + (226 * 64)
14900    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14901    cmp    r3, #0
14902    bxeq   lr                   @ nothing to do - jump to real handler
14903    EXPORT_PC()
14904    mov    r0, rPC              @ arg0
14905    mov    r1, rFP              @ arg1
14906    mov    r2, rSELF            @ arg2
14907    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14908
14909/* ------------------------------ */
14910    .balign 64
14911.L_ALT_OP_IGET_VOLATILE: /* 0xe3 */
14912/* File: armv5te/alt_stub.S */
14913/*
14914 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14915 * any interesting requests and then jump to the real instruction
14916 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14917 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14918 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14919 * bail to the real handler if breakFlags==0.
14920 */
14921    ldrb   r3, [rSELF, #offThread_breakFlags]
14922    adrl   lr, dvmAsmInstructionStart + (227 * 64)
14923    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14924    cmp    r3, #0
14925    bxeq   lr                   @ nothing to do - jump to real handler
14926    EXPORT_PC()
14927    mov    r0, rPC              @ arg0
14928    mov    r1, rFP              @ arg1
14929    mov    r2, rSELF            @ arg2
14930    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14931
14932/* ------------------------------ */
14933    .balign 64
14934.L_ALT_OP_IPUT_VOLATILE: /* 0xe4 */
14935/* File: armv5te/alt_stub.S */
14936/*
14937 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14938 * any interesting requests and then jump to the real instruction
14939 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14940 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14941 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14942 * bail to the real handler if breakFlags==0.
14943 */
14944    ldrb   r3, [rSELF, #offThread_breakFlags]
14945    adrl   lr, dvmAsmInstructionStart + (228 * 64)
14946    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14947    cmp    r3, #0
14948    bxeq   lr                   @ nothing to do - jump to real handler
14949    EXPORT_PC()
14950    mov    r0, rPC              @ arg0
14951    mov    r1, rFP              @ arg1
14952    mov    r2, rSELF            @ arg2
14953    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14954
14955/* ------------------------------ */
14956    .balign 64
14957.L_ALT_OP_SGET_VOLATILE: /* 0xe5 */
14958/* File: armv5te/alt_stub.S */
14959/*
14960 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14961 * any interesting requests and then jump to the real instruction
14962 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14963 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14964 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14965 * bail to the real handler if breakFlags==0.
14966 */
14967    ldrb   r3, [rSELF, #offThread_breakFlags]
14968    adrl   lr, dvmAsmInstructionStart + (229 * 64)
14969    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14970    cmp    r3, #0
14971    bxeq   lr                   @ nothing to do - jump to real handler
14972    EXPORT_PC()
14973    mov    r0, rPC              @ arg0
14974    mov    r1, rFP              @ arg1
14975    mov    r2, rSELF            @ arg2
14976    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14977
14978/* ------------------------------ */
14979    .balign 64
14980.L_ALT_OP_SPUT_VOLATILE: /* 0xe6 */
14981/* File: armv5te/alt_stub.S */
14982/*
14983 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14984 * any interesting requests and then jump to the real instruction
14985 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14986 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14987 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14988 * bail to the real handler if breakFlags==0.
14989 */
14990    ldrb   r3, [rSELF, #offThread_breakFlags]
14991    adrl   lr, dvmAsmInstructionStart + (230 * 64)
14992    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14993    cmp    r3, #0
14994    bxeq   lr                   @ nothing to do - jump to real handler
14995    EXPORT_PC()
14996    mov    r0, rPC              @ arg0
14997    mov    r1, rFP              @ arg1
14998    mov    r2, rSELF            @ arg2
14999    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15000
15001/* ------------------------------ */
15002    .balign 64
15003.L_ALT_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
15004/* File: armv5te/alt_stub.S */
15005/*
15006 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15007 * any interesting requests and then jump to the real instruction
15008 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15009 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15010 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15011 * bail to the real handler if breakFlags==0.
15012 */
15013    ldrb   r3, [rSELF, #offThread_breakFlags]
15014    adrl   lr, dvmAsmInstructionStart + (231 * 64)
15015    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15016    cmp    r3, #0
15017    bxeq   lr                   @ nothing to do - jump to real handler
15018    EXPORT_PC()
15019    mov    r0, rPC              @ arg0
15020    mov    r1, rFP              @ arg1
15021    mov    r2, rSELF            @ arg2
15022    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15023
15024/* ------------------------------ */
15025    .balign 64
15026.L_ALT_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
15027/* File: armv5te/alt_stub.S */
15028/*
15029 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15030 * any interesting requests and then jump to the real instruction
15031 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15032 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15033 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15034 * bail to the real handler if breakFlags==0.
15035 */
15036    ldrb   r3, [rSELF, #offThread_breakFlags]
15037    adrl   lr, dvmAsmInstructionStart + (232 * 64)
15038    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15039    cmp    r3, #0
15040    bxeq   lr                   @ nothing to do - jump to real handler
15041    EXPORT_PC()
15042    mov    r0, rPC              @ arg0
15043    mov    r1, rFP              @ arg1
15044    mov    r2, rSELF            @ arg2
15045    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15046
15047/* ------------------------------ */
15048    .balign 64
15049.L_ALT_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
15050/* File: armv5te/alt_stub.S */
15051/*
15052 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15053 * any interesting requests and then jump to the real instruction
15054 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15055 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15056 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15057 * bail to the real handler if breakFlags==0.
15058 */
15059    ldrb   r3, [rSELF, #offThread_breakFlags]
15060    adrl   lr, dvmAsmInstructionStart + (233 * 64)
15061    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15062    cmp    r3, #0
15063    bxeq   lr                   @ nothing to do - jump to real handler
15064    EXPORT_PC()
15065    mov    r0, rPC              @ arg0
15066    mov    r1, rFP              @ arg1
15067    mov    r2, rSELF            @ arg2
15068    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15069
15070/* ------------------------------ */
15071    .balign 64
15072.L_ALT_OP_SGET_WIDE_VOLATILE: /* 0xea */
15073/* File: armv5te/alt_stub.S */
15074/*
15075 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15076 * any interesting requests and then jump to the real instruction
15077 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15078 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15079 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15080 * bail to the real handler if breakFlags==0.
15081 */
15082    ldrb   r3, [rSELF, #offThread_breakFlags]
15083    adrl   lr, dvmAsmInstructionStart + (234 * 64)
15084    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15085    cmp    r3, #0
15086    bxeq   lr                   @ nothing to do - jump to real handler
15087    EXPORT_PC()
15088    mov    r0, rPC              @ arg0
15089    mov    r1, rFP              @ arg1
15090    mov    r2, rSELF            @ arg2
15091    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15092
15093/* ------------------------------ */
15094    .balign 64
15095.L_ALT_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
15096/* File: armv5te/alt_stub.S */
15097/*
15098 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15099 * any interesting requests and then jump to the real instruction
15100 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15101 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15102 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15103 * bail to the real handler if breakFlags==0.
15104 */
15105    ldrb   r3, [rSELF, #offThread_breakFlags]
15106    adrl   lr, dvmAsmInstructionStart + (235 * 64)
15107    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15108    cmp    r3, #0
15109    bxeq   lr                   @ nothing to do - jump to real handler
15110    EXPORT_PC()
15111    mov    r0, rPC              @ arg0
15112    mov    r1, rFP              @ arg1
15113    mov    r2, rSELF            @ arg2
15114    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15115
15116/* ------------------------------ */
15117    .balign 64
15118.L_ALT_OP_BREAKPOINT: /* 0xec */
15119/* File: armv5te/alt_stub.S */
15120/*
15121 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15122 * any interesting requests and then jump to the real instruction
15123 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15124 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15125 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15126 * bail to the real handler if breakFlags==0.
15127 */
15128    ldrb   r3, [rSELF, #offThread_breakFlags]
15129    adrl   lr, dvmAsmInstructionStart + (236 * 64)
15130    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15131    cmp    r3, #0
15132    bxeq   lr                   @ nothing to do - jump to real handler
15133    EXPORT_PC()
15134    mov    r0, rPC              @ arg0
15135    mov    r1, rFP              @ arg1
15136    mov    r2, rSELF            @ arg2
15137    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15138
15139/* ------------------------------ */
15140    .balign 64
15141.L_ALT_OP_THROW_VERIFICATION_ERROR: /* 0xed */
15142/* File: armv5te/alt_stub.S */
15143/*
15144 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15145 * any interesting requests and then jump to the real instruction
15146 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15147 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15148 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15149 * bail to the real handler if breakFlags==0.
15150 */
15151    ldrb   r3, [rSELF, #offThread_breakFlags]
15152    adrl   lr, dvmAsmInstructionStart + (237 * 64)
15153    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15154    cmp    r3, #0
15155    bxeq   lr                   @ nothing to do - jump to real handler
15156    EXPORT_PC()
15157    mov    r0, rPC              @ arg0
15158    mov    r1, rFP              @ arg1
15159    mov    r2, rSELF            @ arg2
15160    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15161
15162/* ------------------------------ */
15163    .balign 64
15164.L_ALT_OP_EXECUTE_INLINE: /* 0xee */
15165/* File: armv5te/alt_stub.S */
15166/*
15167 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15168 * any interesting requests and then jump to the real instruction
15169 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15170 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15171 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15172 * bail to the real handler if breakFlags==0.
15173 */
15174    ldrb   r3, [rSELF, #offThread_breakFlags]
15175    adrl   lr, dvmAsmInstructionStart + (238 * 64)
15176    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15177    cmp    r3, #0
15178    bxeq   lr                   @ nothing to do - jump to real handler
15179    EXPORT_PC()
15180    mov    r0, rPC              @ arg0
15181    mov    r1, rFP              @ arg1
15182    mov    r2, rSELF            @ arg2
15183    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15184
15185/* ------------------------------ */
15186    .balign 64
15187.L_ALT_OP_EXECUTE_INLINE_RANGE: /* 0xef */
15188/* File: armv5te/alt_stub.S */
15189/*
15190 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15191 * any interesting requests and then jump to the real instruction
15192 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15193 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15194 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15195 * bail to the real handler if breakFlags==0.
15196 */
15197    ldrb   r3, [rSELF, #offThread_breakFlags]
15198    adrl   lr, dvmAsmInstructionStart + (239 * 64)
15199    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15200    cmp    r3, #0
15201    bxeq   lr                   @ nothing to do - jump to real handler
15202    EXPORT_PC()
15203    mov    r0, rPC              @ arg0
15204    mov    r1, rFP              @ arg1
15205    mov    r2, rSELF            @ arg2
15206    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15207
15208/* ------------------------------ */
15209    .balign 64
15210.L_ALT_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */
15211/* File: armv5te/alt_stub.S */
15212/*
15213 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15214 * any interesting requests and then jump to the real instruction
15215 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15216 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15217 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15218 * bail to the real handler if breakFlags==0.
15219 */
15220    ldrb   r3, [rSELF, #offThread_breakFlags]
15221    adrl   lr, dvmAsmInstructionStart + (240 * 64)
15222    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15223    cmp    r3, #0
15224    bxeq   lr                   @ nothing to do - jump to real handler
15225    EXPORT_PC()
15226    mov    r0, rPC              @ arg0
15227    mov    r1, rFP              @ arg1
15228    mov    r2, rSELF            @ arg2
15229    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15230
15231/* ------------------------------ */
15232    .balign 64
15233.L_ALT_OP_RETURN_VOID_BARRIER: /* 0xf1 */
15234/* File: armv5te/alt_stub.S */
15235/*
15236 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15237 * any interesting requests and then jump to the real instruction
15238 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15239 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15240 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15241 * bail to the real handler if breakFlags==0.
15242 */
15243    ldrb   r3, [rSELF, #offThread_breakFlags]
15244    adrl   lr, dvmAsmInstructionStart + (241 * 64)
15245    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15246    cmp    r3, #0
15247    bxeq   lr                   @ nothing to do - jump to real handler
15248    EXPORT_PC()
15249    mov    r0, rPC              @ arg0
15250    mov    r1, rFP              @ arg1
15251    mov    r2, rSELF            @ arg2
15252    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15253
15254/* ------------------------------ */
15255    .balign 64
15256.L_ALT_OP_IGET_QUICK: /* 0xf2 */
15257/* File: armv5te/alt_stub.S */
15258/*
15259 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15260 * any interesting requests and then jump to the real instruction
15261 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15262 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15263 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15264 * bail to the real handler if breakFlags==0.
15265 */
15266    ldrb   r3, [rSELF, #offThread_breakFlags]
15267    adrl   lr, dvmAsmInstructionStart + (242 * 64)
15268    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15269    cmp    r3, #0
15270    bxeq   lr                   @ nothing to do - jump to real handler
15271    EXPORT_PC()
15272    mov    r0, rPC              @ arg0
15273    mov    r1, rFP              @ arg1
15274    mov    r2, rSELF            @ arg2
15275    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15276
15277/* ------------------------------ */
15278    .balign 64
15279.L_ALT_OP_IGET_WIDE_QUICK: /* 0xf3 */
15280/* File: armv5te/alt_stub.S */
15281/*
15282 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15283 * any interesting requests and then jump to the real instruction
15284 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15285 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15286 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15287 * bail to the real handler if breakFlags==0.
15288 */
15289    ldrb   r3, [rSELF, #offThread_breakFlags]
15290    adrl   lr, dvmAsmInstructionStart + (243 * 64)
15291    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15292    cmp    r3, #0
15293    bxeq   lr                   @ nothing to do - jump to real handler
15294    EXPORT_PC()
15295    mov    r0, rPC              @ arg0
15296    mov    r1, rFP              @ arg1
15297    mov    r2, rSELF            @ arg2
15298    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15299
15300/* ------------------------------ */
15301    .balign 64
15302.L_ALT_OP_IGET_OBJECT_QUICK: /* 0xf4 */
15303/* File: armv5te/alt_stub.S */
15304/*
15305 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15306 * any interesting requests and then jump to the real instruction
15307 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15308 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15309 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15310 * bail to the real handler if breakFlags==0.
15311 */
15312    ldrb   r3, [rSELF, #offThread_breakFlags]
15313    adrl   lr, dvmAsmInstructionStart + (244 * 64)
15314    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15315    cmp    r3, #0
15316    bxeq   lr                   @ nothing to do - jump to real handler
15317    EXPORT_PC()
15318    mov    r0, rPC              @ arg0
15319    mov    r1, rFP              @ arg1
15320    mov    r2, rSELF            @ arg2
15321    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15322
15323/* ------------------------------ */
15324    .balign 64
15325.L_ALT_OP_IPUT_QUICK: /* 0xf5 */
15326/* File: armv5te/alt_stub.S */
15327/*
15328 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15329 * any interesting requests and then jump to the real instruction
15330 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15331 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15332 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15333 * bail to the real handler if breakFlags==0.
15334 */
15335    ldrb   r3, [rSELF, #offThread_breakFlags]
15336    adrl   lr, dvmAsmInstructionStart + (245 * 64)
15337    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15338    cmp    r3, #0
15339    bxeq   lr                   @ nothing to do - jump to real handler
15340    EXPORT_PC()
15341    mov    r0, rPC              @ arg0
15342    mov    r1, rFP              @ arg1
15343    mov    r2, rSELF            @ arg2
15344    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15345
15346/* ------------------------------ */
15347    .balign 64
15348.L_ALT_OP_IPUT_WIDE_QUICK: /* 0xf6 */
15349/* File: armv5te/alt_stub.S */
15350/*
15351 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15352 * any interesting requests and then jump to the real instruction
15353 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15354 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15355 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15356 * bail to the real handler if breakFlags==0.
15357 */
15358    ldrb   r3, [rSELF, #offThread_breakFlags]
15359    adrl   lr, dvmAsmInstructionStart + (246 * 64)
15360    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15361    cmp    r3, #0
15362    bxeq   lr                   @ nothing to do - jump to real handler
15363    EXPORT_PC()
15364    mov    r0, rPC              @ arg0
15365    mov    r1, rFP              @ arg1
15366    mov    r2, rSELF            @ arg2
15367    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15368
15369/* ------------------------------ */
15370    .balign 64
15371.L_ALT_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
15372/* File: armv5te/alt_stub.S */
15373/*
15374 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15375 * any interesting requests and then jump to the real instruction
15376 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15377 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15378 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15379 * bail to the real handler if breakFlags==0.
15380 */
15381    ldrb   r3, [rSELF, #offThread_breakFlags]
15382    adrl   lr, dvmAsmInstructionStart + (247 * 64)
15383    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15384    cmp    r3, #0
15385    bxeq   lr                   @ nothing to do - jump to real handler
15386    EXPORT_PC()
15387    mov    r0, rPC              @ arg0
15388    mov    r1, rFP              @ arg1
15389    mov    r2, rSELF            @ arg2
15390    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15391
15392/* ------------------------------ */
15393    .balign 64
15394.L_ALT_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
15395/* File: armv5te/alt_stub.S */
15396/*
15397 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15398 * any interesting requests and then jump to the real instruction
15399 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15400 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15401 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15402 * bail to the real handler if breakFlags==0.
15403 */
15404    ldrb   r3, [rSELF, #offThread_breakFlags]
15405    adrl   lr, dvmAsmInstructionStart + (248 * 64)
15406    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15407    cmp    r3, #0
15408    bxeq   lr                   @ nothing to do - jump to real handler
15409    EXPORT_PC()
15410    mov    r0, rPC              @ arg0
15411    mov    r1, rFP              @ arg1
15412    mov    r2, rSELF            @ arg2
15413    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15414
15415/* ------------------------------ */
15416    .balign 64
15417.L_ALT_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
15418/* File: armv5te/alt_stub.S */
15419/*
15420 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15421 * any interesting requests and then jump to the real instruction
15422 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15423 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15424 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15425 * bail to the real handler if breakFlags==0.
15426 */
15427    ldrb   r3, [rSELF, #offThread_breakFlags]
15428    adrl   lr, dvmAsmInstructionStart + (249 * 64)
15429    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15430    cmp    r3, #0
15431    bxeq   lr                   @ nothing to do - jump to real handler
15432    EXPORT_PC()
15433    mov    r0, rPC              @ arg0
15434    mov    r1, rFP              @ arg1
15435    mov    r2, rSELF            @ arg2
15436    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15437
15438/* ------------------------------ */
15439    .balign 64
15440.L_ALT_OP_INVOKE_SUPER_QUICK: /* 0xfa */
15441/* File: armv5te/alt_stub.S */
15442/*
15443 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15444 * any interesting requests and then jump to the real instruction
15445 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15446 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15447 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15448 * bail to the real handler if breakFlags==0.
15449 */
15450    ldrb   r3, [rSELF, #offThread_breakFlags]
15451    adrl   lr, dvmAsmInstructionStart + (250 * 64)
15452    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15453    cmp    r3, #0
15454    bxeq   lr                   @ nothing to do - jump to real handler
15455    EXPORT_PC()
15456    mov    r0, rPC              @ arg0
15457    mov    r1, rFP              @ arg1
15458    mov    r2, rSELF            @ arg2
15459    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15460
15461/* ------------------------------ */
15462    .balign 64
15463.L_ALT_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
15464/* File: armv5te/alt_stub.S */
15465/*
15466 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15467 * any interesting requests and then jump to the real instruction
15468 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15469 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15470 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15471 * bail to the real handler if breakFlags==0.
15472 */
15473    ldrb   r3, [rSELF, #offThread_breakFlags]
15474    adrl   lr, dvmAsmInstructionStart + (251 * 64)
15475    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15476    cmp    r3, #0
15477    bxeq   lr                   @ nothing to do - jump to real handler
15478    EXPORT_PC()
15479    mov    r0, rPC              @ arg0
15480    mov    r1, rFP              @ arg1
15481    mov    r2, rSELF            @ arg2
15482    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15483
15484/* ------------------------------ */
15485    .balign 64
15486.L_ALT_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
15487/* File: armv5te/alt_stub.S */
15488/*
15489 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15490 * any interesting requests and then jump to the real instruction
15491 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15492 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15493 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15494 * bail to the real handler if breakFlags==0.
15495 */
15496    ldrb   r3, [rSELF, #offThread_breakFlags]
15497    adrl   lr, dvmAsmInstructionStart + (252 * 64)
15498    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15499    cmp    r3, #0
15500    bxeq   lr                   @ nothing to do - jump to real handler
15501    EXPORT_PC()
15502    mov    r0, rPC              @ arg0
15503    mov    r1, rFP              @ arg1
15504    mov    r2, rSELF            @ arg2
15505    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15506
15507/* ------------------------------ */
15508    .balign 64
15509.L_ALT_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
15510/* File: armv5te/alt_stub.S */
15511/*
15512 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15513 * any interesting requests and then jump to the real instruction
15514 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15515 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15516 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15517 * bail to the real handler if breakFlags==0.
15518 */
15519    ldrb   r3, [rSELF, #offThread_breakFlags]
15520    adrl   lr, dvmAsmInstructionStart + (253 * 64)
15521    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15522    cmp    r3, #0
15523    bxeq   lr                   @ nothing to do - jump to real handler
15524    EXPORT_PC()
15525    mov    r0, rPC              @ arg0
15526    mov    r1, rFP              @ arg1
15527    mov    r2, rSELF            @ arg2
15528    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15529
15530/* ------------------------------ */
15531    .balign 64
15532.L_ALT_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
15533/* File: armv5te/alt_stub.S */
15534/*
15535 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15536 * any interesting requests and then jump to the real instruction
15537 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15538 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15539 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15540 * bail to the real handler if breakFlags==0.
15541 */
15542    ldrb   r3, [rSELF, #offThread_breakFlags]
15543    adrl   lr, dvmAsmInstructionStart + (254 * 64)
15544    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15545    cmp    r3, #0
15546    bxeq   lr                   @ nothing to do - jump to real handler
15547    EXPORT_PC()
15548    mov    r0, rPC              @ arg0
15549    mov    r1, rFP              @ arg1
15550    mov    r2, rSELF            @ arg2
15551    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15552
15553/* ------------------------------ */
15554    .balign 64
15555.L_ALT_OP_UNUSED_FF: /* 0xff */
15556/* File: armv5te/alt_stub.S */
15557/*
15558 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15559 * any interesting requests and then jump to the real instruction
15560 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15561 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15562 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15563 * bail to the real handler if breakFlags==0.
15564 */
15565    ldrb   r3, [rSELF, #offThread_breakFlags]
15566    adrl   lr, dvmAsmInstructionStart + (255 * 64)
15567    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15568    cmp    r3, #0
15569    bxeq   lr                   @ nothing to do - jump to real handler
15570    EXPORT_PC()
15571    mov    r0, rPC              @ arg0
15572    mov    r1, rFP              @ arg1
15573    mov    r2, rSELF            @ arg2
15574    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15575
15576    .balign 64
15577    .size   dvmAsmAltInstructionStart, .-dvmAsmAltInstructionStart
15578    .global dvmAsmAltInstructionEnd
15579dvmAsmAltInstructionEnd:
15580/* File: armv5te/footer.S */
15581/*
15582 * ===========================================================================
15583 *  Common subroutines and data
15584 * ===========================================================================
15585 */
15586
15587    .text
15588    .align  2
15589
15590#if defined(WITH_JIT)
15591
15592#if defined(WITH_SELF_VERIFICATION)
15593/*
15594 * "longjmp" to a translation after single-stepping.  Before returning
15595 * to translation, must save state for self-verification.
15596 */
15597    .global dvmJitResumeTranslation              @ (Thread* self, u4* dFP)
15598dvmJitResumeTranslation:
15599    mov    rSELF, r0                             @ restore self
15600    mov    rPC, r1                               @ restore Dalvik pc
15601    mov    rFP, r2                               @ restore Dalvik fp
15602    ldr    r10, [rSELF,#offThread_jitResumeNPC]  @ resume address
15603    mov    r2, #0
15604    str    r2, [rSELF,#offThread_jitResumeNPC]   @ reset resume address
15605    ldr    sp, [rSELF,#offThread_jitResumeNSP]   @ cut back native stack
15606    b      jitSVShadowRunStart                   @ resume as if cache hit
15607                                                 @ expects resume addr in r10
15608
15609    .global dvmJitToInterpPunt
15610dvmJitToInterpPunt:
15611    mov    r2,#kSVSPunt                 @ r2<- interpreter entry point
15612    mov    r3, #0
15613    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
15614    b      jitSVShadowRunEnd            @ doesn't return
15615
15616    .global dvmJitToInterpSingleStep
15617dvmJitToInterpSingleStep:
15618    mov    rPC, r0              @ set up dalvik pc
15619    EXPORT_PC()
15620    str    lr, [rSELF,#offThread_jitResumeNPC]
15621    str    sp, [rSELF,#offThread_jitResumeNSP]
15622    str    r1, [rSELF,#offThread_jitResumeDPC]
15623    mov    r2,#kSVSSingleStep           @ r2<- interpreter entry point
15624    b      jitSVShadowRunEnd            @ doesn't return
15625
15626
15627    .global dvmJitToInterpNoChainNoProfile
15628dvmJitToInterpNoChainNoProfile:
15629    mov    r0,rPC                       @ pass our target PC
15630    mov    r2,#kSVSNoProfile            @ r2<- interpreter entry point
15631    mov    r3, #0                       @ 0 means !inJitCodeCache
15632    str    r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land
15633    b      jitSVShadowRunEnd            @ doesn't return
15634
15635    .global dvmJitToInterpTraceSelectNoChain
15636dvmJitToInterpTraceSelectNoChain:
15637    mov    r0,rPC                       @ pass our target PC
15638    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
15639    mov    r3, #0                       @ 0 means !inJitCodeCache
15640    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
15641    b      jitSVShadowRunEnd            @ doesn't return
15642
15643    .global dvmJitToInterpTraceSelect
15644dvmJitToInterpTraceSelect:
15645    ldr    r0,[lr, #-1]                 @ pass our target PC
15646    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
15647    mov    r3, #0                       @ 0 means !inJitCodeCache
15648    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
15649    b      jitSVShadowRunEnd            @ doesn't return
15650
15651    .global dvmJitToInterpBackwardBranch
15652dvmJitToInterpBackwardBranch:
15653    ldr    r0,[lr, #-1]                 @ pass our target PC
15654    mov    r2,#kSVSBackwardBranch       @ r2<- interpreter entry point
15655    mov    r3, #0                       @ 0 means !inJitCodeCache
15656    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
15657    b      jitSVShadowRunEnd            @ doesn't return
15658
15659    .global dvmJitToInterpNormal
15660dvmJitToInterpNormal:
15661    ldr    r0,[lr, #-1]                 @ pass our target PC
15662    mov    r2,#kSVSNormal               @ r2<- interpreter entry point
15663    mov    r3, #0                       @ 0 means !inJitCodeCache
15664    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
15665    b      jitSVShadowRunEnd            @ doesn't return
15666
15667    .global dvmJitToInterpNoChain
15668dvmJitToInterpNoChain:
15669    mov    r0,rPC                       @ pass our target PC
15670    mov    r2,#kSVSNoChain              @ r2<- interpreter entry point
15671    mov    r3, #0                       @ 0 means !inJitCodeCache
15672    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
15673    b      jitSVShadowRunEnd            @ doesn't return
15674#else
15675
15676/*
15677 * "longjmp" to a translation after single-stepping.
15678 */
15679    .global dvmJitResumeTranslation              @ (Thread* self, u4* dFP)
15680dvmJitResumeTranslation:
15681    mov    rSELF, r0                             @ restore self
15682    mov    rPC, r1                               @ restore Dalvik pc
15683    mov    rFP, r2                               @ restore Dalvik fp
15684    ldr    r0, [rSELF,#offThread_jitResumeNPC]
15685    mov    r2, #0
15686    str    r2, [rSELF,#offThread_jitResumeNPC]   @ reset resume address
15687    ldr    sp, [rSELF,#offThread_jitResumeNSP]   @ cut back native stack
15688    bx     r0                                    @ resume translation
15689
15690/*
15691 * Return from the translation cache to the interpreter when the compiler is
15692 * having issues translating/executing a Dalvik instruction. We have to skip
15693 * the code cache lookup otherwise it is possible to indefinitely bouce
15694 * between the interpreter and the code cache if the instruction that fails
15695 * to be compiled happens to be at a trace start.
15696 */
15697    .global dvmJitToInterpPunt
15698dvmJitToInterpPunt:
15699    mov    rPC, r0
15700#if defined(WITH_JIT_TUNING)
15701    mov    r0,lr
15702    bl     dvmBumpPunt;
15703#endif
15704    EXPORT_PC()
15705    mov    r0, #0
15706    str    r0, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
15707    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15708    FETCH_INST()
15709    GET_INST_OPCODE(ip)
15710    GOTO_OPCODE(ip)
15711
15712/*
15713 * Return to the interpreter to handle a single instruction.
15714 * We'll use the normal single-stepping mechanism via interpBreak,
15715 * but also save the native pc of the resume point in the translation
15716 * and the native sp so that we can later do the equivalent of a
15717 * longjmp() to resume.
15718 * On entry:
15719 *    dPC <= Dalvik PC of instrucion to interpret
15720 *    lr <= resume point in translation
15721 *    r1 <= Dalvik PC of next instruction
15722 */
15723    .global dvmJitToInterpSingleStep
15724dvmJitToInterpSingleStep:
15725    mov    rPC, r0              @ set up dalvik pc
15726    EXPORT_PC()
15727    str    lr, [rSELF,#offThread_jitResumeNPC]
15728    str    sp, [rSELF,#offThread_jitResumeNSP]
15729    str    r1, [rSELF,#offThread_jitResumeDPC]
15730    mov    r1, #1
15731    str    r1, [rSELF,#offThread_singleStepCount]  @ just step once
15732    mov    r0, rSELF
15733    mov    r1, #kSubModeCountedStep
15734    bl     dvmEnableSubMode     @ (self, newMode)
15735    ldr    rIBASE, [rSELF,#offThread_curHandlerTable]
15736    FETCH_INST()
15737    GET_INST_OPCODE(ip)
15738    GOTO_OPCODE(ip)
15739
15740/*
15741 * Return from the translation cache and immediately request
15742 * a translation for the exit target.  Commonly used for callees.
15743 */
15744    .global dvmJitToInterpTraceSelectNoChain
15745dvmJitToInterpTraceSelectNoChain:
15746#if defined(WITH_JIT_TUNING)
15747    bl     dvmBumpNoChain
15748#endif
15749    mov    r0,rPC
15750    mov    r1,rSELF
15751    bl     dvmJitGetTraceAddrThread @ (pc, self)
15752    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
15753    mov    r1, rPC                  @ arg1 of translation may need this
15754    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
15755    cmp    r0,#0                    @ !0 means translation exists
15756    bxne   r0                       @ continue native execution if so
15757    b      2f                       @ branch over to use the interpreter
15758
15759/*
15760 * Return from the translation cache and immediately request
15761 * a translation for the exit target.  Commonly used following
15762 * invokes.
15763 */
15764    .global dvmJitToInterpTraceSelect
15765dvmJitToInterpTraceSelect:
15766    ldr    rPC,[lr, #-1]           @ get our target PC
15767    add    rINST,lr,#-5            @ save start of chain branch
15768    add    rINST, #-4              @  .. which is 9 bytes back
15769    mov    r0,rPC
15770    mov    r1,rSELF
15771    bl     dvmJitGetTraceAddrThread @ (pc, self)
15772    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
15773    cmp    r0,#0
15774    beq    2f
15775    mov    r1,rINST
15776    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
15777    mov    r1, rPC                  @ arg1 of translation may need this
15778    mov    lr, #0                   @ in case target is HANDLER_INTERPRET
15779    cmp    r0,#0                    @ successful chain?
15780    bxne   r0                       @ continue native execution
15781    b      toInterpreter            @ didn't chain - resume with interpreter
15782
15783/* No translation, so request one if profiling isn't disabled*/
157842:
15785    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15786    ldr    r0, [rSELF, #offThread_pJitProfTable]
15787    FETCH_INST()
15788    cmp    r0, #0
15789    movne  r2,#kJitTSelectRequestHot   @ ask for trace selection
15790    bne    common_selectTrace
15791    GET_INST_OPCODE(ip)
15792    GOTO_OPCODE(ip)
15793
15794/*
15795 * Return from the translation cache to the interpreter.
15796 * The return was done with a BLX from thumb mode, and
15797 * the following 32-bit word contains the target rPC value.
15798 * Note that lr (r14) will have its low-order bit set to denote
15799 * its thumb-mode origin.
15800 *
15801 * We'll need to stash our lr origin away, recover the new
15802 * target and then check to see if there is a translation available
15803 * for our new target.  If so, we do a translation chain and
15804 * go back to native execution.  Otherwise, it's back to the
15805 * interpreter (after treating this entry as a potential
15806 * trace start).
15807 */
15808    .global dvmJitToInterpNormal
15809dvmJitToInterpNormal:
15810    ldr    rPC,[lr, #-1]           @ get our target PC
15811    add    rINST,lr,#-5            @ save start of chain branch
15812    add    rINST,#-4               @ .. which is 9 bytes back
15813#if defined(WITH_JIT_TUNING)
15814    bl     dvmBumpNormal
15815#endif
15816    mov    r0,rPC
15817    mov    r1,rSELF
15818    bl     dvmJitGetTraceAddrThread @ (pc, self)
15819    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
15820    cmp    r0,#0
15821    beq    toInterpreter            @ go if not, otherwise do chain
15822    mov    r1,rINST
15823    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
15824    mov    r1, rPC                  @ arg1 of translation may need this
15825    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
15826    cmp    r0,#0                    @ successful chain?
15827    bxne   r0                       @ continue native execution
15828    b      toInterpreter            @ didn't chain - resume with interpreter
15829
15830/*
15831 * Return from the translation cache to the interpreter to do method invocation.
15832 * Check if translation exists for the callee, but don't chain to it.
15833 */
15834    .global dvmJitToInterpNoChainNoProfile
15835dvmJitToInterpNoChainNoProfile:
15836#if defined(WITH_JIT_TUNING)
15837    bl     dvmBumpNoChain
15838#endif
15839    mov    r0,rPC
15840    mov    r1,rSELF
15841    bl     dvmJitGetTraceAddrThread @ (pc, self)
15842    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
15843    mov    r1, rPC                  @ arg1 of translation may need this
15844    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
15845    cmp    r0,#0
15846    bxne   r0                       @ continue native execution if so
15847    EXPORT_PC()
15848    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15849    FETCH_INST()
15850    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
15851    GOTO_OPCODE(ip)                     @ jump to next instruction
15852
15853/*
15854 * Return from the translation cache to the interpreter to do method invocation.
15855 * Check if translation exists for the callee, but don't chain to it.
15856 */
15857    .global dvmJitToInterpNoChain
15858dvmJitToInterpNoChain:
15859#if defined(WITH_JIT_TUNING)
15860    bl     dvmBumpNoChain
15861#endif
15862    mov    r0,rPC
15863    mov    r1,rSELF
15864    bl     dvmJitGetTraceAddrThread @ (pc, self)
15865    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
15866    mov    r1, rPC                  @ arg1 of translation may need this
15867    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
15868    cmp    r0,#0
15869    bxne   r0                       @ continue native execution if so
15870#endif
15871
15872/*
15873 * No translation, restore interpreter regs and start interpreting.
15874 * rSELF & rFP were preserved in the translated code, and rPC has
15875 * already been restored by the time we get here.  We'll need to set
15876 * up rIBASE & rINST, and load the address of the JitTable into r0.
15877 */
15878toInterpreter:
15879    EXPORT_PC()
15880    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15881    FETCH_INST()
15882    ldr    r0, [rSELF, #offThread_pJitProfTable]
15883    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15884    @ NOTE: intended fallthrough
15885
15886/*
15887 * Similar to common_updateProfile, but tests for null pJitProfTable
15888 * r0 holds pJifProfTAble, rINST is loaded, rPC is current and
15889 * rIBASE has been recently refreshed.
15890 */
15891common_testUpdateProfile:
15892    cmp     r0, #0               @ JIT switched off?
15893    beq     4f                   @ return to interp if so
15894
15895/*
15896 * Common code to update potential trace start counter, and initiate
15897 * a trace-build if appropriate.
15898 * On entry here:
15899 *    r0    <= pJitProfTable (verified non-NULL)
15900 *    rPC   <= Dalvik PC
15901 *    rINST <= next instruction
15902 */
15903common_updateProfile:
15904    eor     r3,rPC,rPC,lsr #12 @ cheap, but fast hash function
15905    lsl     r3,r3,#(32 - JIT_PROF_SIZE_LOG_2)          @ shift out excess bits
15906    ldrb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter
15907    GET_INST_OPCODE(ip)
15908    subs    r1,r1,#1           @ decrement counter
15909    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it
15910    GOTO_OPCODE_IFNE(ip)       @ if not threshold, fallthrough otherwise */
15911
15912    /* Looks good, reset the counter */
15913    ldr     r1, [rSELF, #offThread_jitThreshold]
15914    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter
15915    EXPORT_PC()
15916    mov     r0,rPC
15917    mov     r1,rSELF
15918    bl      dvmJitGetTraceAddrThread    @ (pc, self)
15919    str     r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
15920    mov     r1, rPC                     @ arg1 of translation may need this
15921    mov     lr, #0                      @  in case target is HANDLER_INTERPRET
15922    cmp     r0,#0
15923#if !defined(WITH_SELF_VERIFICATION)
15924    bxne    r0                          @ jump to the translation
15925    mov     r2,#kJitTSelectRequest      @ ask for trace selection
15926    @ fall-through to common_selectTrace
15927#else
15928    moveq   r2,#kJitTSelectRequest      @ ask for trace selection
15929    beq     common_selectTrace
15930    /*
15931     * At this point, we have a target translation.  However, if
15932     * that translation is actually the interpret-only pseudo-translation
15933     * we want to treat it the same as no translation.
15934     */
15935    mov     r10, r0                     @ save target
15936    bl      dvmCompilerGetInterpretTemplate
15937    cmp     r0, r10                     @ special case?
15938    bne     jitSVShadowRunStart         @ set up self verification shadow space
15939    @ Need to clear the inJitCodeCache flag
15940    mov    r3, #0                       @ 0 means not in the JIT code cache
15941    str    r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land
15942    GET_INST_OPCODE(ip)
15943    GOTO_OPCODE(ip)
15944    /* no return */
15945#endif
15946
15947/*
15948 * On entry:
15949 *  r2 is jit state.
15950 */
15951common_selectTrace:
15952    ldrh    r0,[rSELF,#offThread_subMode]
15953    ands    r0, #(kSubModeJitTraceBuild | kSubModeJitSV)
15954    bne     3f                         @ already doing JIT work, continue
15955    str     r2,[rSELF,#offThread_jitState]
15956    mov     r0, rSELF
15957/*
15958 * Call out to validate trace-building request.  If successful,
15959 * rIBASE will be swapped to to send us into single-stepping trace
15960 * building mode, so we need to refresh before we continue.
15961 */
15962    EXPORT_PC()
15963    SAVE_PC_FP_TO_SELF()                 @ copy of pc/fp to Thread
15964    bl      dvmJitCheckTraceRequest
159653:
15966    FETCH_INST()
15967    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
159684:
15969    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
15970    GOTO_OPCODE(ip)
15971    /* no return */
15972#endif
15973
15974#if defined(WITH_SELF_VERIFICATION)
15975/*
15976 * Save PC and registers to shadow memory for self verification mode
15977 * before jumping to native translation.
15978 * On entry:
15979 *    rPC, rFP, rSELF: the values that they should contain
15980 *    r10: the address of the target translation.
15981 */
15982jitSVShadowRunStart:
15983    mov     r0,rPC                      @ r0<- program counter
15984    mov     r1,rFP                      @ r1<- frame pointer
15985    mov     r2,rSELF                    @ r2<- self (Thread) pointer
15986    mov     r3,r10                      @ r3<- target translation
15987    bl      dvmSelfVerificationSaveState @ save registers to shadow space
15988    ldr     rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space
15989    bx      r10                         @ jump to the translation
15990
15991/*
15992 * Restore PC, registers, and interpreter state to original values
15993 * before jumping back to the interpreter.
15994 * On entry:
15995 *   r0:  dPC
15996 *   r2:  self verification state
15997 */
15998jitSVShadowRunEnd:
15999    mov    r1,rFP                        @ pass ending fp
16000    mov    r3,rSELF                      @ pass self ptr for convenience
16001    bl     dvmSelfVerificationRestoreState @ restore pc and fp values
16002    LOAD_PC_FP_FROM_SELF()               @ restore pc, fp
16003    ldr    r1,[r0,#offShadowSpace_svState] @ get self verification state
16004    cmp    r1,#0                         @ check for punt condition
16005    beq    1f
16006    @ Set up SV single-stepping
16007    mov    r0, rSELF
16008    mov    r1, #kSubModeJitSV
16009    bl     dvmEnableSubMode              @ (self, subMode)
16010    mov    r2,#kJitSelfVerification      @ ask for self verification
16011    str    r2,[rSELF,#offThread_jitState]
16012    @ intentional fallthrough
160131:                                       @ exit to interpreter without check
16014    EXPORT_PC()
16015    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
16016    FETCH_INST()
16017    GET_INST_OPCODE(ip)
16018    GOTO_OPCODE(ip)
16019#endif
16020
16021/*
16022 * The equivalent of "goto bail", this calls through the "bail handler".
16023 * It will end this interpreter activation, and return to the caller
16024 * of dvmMterpStdRun.
16025 *
16026 * State registers will be saved to the "thread" area before bailing
16027 * debugging purposes
16028 */
16029common_gotoBail:
16030    SAVE_PC_FP_TO_SELF()                @ export state to "thread"
16031    mov     r0, rSELF                   @ r0<- self ptr
16032    b       dvmMterpStdBail             @ call(self, changeInterp)
16033
16034/*
16035 * The JIT's invoke method needs to remember the callsite class and
16036 * target pair.  Save them here so that they are available to
16037 * dvmCheckJit following the interpretation of this invoke.
16038 */
16039#if defined(WITH_JIT)
16040save_callsiteinfo:
16041    cmp     r9, #0
16042    ldrne   r9, [r9, #offObject_clazz]
16043    str     r0, [rSELF, #offThread_methodToCall]
16044    str     r9, [rSELF, #offThread_callsiteClass]
16045    bx      lr
16046#endif
16047
16048/*
16049 * Common code for method invocation with range.
16050 *
16051 * On entry:
16052 *  r0 is "Method* methodToCall", r9 is "this"
16053 */
16054common_invokeMethodRange:
16055.LinvokeNewRange:
16056#if defined(WITH_JIT)
16057    ldrh    r1, [rSELF, #offThread_subMode]
16058    ands    r1, #kSubModeJitTraceBuild
16059    blne    save_callsiteinfo
16060#endif
16061    @ prepare to copy args to "outs" area of current frame
16062    movs    r2, rINST, lsr #8           @ r2<- AA (arg count) -- test for zero
16063    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
16064    beq     .LinvokeArgsDone            @ if no args, skip the rest
16065    FETCH(r1, 2)                        @ r1<- CCCC
16066
16067.LinvokeRangeArgs:
16068    @ r0=methodToCall, r1=CCCC, r2=count, r10=outs
16069    @ (very few methods have > 10 args; could unroll for common cases)
16070    add     r3, rFP, r1, lsl #2         @ r3<- &fp[CCCC]
16071    sub     r10, r10, r2, lsl #2        @ r10<- "outs" area, for call args
160721:  ldr     r1, [r3], #4                @ val = *fp++
16073    subs    r2, r2, #1                  @ count--
16074    str     r1, [r10], #4               @ *outs++ = val
16075    bne     1b                          @ ...while count != 0
16076    b       .LinvokeArgsDone
16077
16078/*
16079 * Common code for method invocation without range.
16080 *
16081 * On entry:
16082 *  r0 is "Method* methodToCall", r9 is "this"
16083 */
16084common_invokeMethodNoRange:
16085.LinvokeNewNoRange:
16086#if defined(WITH_JIT)
16087    ldrh    r1, [rSELF, #offThread_subMode]
16088    ands    r1, #kSubModeJitTraceBuild
16089    blne    save_callsiteinfo
16090#endif
16091    @ prepare to copy args to "outs" area of current frame
16092    movs    r2, rINST, lsr #12          @ r2<- B (arg count) -- test for zero
16093    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
16094    FETCH(r1, 2)                        @ r1<- GFED (load here to hide latency)
16095    beq     .LinvokeArgsDone
16096
16097    @ r0=methodToCall, r1=GFED, r2=count, r10=outs
16098.LinvokeNonRange:
16099    rsb     r2, r2, #5                  @ r2<- 5-r2
16100    add     pc, pc, r2, lsl #4          @ computed goto, 4 instrs each
16101    bl      common_abort                @ (skipped due to ARM prefetch)
161025:  and     ip, rINST, #0x0f00          @ isolate A
16103    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vA (shift right 8, left 2)
16104    mov     r0, r0                      @ nop
16105    str     r2, [r10, #-4]!             @ *--outs = vA
161064:  and     ip, r1, #0xf000             @ isolate G
16107    ldr     r2, [rFP, ip, lsr #10]      @ r2<- vG (shift right 12, left 2)
16108    mov     r0, r0                      @ nop
16109    str     r2, [r10, #-4]!             @ *--outs = vG
161103:  and     ip, r1, #0x0f00             @ isolate F
16111    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vF
16112    mov     r0, r0                      @ nop
16113    str     r2, [r10, #-4]!             @ *--outs = vF
161142:  and     ip, r1, #0x00f0             @ isolate E
16115    ldr     r2, [rFP, ip, lsr #2]       @ r2<- vE
16116    mov     r0, r0                      @ nop
16117    str     r2, [r10, #-4]!             @ *--outs = vE
161181:  and     ip, r1, #0x000f             @ isolate D
16119    ldr     r2, [rFP, ip, lsl #2]       @ r2<- vD
16120    mov     r0, r0                      @ nop
16121    str     r2, [r10, #-4]!             @ *--outs = vD
161220:  @ fall through to .LinvokeArgsDone
16123
16124.LinvokeArgsDone: @ r0=methodToCall
16125    ldrh    r9, [r0, #offMethod_registersSize]  @ r9<- methodToCall->regsSize
16126    ldrh    r3, [r0, #offMethod_outsSize]  @ r3<- methodToCall->outsSize
16127    ldr     r2, [r0, #offMethod_insns]  @ r2<- method->insns
16128    ldr     rINST, [r0, #offMethod_clazz]  @ rINST<- method->clazz
16129    @ find space for the new stack frame, check for overflow
16130    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- stack save area
16131    sub     r1, r1, r9, lsl #2          @ r1<- newFp (old savearea - regsSize)
16132    SAVEAREA_FROM_FP(r10, r1)           @ r10<- newSaveArea
16133@    bl      common_dumpRegs
16134    ldr     r9, [rSELF, #offThread_interpStackEnd]    @ r9<- interpStackEnd
16135    sub     r3, r10, r3, lsl #2         @ r3<- bottom (newsave - outsSize)
16136    cmp     r3, r9                      @ bottom < interpStackEnd?
16137    ldrh    lr, [rSELF, #offThread_subMode]
16138    ldr     r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags
16139    blo     .LstackOverflow             @ yes, this frame will overflow stack
16140
16141    @ set up newSaveArea
16142#ifdef EASY_GDB
16143    SAVEAREA_FROM_FP(ip, rFP)           @ ip<- stack save area
16144    str     ip, [r10, #offStackSaveArea_prevSave]
16145#endif
16146    str     rFP, [r10, #offStackSaveArea_prevFrame]
16147    str     rPC, [r10, #offStackSaveArea_savedPc]
16148#if defined(WITH_JIT)
16149    mov     r9, #0
16150    str     r9, [r10, #offStackSaveArea_returnAddr]
16151#endif
16152    str     r0, [r10, #offStackSaveArea_method]
16153
16154    @ Profiling?
16155    cmp     lr, #0                      @ any special modes happening?
16156    bne     2f                          @ go if so
161571:
16158    tst     r3, #ACC_NATIVE
16159    bne     .LinvokeNative
16160
16161    /*
16162    stmfd   sp!, {r0-r3}
16163    bl      common_printNewline
16164    mov     r0, rFP
16165    mov     r1, #0
16166    bl      dvmDumpFp
16167    ldmfd   sp!, {r0-r3}
16168    stmfd   sp!, {r0-r3}
16169    mov     r0, r1
16170    mov     r1, r10
16171    bl      dvmDumpFp
16172    bl      common_printNewline
16173    ldmfd   sp!, {r0-r3}
16174    */
16175
16176    ldrh    r9, [r2]                        @ r9 <- load INST from new PC
16177    ldr     r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
16178    mov     rPC, r2                         @ publish new rPC
16179
16180    @ Update state values for the new method
16181    @ r0=methodToCall, r1=newFp, r3=newMethodClass, r9=newINST
16182    str     r0, [rSELF, #offThread_method]    @ self->method = methodToCall
16183    str     r3, [rSELF, #offThread_methodClassDex] @ self->methodClassDex = ...
16184    mov     r2, #1
16185    str     r2, [rSELF, #offThread_debugIsMethodEntry]
16186#if defined(WITH_JIT)
16187    ldr     r0, [rSELF, #offThread_pJitProfTable]
16188    mov     rFP, r1                         @ fp = newFp
16189    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
16190    mov     rINST, r9                       @ publish new rINST
16191    str     r1, [rSELF, #offThread_curFrame]   @ curFrame = newFp
16192    cmp     r0,#0
16193    bne     common_updateProfile
16194    GOTO_OPCODE(ip)                         @ jump to next instruction
16195#else
16196    mov     rFP, r1                         @ fp = newFp
16197    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
16198    mov     rINST, r9                       @ publish new rINST
16199    str     r1, [rSELF, #offThread_curFrame]   @ curFrame = newFp
16200    GOTO_OPCODE(ip)                         @ jump to next instruction
16201#endif
16202
162032:
16204    @ Profiling - record method entry.  r0: methodToCall
16205    stmfd   sp!, {r0-r3}                @ preserve r0-r3
16206    str     rPC, [rSELF, #offThread_pc] @ update interpSave.pc
16207    mov     r1, r0
16208    mov     r0, rSELF
16209    bl      dvmReportInvoke             @ (self, method)
16210    ldmfd   sp!, {r0-r3}                @ restore r0-r3
16211    b       1b
16212
16213.LinvokeNative:
16214    @ Prep for the native call
16215    @ r0=methodToCall, r1=newFp, r10=newSaveArea
16216    ldrh    lr, [rSELF, #offThread_subMode]
16217    ldr     r9, [rSELF, #offThread_jniLocal_topCookie]@r9<-thread->localRef->...
16218    str     r1, [rSELF, #offThread_curFrame]   @ curFrame = newFp
16219    str     r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top
16220    mov     r2, r0                      @ r2<- methodToCall
16221    mov     r0, r1                      @ r0<- newFp (points to args)
16222    add     r1, rSELF, #offThread_retval  @ r1<- &retval
16223    mov     r3, rSELF                   @ arg3<- self
16224
16225#ifdef ASSIST_DEBUGGER
16226    /* insert fake function header to help gdb find the stack frame */
16227    b       .Lskip
16228    .type   dalvik_mterp, %function
16229dalvik_mterp:
16230    .fnstart
16231    MTERP_ENTRY1
16232    MTERP_ENTRY2
16233.Lskip:
16234#endif
16235
16236    cmp     lr, #0                      @ any special SubModes active?
16237    bne     11f                         @ go handle them if so
16238    mov     lr, pc                      @ set return addr
16239    ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
162407:
16241
16242    @ native return; r10=newSaveArea
16243    @ equivalent to dvmPopJniLocals
16244    ldr     r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top
16245    ldr     r1, [rSELF, #offThread_exception] @ check for exception
16246    str     rFP, [rSELF, #offThread_curFrame]  @ curFrame = fp
16247    cmp     r1, #0                      @ null?
16248    str     r0, [rSELF, #offThread_jniLocal_topCookie] @ new top <- old top
16249    bne     common_exceptionThrown      @ no, handle exception
16250
16251    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
16252    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
16253    GOTO_OPCODE(ip)                     @ jump to next instruction
16254
1625511:
16256    @ r0=newFp, r1=&retval, r2=methodToCall, r3=self, lr=subModes
16257    stmfd   sp!, {r0-r3}                @ save all but subModes
16258    mov     r0, r2                      @ r0<- methodToCall
16259    mov     r1, rSELF
16260    mov     r2, rFP
16261    bl      dvmReportPreNativeInvoke    @ (methodToCall, self, fp)
16262    ldmfd   sp, {r0-r3}                 @ refresh.  NOTE: no sp autoincrement
16263
16264    @ Call the native method
16265    mov     lr, pc                      @ set return addr
16266    ldr     pc, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
16267
16268    @ Restore the pre-call arguments
16269    ldmfd   sp!, {r0-r3}                @ r2<- methodToCall (others unneeded)
16270
16271    @ Finish up any post-invoke subMode requirements
16272    mov     r0, r2                      @ r0<- methodToCall
16273    mov     r1, rSELF
16274    mov     r2, rFP
16275    bl      dvmReportPostNativeInvoke   @ (methodToCall, self, fp)
16276    b       7b                          @ resume
16277
16278.LstackOverflow:    @ r0=methodToCall
16279    mov     r1, r0                      @ r1<- methodToCall
16280    mov     r0, rSELF                   @ r0<- self
16281    bl      dvmHandleStackOverflow
16282    b       common_exceptionThrown
16283#ifdef ASSIST_DEBUGGER
16284    .fnend
16285    .size   dalvik_mterp, .-dalvik_mterp
16286#endif
16287
16288
16289    /*
16290     * Common code for method invocation, calling through "glue code".
16291     *
16292     * TODO: now that we have range and non-range invoke handlers, this
16293     *       needs to be split into two.  Maybe just create entry points
16294     *       that set r9 and jump here?
16295     *
16296     * On entry:
16297     *  r0 is "Method* methodToCall", the method we're trying to call
16298     *  r9 is "bool methodCallRange", indicating if this is a /range variant
16299     */
16300     .if    0
16301.LinvokeOld:
16302    sub     sp, sp, #8                  @ space for args + pad
16303    FETCH(ip, 2)                        @ ip<- FEDC or CCCC
16304    mov     r2, r0                      @ A2<- methodToCall
16305    mov     r0, rSELF                   @ A0<- self
16306    SAVE_PC_FP_TO_SELF()                @ export state to "self"
16307    mov     r1, r9                      @ A1<- methodCallRange
16308    mov     r3, rINST, lsr #8           @ A3<- AA
16309    str     ip, [sp, #0]                @ A4<- ip
16310    bl      dvmMterp_invokeMethod       @ call the C invokeMethod
16311    add     sp, sp, #8                  @ remove arg area
16312    b       common_resumeAfterGlueCall  @ continue to next instruction
16313    .endif
16314
16315
16316
16317/*
16318 * Common code for handling a return instruction.
16319 *
16320 * This does not return.
16321 */
16322common_returnFromMethod:
16323.LreturnNew:
16324    ldrh    lr, [rSELF, #offThread_subMode]
16325    SAVEAREA_FROM_FP(r0, rFP)
16326    ldr     r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc
16327    cmp     lr, #0                      @ any special subMode handling needed?
16328    bne     19f
1632914:
16330    ldr     rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame
16331    ldr     r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)]
16332                                        @ r2<- method we're returning to
16333    cmp     r2, #0                      @ is this a break frame?
16334#if defined(WORKAROUND_CORTEX_A9_745320)
16335    /* Don't use conditional loads if the HW defect exists */
16336    beq     15f
16337    ldr     r10, [r2, #offMethod_clazz] @ r10<- method->clazz
1633815:
16339#else
16340    ldrne   r10, [r2, #offMethod_clazz] @ r10<- method->clazz
16341#endif
16342    beq     common_gotoBail             @ break frame, bail out completely
16343
16344    ldr     rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
16345    PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST
16346    str     r2, [rSELF, #offThread_method]@ self->method = newSave->method
16347    ldr     r1, [r10, #offClassObject_pDvmDex]   @ r1<- method->clazz->pDvmDex
16348    str     rFP, [rSELF, #offThread_curFrame]  @ curFrame = fp
16349#if defined(WITH_JIT)
16350    ldr     r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr
16351    mov     rPC, r9                     @ publish new rPC
16352    str     r1, [rSELF, #offThread_methodClassDex]
16353    str     r10, [rSELF, #offThread_inJitCodeCache]  @ may return to JIT'ed land
16354    cmp     r10, #0                      @ caller is compiled code
16355    blxne   r10
16356    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
16357    GOTO_OPCODE(ip)                     @ jump to next instruction
16358#else
16359    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
16360    mov     rPC, r9                     @ publish new rPC
16361    str     r1, [rSELF, #offThread_methodClassDex]
16362    GOTO_OPCODE(ip)                     @ jump to next instruction
16363#endif
16364
1636519:
16366    @ Handle special actions
16367    @ On entry, r0: StackSaveArea
16368    ldr     r1, [r0, #offStackSaveArea_prevFrame]  @ r2<- prevFP
16369    str     rPC, [rSELF, #offThread_pc] @ update interpSave.pc
16370    str     r1, [rSELF, #offThread_curFrame]   @ update interpSave.curFrame
16371    mov     r0, rSELF
16372    bl      dvmReportReturn             @ (self)
16373    SAVEAREA_FROM_FP(r0, rFP)           @ restore StackSaveArea
16374    b       14b                         @ continue
16375
16376    /*
16377     * Return handling, calls through "glue code".
16378     */
16379     .if    0
16380.LreturnOld:
16381    SAVE_PC_FP_TO_SELF()                @ export state
16382    mov     r0, rSELF                   @ arg to function
16383    bl      dvmMterp_returnFromMethod
16384    b       common_resumeAfterGlueCall
16385    .endif
16386
16387
16388/*
16389 * Somebody has thrown an exception.  Handle it.
16390 *
16391 * If the exception processing code returns to us (instead of falling
16392 * out of the interpreter), continue with whatever the next instruction
16393 * now happens to be.
16394 *
16395 * This does not return.
16396 */
16397     .global dvmMterpCommonExceptionThrown
16398dvmMterpCommonExceptionThrown:
16399common_exceptionThrown:
16400.LexceptionNew:
16401
16402    EXPORT_PC()
16403
16404    mov     r0, rSELF
16405    bl      dvmCheckSuspendPending
16406
16407    ldr     r9, [rSELF, #offThread_exception] @ r9<- self->exception
16408    mov     r1, rSELF                   @ r1<- self
16409    mov     r0, r9                      @ r0<- exception
16410    bl      dvmAddTrackedAlloc          @ don't let the exception be GCed
16411    ldrh    r2, [rSELF, #offThread_subMode]  @ get subMode flags
16412    mov     r3, #0                      @ r3<- NULL
16413    str     r3, [rSELF, #offThread_exception] @ self->exception = NULL
16414
16415    @ Special subMode?
16416    cmp     r2, #0                      @ any special subMode handling needed?
16417    bne     7f                          @ go if so
164188:
16419    /* set up args and a local for "&fp" */
16420    /* (str sp, [sp, #-4]!  would be perfect here, but is discouraged) */
16421    str     rFP, [sp, #-4]!             @ *--sp = fp
16422    mov     ip, sp                      @ ip<- &fp
16423    mov     r3, #0                      @ r3<- false
16424    str     ip, [sp, #-4]!              @ *--sp = &fp
16425    ldr     r1, [rSELF, #offThread_method] @ r1<- self->method
16426    mov     r0, rSELF                   @ r0<- self
16427    ldr     r1, [r1, #offMethod_insns]  @ r1<- method->insns
16428    ldrh    lr, [rSELF, #offThread_subMode]  @ lr<- subMode flags
16429    mov     r2, r9                      @ r2<- exception
16430    sub     r1, rPC, r1                 @ r1<- pc - method->insns
16431    mov     r1, r1, asr #1              @ r1<- offset in code units
16432
16433    /* call, r0 gets catchRelPc (a code-unit offset) */
16434    bl      dvmFindCatchBlock           @ call(self, relPc, exc, scan?, &fp)
16435
16436    /* fix earlier stack overflow if necessary; may trash rFP */
16437    ldrb    r1, [rSELF, #offThread_stackOverflowed]
16438    cmp     r1, #0                      @ did we overflow earlier?
16439    beq     1f                          @ no, skip ahead
16440    mov     rFP, r0                     @ save relPc result in rFP
16441    mov     r0, rSELF                   @ r0<- self
16442    mov     r1, r9                      @ r1<- exception
16443    bl      dvmCleanupStackOverflow     @ call(self)
16444    mov     r0, rFP                     @ restore result
164451:
16446
16447    /* update frame pointer and check result from dvmFindCatchBlock */
16448    ldr     rFP, [sp, #4]               @ retrieve the updated rFP
16449    cmp     r0, #0                      @ is catchRelPc < 0?
16450    add     sp, sp, #8                  @ restore stack
16451    bmi     .LnotCaughtLocally
16452
16453    /* adjust locals to match self->interpSave.curFrame and updated PC */
16454    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- new save area
16455    ldr     r1, [r1, #offStackSaveArea_method] @ r1<- new method
16456    str     r1, [rSELF, #offThread_method]  @ self->method = new method
16457    ldr     r2, [r1, #offMethod_clazz]      @ r2<- method->clazz
16458    ldr     r3, [r1, #offMethod_insns]      @ r3<- method->insns
16459    ldr     r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex
16460    add     rPC, r3, r0, asl #1             @ rPC<- method->insns + catchRelPc
16461    str     r2, [rSELF, #offThread_methodClassDex] @ self->pDvmDex = meth...
16462
16463    /* release the tracked alloc on the exception */
16464    mov     r0, r9                      @ r0<- exception
16465    mov     r1, rSELF                   @ r1<- self
16466    bl      dvmReleaseTrackedAlloc      @ release the exception
16467
16468    /* restore the exception if the handler wants it */
16469    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
16470    FETCH_INST()                        @ load rINST from rPC
16471    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
16472    cmp     ip, #OP_MOVE_EXCEPTION      @ is it "move-exception"?
16473    streq   r9, [rSELF, #offThread_exception] @ yes, restore the exception
16474    GOTO_OPCODE(ip)                     @ jump to next instruction
16475
16476    @ Manage debugger bookkeeping
164777:
16478    str     rPC, [rSELF, #offThread_pc]     @ update interpSave.pc
16479    str     rFP, [rSELF, #offThread_curFrame]     @ update interpSave.curFrame
16480    mov     r0, rSELF                       @ arg0<- self
16481    mov     r1, r9                          @ arg1<- exception
16482    bl      dvmReportExceptionThrow         @ (self, exception)
16483    b       8b                              @ resume with normal handling
16484
16485.LnotCaughtLocally: @ r9=exception
16486    /* fix stack overflow if necessary */
16487    ldrb    r1, [rSELF, #offThread_stackOverflowed]
16488    cmp     r1, #0                      @ did we overflow earlier?
16489    movne   r0, rSELF                   @ if yes: r0<- self
16490    movne   r1, r9                      @ if yes: r1<- exception
16491    blne    dvmCleanupStackOverflow     @ if yes: call(self)
16492
16493    @ may want to show "not caught locally" debug messages here
16494#if DVM_SHOW_EXCEPTION >= 2
16495    /* call __android_log_print(prio, tag, format, ...) */
16496    /* "Exception %s from %s:%d not caught locally" */
16497    @ dvmLineNumFromPC(method, pc - method->insns)
16498    ldr     r0, [rSELF, #offThread_method]
16499    ldr     r1, [r0, #offMethod_insns]
16500    sub     r1, rPC, r1
16501    asr     r1, r1, #1
16502    bl      dvmLineNumFromPC
16503    str     r0, [sp, #-4]!
16504    @ dvmGetMethodSourceFile(method)
16505    ldr     r0, [rSELF, #offThread_method]
16506    bl      dvmGetMethodSourceFile
16507    str     r0, [sp, #-4]!
16508    @ exception->clazz->descriptor
16509    ldr     r3, [r9, #offObject_clazz]
16510    ldr     r3, [r3, #offClassObject_descriptor]
16511    @
16512    ldr     r2, strExceptionNotCaughtLocally
16513    ldr     r1, strLogTag
16514    mov     r0, #3                      @ LOG_DEBUG
16515    bl      __android_log_print
16516#endif
16517    str     r9, [rSELF, #offThread_exception] @ restore exception
16518    mov     r0, r9                      @ r0<- exception
16519    mov     r1, rSELF                   @ r1<- self
16520    bl      dvmReleaseTrackedAlloc      @ release the exception
16521    b       common_gotoBail             @ bail out
16522
16523
16524    /*
16525     * Exception handling, calls through "glue code".
16526     */
16527    .if     0
16528.LexceptionOld:
16529    SAVE_PC_FP_TO_SELF()                @ export state
16530    mov     r0, rSELF                   @ arg to function
16531    bl      dvmMterp_exceptionThrown
16532    b       common_resumeAfterGlueCall
16533    .endif
16534
16535#if defined(WITH_JIT)
16536    /*
16537     * If the JIT is actively building a trace we need to make sure
16538     * that the field is fully resolved before including the current
16539     * instruction.
16540     *
16541     * On entry:
16542     *     r10: &dvmDex->pResFields[field]
16543     *     r0:  field pointer (must preserve)
16544     */
16545common_verifyField:
16546    ldrh    r3, [rSELF, #offThread_subMode]  @ r3 <- submode byte
16547    ands    r3, #kSubModeJitTraceBuild
16548    bxeq    lr                          @ Not building trace, continue
16549    ldr     r1, [r10]                   @ r1<- reload resolved StaticField ptr
16550    cmp     r1, #0                      @ resolution complete?
16551    bxne    lr                          @ yes, continue
16552    stmfd   sp!, {r0-r2,lr}             @ save regs
16553    mov     r0, rSELF
16554    mov     r1, rPC
16555    bl      dvmJitEndTraceSelect        @ (self,pc) end trace before this inst
16556    ldmfd   sp!, {r0-r2, lr}
16557    bx      lr                          @ return
16558#endif
16559
16560/*
16561 * After returning from a "glued" function, pull out the updated
16562 * values and start executing at the next instruction.
16563 */
16564common_resumeAfterGlueCall:
16565    LOAD_PC_FP_FROM_SELF()              @ pull rPC and rFP out of thread
16566    ldr     rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh
16567    FETCH_INST()                        @ load rINST from rPC
16568    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
16569    GOTO_OPCODE(ip)                     @ jump to next instruction
16570
16571/*
16572 * Invalid array index. Note that our calling convention is strange; we use r1
16573 * and r3 because those just happen to be the registers all our callers are
16574 * using. We move r3 before calling the C function, but r1 happens to match.
16575 * r1: index
16576 * r3: size
16577 */
16578common_errArrayIndex:
16579    EXPORT_PC()
16580    mov     r0, r3
16581    bl      dvmThrowArrayIndexOutOfBoundsException
16582    b       common_exceptionThrown
16583
16584/*
16585 * Integer divide or mod by zero.
16586 */
16587common_errDivideByZero:
16588    EXPORT_PC()
16589    ldr     r0, strDivideByZero
16590    bl      dvmThrowArithmeticException
16591    b       common_exceptionThrown
16592
16593/*
16594 * Attempt to allocate an array with a negative size.
16595 * On entry: length in r1
16596 */
16597common_errNegativeArraySize:
16598    EXPORT_PC()
16599    mov     r0, r1                                @ arg0 <- len
16600    bl      dvmThrowNegativeArraySizeException    @ (len)
16601    b       common_exceptionThrown
16602
16603/*
16604 * Invocation of a non-existent method.
16605 * On entry: method name in r1
16606 */
16607common_errNoSuchMethod:
16608    EXPORT_PC()
16609    mov     r0, r1
16610    bl      dvmThrowNoSuchMethodError
16611    b       common_exceptionThrown
16612
16613/*
16614 * We encountered a null object when we weren't expecting one.  We
16615 * export the PC, throw a NullPointerException, and goto the exception
16616 * processing code.
16617 */
16618common_errNullObject:
16619    EXPORT_PC()
16620    mov     r0, #0
16621    bl      dvmThrowNullPointerException
16622    b       common_exceptionThrown
16623
16624/*
16625 * For debugging, cause an immediate fault.  The source address will
16626 * be in lr (use a bl instruction to jump here).
16627 */
16628common_abort:
16629    ldr     pc, .LdeadFood
16630.LdeadFood:
16631    .word   0xdeadf00d
16632
16633/*
16634 * Spit out a "we were here", preserving all registers.  (The attempt
16635 * to save ip won't work, but we need to save an even number of
16636 * registers for EABI 64-bit stack alignment.)
16637 */
16638    .macro  SQUEAK num
16639common_squeak\num:
16640    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
16641    ldr     r0, strSqueak
16642    mov     r1, #\num
16643    bl      printf
16644    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
16645    bx      lr
16646    .endm
16647
16648    SQUEAK  0
16649    SQUEAK  1
16650    SQUEAK  2
16651    SQUEAK  3
16652    SQUEAK  4
16653    SQUEAK  5
16654
16655/*
16656 * Spit out the number in r0, preserving registers.
16657 */
16658common_printNum:
16659    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
16660    mov     r1, r0
16661    ldr     r0, strSqueak
16662    bl      printf
16663    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
16664    bx      lr
16665
16666/*
16667 * Print a newline, preserving registers.
16668 */
16669common_printNewline:
16670    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
16671    ldr     r0, strNewline
16672    bl      printf
16673    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
16674    bx      lr
16675
16676    /*
16677     * Print the 32-bit quantity in r0 as a hex value, preserving registers.
16678     */
16679common_printHex:
16680    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
16681    mov     r1, r0
16682    ldr     r0, strPrintHex
16683    bl      printf
16684    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
16685    bx      lr
16686
16687/*
16688 * Print the 64-bit quantity in r0-r1, preserving registers.
16689 */
16690common_printLong:
16691    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
16692    mov     r3, r1
16693    mov     r2, r0
16694    ldr     r0, strPrintLong
16695    bl      printf
16696    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
16697    bx      lr
16698
16699/*
16700 * Print full method info.  Pass the Method* in r0.  Preserves regs.
16701 */
16702common_printMethod:
16703    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
16704    bl      dvmMterpPrintMethod
16705    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
16706    bx      lr
16707
16708/*
16709 * Call a C helper function that dumps regs and possibly some
16710 * additional info.  Requires the C function to be compiled in.
16711 */
16712    .if     0
16713common_dumpRegs:
16714    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
16715    bl      dvmMterpDumpArmRegs
16716    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
16717    bx      lr
16718    .endif
16719
16720#if 0
16721/*
16722 * Experiment on VFP mode.
16723 *
16724 * uint32_t setFPSCR(uint32_t val, uint32_t mask)
16725 *
16726 * Updates the bits specified by "mask", setting them to the values in "val".
16727 */
16728setFPSCR:
16729    and     r0, r0, r1                  @ make sure no stray bits are set
16730    fmrx    r2, fpscr                   @ get VFP reg
16731    mvn     r1, r1                      @ bit-invert mask
16732    and     r2, r2, r1                  @ clear masked bits
16733    orr     r2, r2, r0                  @ set specified bits
16734    fmxr    fpscr, r2                   @ set VFP reg
16735    mov     r0, r2                      @ return new value
16736    bx      lr
16737
16738    .align  2
16739    .global dvmConfigureFP
16740    .type   dvmConfigureFP, %function
16741dvmConfigureFP:
16742    stmfd   sp!, {ip, lr}
16743    /* 0x03000000 sets DN/FZ */
16744    /* 0x00009f00 clears the six exception enable flags */
16745    bl      common_squeak0
16746    mov     r0, #0x03000000             @ r0<- 0x03000000
16747    add     r1, r0, #0x9f00             @ r1<- 0x03009f00
16748    bl      setFPSCR
16749    ldmfd   sp!, {ip, pc}
16750#endif
16751
16752
16753/*
16754 * String references, must be close to the code that uses them.
16755 */
16756    .align  2
16757strDivideByZero:
16758    .word   .LstrDivideByZero
16759strLogTag:
16760    .word   .LstrLogTag
16761strExceptionNotCaughtLocally:
16762    .word   .LstrExceptionNotCaughtLocally
16763
16764strNewline:
16765    .word   .LstrNewline
16766strSqueak:
16767    .word   .LstrSqueak
16768strPrintHex:
16769    .word   .LstrPrintHex
16770strPrintLong:
16771    .word   .LstrPrintLong
16772
16773/*
16774 * Zero-terminated ASCII string data.
16775 *
16776 * On ARM we have two choices: do like gcc does, and LDR from a .word
16777 * with the address, or use an ADR pseudo-op to get the address
16778 * directly.  ADR saves 4 bytes and an indirection, but it's using a
16779 * PC-relative addressing mode and hence has a limited range, which
16780 * makes it not work well with mergeable string sections.
16781 */
16782    .section .rodata.str1.4,"aMS",%progbits,1
16783
16784.LstrBadEntryPoint:
16785    .asciz  "Bad entry point %d\n"
16786.LstrFilledNewArrayNotImpl:
16787    .asciz  "filled-new-array only implemented for objects and 'int'"
16788.LstrDivideByZero:
16789    .asciz  "divide by zero"
16790.LstrLogTag:
16791    .asciz  "mterp"
16792.LstrExceptionNotCaughtLocally:
16793    .asciz  "Exception %s from %s:%d not caught locally\n"
16794
16795.LstrNewline:
16796    .asciz  "\n"
16797.LstrSqueak:
16798    .asciz  "<%d>"
16799.LstrPrintHex:
16800    .asciz  "<%#x>"
16801.LstrPrintLong:
16802    .asciz  "<%lld>"
16803
16804