InterpAsm-armv5te.S revision 5dfcc78af479937ba8dafceefd9b1931a88dfaaf
1/*
2 * This file was generated automatically by gen-mterp.py for 'armv5te'.
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: armv5te/platform.S */
206/*
207 * ===========================================================================
208 *  CPU-version-specific defines
209 * ===========================================================================
210 */
211
212/*
213 * Macro for data memory barrier; not meaningful pre-ARMv6K.
214 */
215.macro  SMP_DMB
216.endm
217
218/*
219 * Macro for data memory barrier; not meaningful pre-ARMv6K.
220 */
221.macro  SMP_DMB_ST
222.endm
223
224/* File: armv5te/entry.S */
225/*
226 * Copyright (C) 2008 The Android Open Source Project
227 *
228 * Licensed under the Apache License, Version 2.0 (the "License");
229 * you may not use this file except in compliance with the License.
230 * You may obtain a copy of the License at
231 *
232 *      http://www.apache.org/licenses/LICENSE-2.0
233 *
234 * Unless required by applicable law or agreed to in writing, software
235 * distributed under the License is distributed on an "AS IS" BASIS,
236 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
237 * See the License for the specific language governing permissions and
238 * limitations under the License.
239 */
240/*
241 * Interpreter entry point.
242 */
243
244/*
245 * We don't have formal stack frames, so gdb scans upward in the code
246 * to find the start of the function (a label with the %function type),
247 * and then looks at the next few instructions to figure out what
248 * got pushed onto the stack.  From this it figures out how to restore
249 * the registers, including PC, for the previous stack frame.  If gdb
250 * sees a non-function label, it stops scanning, so either we need to
251 * have nothing but assembler-local labels between the entry point and
252 * the break, or we need to fake it out.
253 *
254 * When this is defined, we add some stuff to make gdb less confused.
255 */
256#define ASSIST_DEBUGGER 1
257
258    .text
259    .align  2
260    .global dvmMterpStdRun
261    .type   dvmMterpStdRun, %function
262
263/*
264 * On entry:
265 *  r0  Thread* self
266 *
267 * The return comes via a call to dvmMterpStdBail().
268 */
269dvmMterpStdRun:
270#define MTERP_ENTRY1 \
271    .save {r4-r10,fp,lr}; \
272    stmfd   sp!, {r4-r10,fp,lr}         @ save 9 regs
273#define MTERP_ENTRY2 \
274    .pad    #4; \
275    sub     sp, sp, #4                  @ align 64
276
277    .fnstart
278    MTERP_ENTRY1
279    MTERP_ENTRY2
280
281    /* save stack pointer, add magic word for debuggerd */
282    str     sp, [r0, #offThread_bailPtr]  @ save SP for eventual return
283
284    /* set up "named" registers, figure out entry point */
285    mov     rSELF, r0                   @ set rSELF
286    LOAD_PC_FP_FROM_SELF()              @ load rPC and rFP from "thread"
287    ldr     rIBASE, [rSELF, #offThread_curHandlerTable] @ set rIBASE
288
289#if defined(WITH_JIT)
290.LentryInstr:
291    /* Entry is always a possible trace start */
292    ldr     r0, [rSELF, #offThread_pJitProfTable]
293    FETCH_INST()
294    mov     r1, #0                      @ prepare the value for the new state
295    str     r1, [rSELF, #offThread_inJitCodeCache] @ back to the interp land
296    cmp     r0,#0                       @ is profiling disabled?
297#if !defined(WITH_SELF_VERIFICATION)
298    bne     common_updateProfile        @ profiling is enabled
299#else
300    ldr     r2, [rSELF, #offThread_shadowSpace] @ to find out the jit exit state
301    beq     1f                          @ profiling is disabled
302    ldr     r3, [r2, #offShadowSpace_jitExitState]  @ jit exit state
303    cmp     r3, #kSVSTraceSelect        @ hot trace following?
304    moveq   r2,#kJitTSelectRequestHot   @ ask for trace selection
305    beq     common_selectTrace          @ go build the trace
306    cmp     r3, #kSVSNoProfile          @ don't profile the next instruction?
307    beq     1f                          @ intrepret the next instruction
308    b       common_updateProfile        @ collect profiles
309#endif
3101:
311    GET_INST_OPCODE(ip)
312    GOTO_OPCODE(ip)
313#else
314    /* start executing the instruction at rPC */
315    FETCH_INST()                        @ load rINST from rPC
316    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
317    GOTO_OPCODE(ip)                     @ jump to next instruction
318#endif
319
320.Lbad_arg:
321    ldr     r0, strBadEntryPoint
3220:  add     r0, pc
323    @ r1 holds value of entryPoint
324    bl      printf
325    bl      dvmAbort
326    .fnend
327    .size   dvmMterpStdRun, .-dvmMterpStdRun
328
329strBadEntryPoint:
330    .word   PCREL_REF(.LstrBadEntryPoint,0b)
331
332    .global dvmMterpStdBail
333    .type   dvmMterpStdBail, %function
334
335/*
336 * Restore the stack pointer and PC from the save point established on entry.
337 * This is essentially the same as a longjmp, but should be cheaper.  The
338 * last instruction causes us to return to whoever called dvmMterpStdRun.
339 *
340 * We pushed some registers on the stack in dvmMterpStdRun, then saved
341 * SP and LR.  Here we restore SP, restore the registers, and then restore
342 * LR to PC.
343 *
344 * On entry:
345 *  r0  Thread* self
346 */
347dvmMterpStdBail:
348    ldr     sp, [r0, #offThread_bailPtr]    @ sp<- saved SP
349    add     sp, sp, #4                      @ un-align 64
350    ldmfd   sp!, {r4-r10,fp,pc}             @ restore 9 regs and return
351
352
353
354    .global dvmAsmInstructionStart
355    .type   dvmAsmInstructionStart, %function
356dvmAsmInstructionStart = .L_OP_NOP
357    .text
358
359/* ------------------------------ */
360    .balign 64
361.L_OP_NOP: /* 0x00 */
362/* File: armv5te/OP_NOP.S */
363    FETCH_ADVANCE_INST(1)               @ advance to next instr, load rINST
364    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
365    GOTO_OPCODE(ip)                     @ execute it
366
367#ifdef ASSIST_DEBUGGER
368    /* insert fake function header to help gdb find the stack frame */
369    .type   dalvik_inst, %function
370dalvik_inst:
371    .fnstart
372    MTERP_ENTRY1
373    MTERP_ENTRY2
374    .fnend
375#endif
376
377/* ------------------------------ */
378    .balign 64
379.L_OP_MOVE: /* 0x01 */
380/* File: armv5te/OP_MOVE.S */
381    /* for move, move-object, long-to-int */
382    /* op vA, vB */
383    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
384    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
385    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
386    GET_VREG(r2, r1)                    @ r2<- fp[B]
387    and     r0, r0, #15
388    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
389    SET_VREG(r2, r0)                    @ fp[A]<- r2
390    GOTO_OPCODE(ip)                     @ execute next instruction
391
392/* ------------------------------ */
393    .balign 64
394.L_OP_MOVE_FROM16: /* 0x02 */
395/* File: armv5te/OP_MOVE_FROM16.S */
396    /* for: move/from16, move-object/from16 */
397    /* op vAA, vBBBB */
398    FETCH(r1, 1)                        @ r1<- BBBB
399    mov     r0, rINST, lsr #8           @ r0<- AA
400    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
401    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
402    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
403    SET_VREG(r2, r0)                    @ fp[AA]<- r2
404    GOTO_OPCODE(ip)                     @ jump to next instruction
405
406/* ------------------------------ */
407    .balign 64
408.L_OP_MOVE_16: /* 0x03 */
409/* File: armv5te/OP_MOVE_16.S */
410    /* for: move/16, move-object/16 */
411    /* op vAAAA, vBBBB */
412    FETCH(r1, 2)                        @ r1<- BBBB
413    FETCH(r0, 1)                        @ r0<- AAAA
414    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
415    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
416    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
417    SET_VREG(r2, r0)                    @ fp[AAAA]<- r2
418    GOTO_OPCODE(ip)                     @ jump to next instruction
419
420/* ------------------------------ */
421    .balign 64
422.L_OP_MOVE_WIDE: /* 0x04 */
423/* File: armv5te/OP_MOVE_WIDE.S */
424    /* move-wide vA, vB */
425    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
426    mov     r2, rINST, lsr #8           @ r2<- A(+)
427    mov     r3, rINST, lsr #12          @ r3<- B
428    and     r2, r2, #15
429    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
430    add     r2, rFP, r2, lsl #2         @ r2<- &fp[A]
431    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[B]
432    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
433    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
434    stmia   r2, {r0-r1}                 @ fp[A]<- r0/r1
435    GOTO_OPCODE(ip)                     @ jump to next instruction
436
437/* ------------------------------ */
438    .balign 64
439.L_OP_MOVE_WIDE_FROM16: /* 0x05 */
440/* File: armv5te/OP_MOVE_WIDE_FROM16.S */
441    /* move-wide/from16 vAA, vBBBB */
442    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
443    FETCH(r3, 1)                        @ r3<- BBBB
444    mov     r2, rINST, lsr #8           @ r2<- AA
445    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BBBB]
446    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
447    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[BBBB]
448    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
449    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
450    stmia   r2, {r0-r1}                 @ fp[AA]<- r0/r1
451    GOTO_OPCODE(ip)                     @ jump to next instruction
452
453/* ------------------------------ */
454    .balign 64
455.L_OP_MOVE_WIDE_16: /* 0x06 */
456/* File: armv5te/OP_MOVE_WIDE_16.S */
457    /* move-wide/16 vAAAA, vBBBB */
458    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
459    FETCH(r3, 2)                        @ r3<- BBBB
460    FETCH(r2, 1)                        @ r2<- AAAA
461    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BBBB]
462    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AAAA]
463    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[BBBB]
464    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
465    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
466    stmia   r2, {r0-r1}                 @ fp[AAAA]<- r0/r1
467    GOTO_OPCODE(ip)                     @ jump to next instruction
468
469/* ------------------------------ */
470    .balign 64
471.L_OP_MOVE_OBJECT: /* 0x07 */
472/* File: armv5te/OP_MOVE_OBJECT.S */
473/* File: armv5te/OP_MOVE.S */
474    /* for move, move-object, long-to-int */
475    /* op vA, vB */
476    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
477    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
478    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
479    GET_VREG(r2, r1)                    @ r2<- fp[B]
480    and     r0, r0, #15
481    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
482    SET_VREG(r2, r0)                    @ fp[A]<- r2
483    GOTO_OPCODE(ip)                     @ execute next instruction
484
485
486/* ------------------------------ */
487    .balign 64
488.L_OP_MOVE_OBJECT_FROM16: /* 0x08 */
489/* File: armv5te/OP_MOVE_OBJECT_FROM16.S */
490/* File: armv5te/OP_MOVE_FROM16.S */
491    /* for: move/from16, move-object/from16 */
492    /* op vAA, vBBBB */
493    FETCH(r1, 1)                        @ r1<- BBBB
494    mov     r0, rINST, lsr #8           @ r0<- AA
495    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
496    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
497    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
498    SET_VREG(r2, r0)                    @ fp[AA]<- r2
499    GOTO_OPCODE(ip)                     @ jump to next instruction
500
501
502/* ------------------------------ */
503    .balign 64
504.L_OP_MOVE_OBJECT_16: /* 0x09 */
505/* File: armv5te/OP_MOVE_OBJECT_16.S */
506/* File: armv5te/OP_MOVE_16.S */
507    /* for: move/16, move-object/16 */
508    /* op vAAAA, vBBBB */
509    FETCH(r1, 2)                        @ r1<- BBBB
510    FETCH(r0, 1)                        @ r0<- AAAA
511    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
512    GET_VREG(r2, r1)                    @ r2<- fp[BBBB]
513    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
514    SET_VREG(r2, r0)                    @ fp[AAAA]<- r2
515    GOTO_OPCODE(ip)                     @ jump to next instruction
516
517
518/* ------------------------------ */
519    .balign 64
520.L_OP_MOVE_RESULT: /* 0x0a */
521/* File: armv5te/OP_MOVE_RESULT.S */
522    /* for: move-result, move-result-object */
523    /* op vAA */
524    mov     r2, rINST, lsr #8           @ r2<- AA
525    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
526    ldr     r0, [rSELF, #offThread_retval]    @ r0<- self->retval.i
527    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
528    SET_VREG(r0, r2)                    @ fp[AA]<- r0
529    GOTO_OPCODE(ip)                     @ jump to next instruction
530
531/* ------------------------------ */
532    .balign 64
533.L_OP_MOVE_RESULT_WIDE: /* 0x0b */
534/* File: armv5te/OP_MOVE_RESULT_WIDE.S */
535    /* move-result-wide vAA */
536    mov     r2, rINST, lsr #8           @ r2<- AA
537    add     r3, rSELF, #offThread_retval  @ r3<- &self->retval
538    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
539    ldmia   r3, {r0-r1}                 @ r0/r1<- retval.j
540    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
541    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
542    stmia   r2, {r0-r1}                 @ fp[AA]<- r0/r1
543    GOTO_OPCODE(ip)                     @ jump to next instruction
544
545/* ------------------------------ */
546    .balign 64
547.L_OP_MOVE_RESULT_OBJECT: /* 0x0c */
548/* File: armv5te/OP_MOVE_RESULT_OBJECT.S */
549/* File: armv5te/OP_MOVE_RESULT.S */
550    /* for: move-result, move-result-object */
551    /* op vAA */
552    mov     r2, rINST, lsr #8           @ r2<- AA
553    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
554    ldr     r0, [rSELF, #offThread_retval]    @ r0<- self->retval.i
555    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
556    SET_VREG(r0, r2)                    @ fp[AA]<- r0
557    GOTO_OPCODE(ip)                     @ jump to next instruction
558
559
560/* ------------------------------ */
561    .balign 64
562.L_OP_MOVE_EXCEPTION: /* 0x0d */
563/* File: armv5te/OP_MOVE_EXCEPTION.S */
564    /* move-exception vAA */
565    mov     r2, rINST, lsr #8           @ r2<- AA
566    ldr     r3, [rSELF, #offThread_exception]  @ r3<- dvmGetException bypass
567    mov     r1, #0                      @ r1<- 0
568    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
569    SET_VREG(r3, r2)                    @ fp[AA]<- exception obj
570    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
571    str     r1, [rSELF, #offThread_exception]  @ dvmClearException bypass
572    GOTO_OPCODE(ip)                     @ jump to next instruction
573
574/* ------------------------------ */
575    .balign 64
576.L_OP_RETURN_VOID: /* 0x0e */
577/* File: armv5te/OP_RETURN_VOID.S */
578    b       common_returnFromMethod
579
580/* ------------------------------ */
581    .balign 64
582.L_OP_RETURN: /* 0x0f */
583/* File: armv5te/OP_RETURN.S */
584    /*
585     * Return a 32-bit value.  Copies the return value into the "thread"
586     * structure, then jumps to the return handler.
587     *
588     * for: return, return-object
589     */
590    /* op vAA */
591    mov     r2, rINST, lsr #8           @ r2<- AA
592    GET_VREG(r0, r2)                    @ r0<- vAA
593    str     r0, [rSELF, #offThread_retval] @ retval.i <- vAA
594    b       common_returnFromMethod
595
596/* ------------------------------ */
597    .balign 64
598.L_OP_RETURN_WIDE: /* 0x10 */
599/* File: armv5te/OP_RETURN_WIDE.S */
600    /*
601     * Return a 64-bit value.  Copies the return value into the "thread"
602     * structure, then jumps to the return handler.
603     */
604    /* return-wide vAA */
605    mov     r2, rINST, lsr #8           @ r2<- AA
606    add     r2, rFP, r2, lsl #2         @ r2<- &fp[AA]
607    add     r3, rSELF, #offThread_retval  @ r3<- &self->retval
608    ldmia   r2, {r0-r1}                 @ r0/r1 <- vAA/vAA+1
609    stmia   r3, {r0-r1}                 @ retval<- r0/r1
610    b       common_returnFromMethod
611
612/* ------------------------------ */
613    .balign 64
614.L_OP_RETURN_OBJECT: /* 0x11 */
615/* File: armv5te/OP_RETURN_OBJECT.S */
616/* File: armv5te/OP_RETURN.S */
617    /*
618     * Return a 32-bit value.  Copies the return value into the "thread"
619     * structure, then jumps to the return handler.
620     *
621     * for: return, return-object
622     */
623    /* op vAA */
624    mov     r2, rINST, lsr #8           @ r2<- AA
625    GET_VREG(r0, r2)                    @ r0<- vAA
626    str     r0, [rSELF, #offThread_retval] @ retval.i <- vAA
627    b       common_returnFromMethod
628
629
630/* ------------------------------ */
631    .balign 64
632.L_OP_CONST_4: /* 0x12 */
633/* File: armv5te/OP_CONST_4.S */
634    /* const/4 vA, #+B */
635    mov     r1, rINST, lsl #16          @ r1<- Bxxx0000
636    mov     r0, rINST, lsr #8           @ r0<- A+
637    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
638    mov     r1, r1, asr #28             @ r1<- sssssssB (sign-extended)
639    and     r0, r0, #15
640    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
641    SET_VREG(r1, r0)                    @ fp[A]<- r1
642    GOTO_OPCODE(ip)                     @ execute next instruction
643
644/* ------------------------------ */
645    .balign 64
646.L_OP_CONST_16: /* 0x13 */
647/* File: armv5te/OP_CONST_16.S */
648    /* const/16 vAA, #+BBBB */
649    FETCH_S(r0, 1)                      @ r0<- ssssBBBB (sign-extended)
650    mov     r3, rINST, lsr #8           @ r3<- AA
651    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
652    SET_VREG(r0, r3)                    @ vAA<- r0
653    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
654    GOTO_OPCODE(ip)                     @ jump to next instruction
655
656/* ------------------------------ */
657    .balign 64
658.L_OP_CONST: /* 0x14 */
659/* File: armv5te/OP_CONST.S */
660    /* const vAA, #+BBBBbbbb */
661    mov     r3, rINST, lsr #8           @ r3<- AA
662    FETCH(r0, 1)                        @ r0<- bbbb (low)
663    FETCH(r1, 2)                        @ r1<- BBBB (high)
664    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
665    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
666    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
667    SET_VREG(r0, r3)                    @ vAA<- r0
668    GOTO_OPCODE(ip)                     @ jump to next instruction
669
670/* ------------------------------ */
671    .balign 64
672.L_OP_CONST_HIGH16: /* 0x15 */
673/* File: armv5te/OP_CONST_HIGH16.S */
674    /* const/high16 vAA, #+BBBB0000 */
675    FETCH(r0, 1)                        @ r0<- 0000BBBB (zero-extended)
676    mov     r3, rINST, lsr #8           @ r3<- AA
677    mov     r0, r0, lsl #16             @ r0<- BBBB0000
678    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
679    SET_VREG(r0, r3)                    @ vAA<- r0
680    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
681    GOTO_OPCODE(ip)                     @ jump to next instruction
682
683/* ------------------------------ */
684    .balign 64
685.L_OP_CONST_WIDE_16: /* 0x16 */
686/* File: armv5te/OP_CONST_WIDE_16.S */
687    /* const-wide/16 vAA, #+BBBB */
688    FETCH_S(r0, 1)                      @ r0<- ssssBBBB (sign-extended)
689    mov     r3, rINST, lsr #8           @ r3<- AA
690    mov     r1, r0, asr #31             @ r1<- ssssssss
691    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
692    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
693    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
694    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
695    GOTO_OPCODE(ip)                     @ jump to next instruction
696
697/* ------------------------------ */
698    .balign 64
699.L_OP_CONST_WIDE_32: /* 0x17 */
700/* File: armv5te/OP_CONST_WIDE_32.S */
701    /* const-wide/32 vAA, #+BBBBbbbb */
702    FETCH(r0, 1)                        @ r0<- 0000bbbb (low)
703    mov     r3, rINST, lsr #8           @ r3<- AA
704    FETCH_S(r2, 2)                      @ r2<- ssssBBBB (high)
705    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
706    orr     r0, r0, r2, lsl #16         @ r0<- BBBBbbbb
707    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
708    mov     r1, r0, asr #31             @ r1<- ssssssss
709    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
710    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
711    GOTO_OPCODE(ip)                     @ jump to next instruction
712
713/* ------------------------------ */
714    .balign 64
715.L_OP_CONST_WIDE: /* 0x18 */
716/* File: armv5te/OP_CONST_WIDE.S */
717    /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
718    FETCH(r0, 1)                        @ r0<- bbbb (low)
719    FETCH(r1, 2)                        @ r1<- BBBB (low middle)
720    FETCH(r2, 3)                        @ r2<- hhhh (high middle)
721    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb (low word)
722    FETCH(r3, 4)                        @ r3<- HHHH (high)
723    mov     r9, rINST, lsr #8           @ r9<- AA
724    orr     r1, r2, r3, lsl #16         @ r1<- HHHHhhhh (high word)
725    FETCH_ADVANCE_INST(5)               @ advance rPC, load rINST
726    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
727    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
728    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
729    GOTO_OPCODE(ip)                     @ jump to next instruction
730
731/* ------------------------------ */
732    .balign 64
733.L_OP_CONST_WIDE_HIGH16: /* 0x19 */
734/* File: armv5te/OP_CONST_WIDE_HIGH16.S */
735    /* const-wide/high16 vAA, #+BBBB000000000000 */
736    FETCH(r1, 1)                        @ r1<- 0000BBBB (zero-extended)
737    mov     r3, rINST, lsr #8           @ r3<- AA
738    mov     r0, #0                      @ r0<- 00000000
739    mov     r1, r1, lsl #16             @ r1<- BBBB0000
740    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
741    add     r3, rFP, r3, lsl #2         @ r3<- &fp[AA]
742    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
743    stmia   r3, {r0-r1}                 @ vAA<- r0/r1
744    GOTO_OPCODE(ip)                     @ jump to next instruction
745
746/* ------------------------------ */
747    .balign 64
748.L_OP_CONST_STRING: /* 0x1a */
749/* File: armv5te/OP_CONST_STRING.S */
750    /* const/string vAA, String@BBBB */
751    FETCH(r1, 1)                        @ r1<- BBBB
752    ldr     r2, [rSELF, #offThread_methodClassDex]  @ r2<- self->methodClassDex
753    mov     r9, rINST, lsr #8           @ r9<- AA
754    ldr     r2, [r2, #offDvmDex_pResStrings]   @ r2<- dvmDex->pResStrings
755    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResStrings[BBBB]
756    cmp     r0, #0                      @ not yet resolved?
757    beq     .LOP_CONST_STRING_resolve
758    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
759    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
760    SET_VREG(r0, r9)                    @ vAA<- r0
761    GOTO_OPCODE(ip)                     @ jump to next instruction
762
763/* ------------------------------ */
764    .balign 64
765.L_OP_CONST_STRING_JUMBO: /* 0x1b */
766/* File: armv5te/OP_CONST_STRING_JUMBO.S */
767    /* const/string vAA, String@BBBBBBBB */
768    FETCH(r0, 1)                        @ r0<- bbbb (low)
769    FETCH(r1, 2)                        @ r1<- BBBB (high)
770    ldr     r2, [rSELF, #offThread_methodClassDex]  @ r2<- self->methodClassDex
771    mov     r9, rINST, lsr #8           @ r9<- AA
772    ldr     r2, [r2, #offDvmDex_pResStrings]   @ r2<- dvmDex->pResStrings
773    orr     r1, r0, r1, lsl #16         @ r1<- BBBBbbbb
774    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResStrings[BBBB]
775    cmp     r0, #0
776    beq     .LOP_CONST_STRING_JUMBO_resolve
777    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
778    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
779    SET_VREG(r0, r9)                    @ vAA<- r0
780    GOTO_OPCODE(ip)                     @ jump to next instruction
781
782/* ------------------------------ */
783    .balign 64
784.L_OP_CONST_CLASS: /* 0x1c */
785/* File: armv5te/OP_CONST_CLASS.S */
786    /* const/class vAA, Class@BBBB */
787    FETCH(r1, 1)                        @ r1<- BBBB
788    ldr     r2, [rSELF, #offThread_methodClassDex]  @ r2<- self->methodClassDex
789    mov     r9, rINST, lsr #8           @ r9<- AA
790    ldr     r2, [r2, #offDvmDex_pResClasses]   @ r2<- dvmDex->pResClasses
791    ldr     r0, [r2, r1, lsl #2]        @ r0<- pResClasses[BBBB]
792    cmp     r0, #0                      @ not yet resolved?
793    beq     .LOP_CONST_CLASS_resolve
794    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
795    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
796    SET_VREG(r0, r9)                    @ vAA<- r0
797    GOTO_OPCODE(ip)                     @ jump to next instruction
798
799/* ------------------------------ */
800    .balign 64
801.L_OP_MONITOR_ENTER: /* 0x1d */
802/* File: armv5te/OP_MONITOR_ENTER.S */
803    /*
804     * Synchronize on an object.
805     */
806    /* monitor-enter vAA */
807    mov     r2, rINST, lsr #8           @ r2<- AA
808    GET_VREG(r1, r2)                    @ r1<- vAA (object)
809    mov     r0, rSELF                   @ r0<- self
810    cmp     r1, #0                      @ null object?
811    EXPORT_PC()                         @ need for precise GC
812    beq     common_errNullObject        @ null object, throw an exception
813    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
814    bl      dvmLockObject               @ call(self, obj)
815    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
816    GOTO_OPCODE(ip)                     @ jump to next instruction
817
818/* ------------------------------ */
819    .balign 64
820.L_OP_MONITOR_EXIT: /* 0x1e */
821/* File: armv5te/OP_MONITOR_EXIT.S */
822    /*
823     * Unlock an object.
824     *
825     * Exceptions that occur when unlocking a monitor need to appear as
826     * if they happened at the following instruction.  See the Dalvik
827     * instruction spec.
828     */
829    /* monitor-exit vAA */
830    mov     r2, rINST, lsr #8           @ r2<- AA
831    EXPORT_PC()                         @ before fetch: export the PC
832    GET_VREG(r1, r2)                    @ r1<- vAA (object)
833    cmp     r1, #0                      @ null object?
834    beq     1f                          @ yes
835    mov     r0, rSELF                   @ r0<- self
836    bl      dvmUnlockObject             @ r0<- success for unlock(self, obj)
837    cmp     r0, #0                      @ failed?
838    FETCH_ADVANCE_INST(1)               @ before throw: advance rPC, load rINST
839    beq     common_exceptionThrown      @ yes, exception is pending
840    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
841    GOTO_OPCODE(ip)                     @ jump to next instruction
8421:
843    FETCH_ADVANCE_INST(1)               @ advance before throw
844    b      common_errNullObject
845
846/* ------------------------------ */
847    .balign 64
848.L_OP_CHECK_CAST: /* 0x1f */
849/* File: armv5te/OP_CHECK_CAST.S */
850    /*
851     * Check to see if a cast from one class to another is allowed.
852     */
853    /* check-cast vAA, class@BBBB */
854    mov     r3, rINST, lsr #8           @ r3<- AA
855    FETCH(r2, 1)                        @ r2<- BBBB
856    GET_VREG(r9, r3)                    @ r9<- object
857    ldr     r0, [rSELF, #offThread_methodClassDex]    @ r0<- pDvmDex
858    cmp     r9, #0                      @ is object null?
859    ldr     r0, [r0, #offDvmDex_pResClasses]    @ r0<- pDvmDex->pResClasses
860    beq     .LOP_CHECK_CAST_okay            @ null obj, cast always succeeds
861    ldr     r1, [r0, r2, lsl #2]        @ r1<- resolved class
862    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
863    cmp     r1, #0                      @ have we resolved this before?
864    beq     .LOP_CHECK_CAST_resolve         @ not resolved, do it now
865.LOP_CHECK_CAST_resolved:
866    cmp     r0, r1                      @ same class (trivial success)?
867    bne     .LOP_CHECK_CAST_fullcheck       @ no, do full check
868.LOP_CHECK_CAST_okay:
869    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
870    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
871    GOTO_OPCODE(ip)                     @ jump to next instruction
872
873/* ------------------------------ */
874    .balign 64
875.L_OP_INSTANCE_OF: /* 0x20 */
876/* File: armv5te/OP_INSTANCE_OF.S */
877    /*
878     * Check to see if an object reference is an instance of a class.
879     *
880     * Most common situation is a non-null object, being compared against
881     * an already-resolved class.
882     */
883    /* instance-of vA, vB, class@CCCC */
884    mov     r3, rINST, lsr #12          @ r3<- B
885    mov     r9, rINST, lsr #8           @ r9<- A+
886    GET_VREG(r0, r3)                    @ r0<- vB (object)
887    and     r9, r9, #15                 @ r9<- A
888    cmp     r0, #0                      @ is object null?
889    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- pDvmDex
890    beq     .LOP_INSTANCE_OF_store           @ null obj, not an instance, store r0
891    FETCH(r3, 1)                        @ r3<- CCCC
892    ldr     r2, [r2, #offDvmDex_pResClasses]    @ r2<- pDvmDex->pResClasses
893    ldr     r1, [r2, r3, lsl #2]        @ r1<- resolved class
894    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
895    cmp     r1, #0                      @ have we resolved this before?
896    beq     .LOP_INSTANCE_OF_resolve         @ not resolved, do it now
897.LOP_INSTANCE_OF_resolved: @ r0=obj->clazz, r1=resolved class
898    cmp     r0, r1                      @ same class (trivial success)?
899    beq     .LOP_INSTANCE_OF_trivial         @ yes, trivial finish
900    b       .LOP_INSTANCE_OF_fullcheck       @ no, do full check
901
902/* ------------------------------ */
903    .balign 64
904.L_OP_ARRAY_LENGTH: /* 0x21 */
905/* File: armv5te/OP_ARRAY_LENGTH.S */
906    /*
907     * Return the length of an array.
908     */
909    mov     r1, rINST, lsr #12          @ r1<- B
910    mov     r2, rINST, lsr #8           @ r2<- A+
911    GET_VREG(r0, r1)                    @ r0<- vB (object ref)
912    and     r2, r2, #15                 @ r2<- A
913    cmp     r0, #0                      @ is object null?
914    beq     common_errNullObject        @ yup, fail
915    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
916    ldr     r3, [r0, #offArrayObject_length]    @ r3<- array length
917    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
918    SET_VREG(r3, r2)                    @ vB<- length
919    GOTO_OPCODE(ip)                     @ jump to next instruction
920
921/* ------------------------------ */
922    .balign 64
923.L_OP_NEW_INSTANCE: /* 0x22 */
924/* File: armv5te/OP_NEW_INSTANCE.S */
925    /*
926     * Create a new instance of a class.
927     */
928    /* new-instance vAA, class@BBBB */
929    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
930    FETCH(r1, 1)                        @ r1<- BBBB
931    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
932    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
933#if defined(WITH_JIT)
934    add     r10, r3, r1, lsl #2         @ r10<- &resolved_class
935#endif
936    EXPORT_PC()                         @ req'd for init, resolve, alloc
937    cmp     r0, #0                      @ already resolved?
938    beq     .LOP_NEW_INSTANCE_resolve         @ no, resolve it now
939.LOP_NEW_INSTANCE_resolved:   @ r0=class
940    ldrb    r1, [r0, #offClassObject_status]    @ r1<- ClassStatus enum
941    cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
942    bne     .LOP_NEW_INSTANCE_needinit        @ no, init class now
943.LOP_NEW_INSTANCE_initialized: @ r0=class
944    mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
945    bl      dvmAllocObject              @ r0<- new object
946    b       .LOP_NEW_INSTANCE_finish          @ continue
947
948/* ------------------------------ */
949    .balign 64
950.L_OP_NEW_ARRAY: /* 0x23 */
951/* File: armv5te/OP_NEW_ARRAY.S */
952    /*
953     * Allocate an array of objects, specified with the array class
954     * and a count.
955     *
956     * The verifier guarantees that this is an array class, so we don't
957     * check for it here.
958     */
959    /* new-array vA, vB, class@CCCC */
960    mov     r0, rINST, lsr #12          @ r0<- B
961    FETCH(r2, 1)                        @ r2<- CCCC
962    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
963    GET_VREG(r1, r0)                    @ r1<- vB (array length)
964    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
965    cmp     r1, #0                      @ check length
966    ldr     r0, [r3, r2, lsl #2]        @ r0<- resolved class
967    bmi     common_errNegativeArraySize @ negative length, bail - len in r1
968    cmp     r0, #0                      @ already resolved?
969    EXPORT_PC()                         @ req'd for resolve, alloc
970    bne     .LOP_NEW_ARRAY_finish          @ resolved, continue
971    b       .LOP_NEW_ARRAY_resolve         @ do resolve now
972
973/* ------------------------------ */
974    .balign 64
975.L_OP_FILLED_NEW_ARRAY: /* 0x24 */
976/* File: armv5te/OP_FILLED_NEW_ARRAY.S */
977    /*
978     * Create a new array with elements filled from registers.
979     *
980     * for: filled-new-array, filled-new-array/range
981     */
982    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
983    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
984    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
985    FETCH(r1, 1)                        @ r1<- BBBB
986    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
987    EXPORT_PC()                         @ need for resolve and alloc
988    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
989    mov     r10, rINST, lsr #8          @ r10<- AA or BA
990    cmp     r0, #0                      @ already resolved?
991    bne     .LOP_FILLED_NEW_ARRAY_continue        @ yes, continue on
9928:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
993    mov     r2, #0                      @ r2<- false
994    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
995    bl      dvmResolveClass             @ r0<- call(clazz, ref)
996    cmp     r0, #0                      @ got null?
997    beq     common_exceptionThrown      @ yes, handle exception
998    b       .LOP_FILLED_NEW_ARRAY_continue
999
1000/* ------------------------------ */
1001    .balign 64
1002.L_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
1003/* File: armv5te/OP_FILLED_NEW_ARRAY_RANGE.S */
1004/* File: armv5te/OP_FILLED_NEW_ARRAY.S */
1005    /*
1006     * Create a new array with elements filled from registers.
1007     *
1008     * for: filled-new-array, filled-new-array/range
1009     */
1010    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
1011    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
1012    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
1013    FETCH(r1, 1)                        @ r1<- BBBB
1014    ldr     r3, [r3, #offDvmDex_pResClasses]    @ r3<- pDvmDex->pResClasses
1015    EXPORT_PC()                         @ need for resolve and alloc
1016    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved class
1017    mov     r10, rINST, lsr #8          @ r10<- AA or BA
1018    cmp     r0, #0                      @ already resolved?
1019    bne     .LOP_FILLED_NEW_ARRAY_RANGE_continue        @ yes, continue on
10208:  ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
1021    mov     r2, #0                      @ r2<- false
1022    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
1023    bl      dvmResolveClass             @ r0<- call(clazz, ref)
1024    cmp     r0, #0                      @ got null?
1025    beq     common_exceptionThrown      @ yes, handle exception
1026    b       .LOP_FILLED_NEW_ARRAY_RANGE_continue
1027
1028
1029/* ------------------------------ */
1030    .balign 64
1031.L_OP_FILL_ARRAY_DATA: /* 0x26 */
1032/* File: armv5te/OP_FILL_ARRAY_DATA.S */
1033    /* fill-array-data vAA, +BBBBBBBB */
1034    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1035    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1036    mov     r3, rINST, lsr #8           @ r3<- AA
1037    orr     r1, r0, r1, lsl #16         @ r1<- BBBBbbbb
1038    GET_VREG(r0, r3)                    @ r0<- vAA (array object)
1039    add     r1, rPC, r1, lsl #1         @ r1<- PC + BBBBbbbb*2 (array data off.)
1040    EXPORT_PC();
1041    bl      dvmInterpHandleFillArrayData@ fill the array with predefined data
1042    cmp     r0, #0                      @ 0 means an exception is thrown
1043    beq     common_exceptionThrown      @ has exception
1044    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
1045    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1046    GOTO_OPCODE(ip)                     @ jump to next instruction
1047
1048/* ------------------------------ */
1049    .balign 64
1050.L_OP_THROW: /* 0x27 */
1051/* File: armv5te/OP_THROW.S */
1052    /*
1053     * Throw an exception object in the current thread.
1054     */
1055    /* throw vAA */
1056    mov     r2, rINST, lsr #8           @ r2<- AA
1057    GET_VREG(r1, r2)                    @ r1<- vAA (exception object)
1058    EXPORT_PC()                         @ exception handler can throw
1059    cmp     r1, #0                      @ null object?
1060    beq     common_errNullObject        @ yes, throw an NPE instead
1061    @ bypass dvmSetException, just store it
1062    str     r1, [rSELF, #offThread_exception]  @ thread->exception<- obj
1063    b       common_exceptionThrown
1064
1065/* ------------------------------ */
1066    .balign 64
1067.L_OP_GOTO: /* 0x28 */
1068/* File: armv5te/OP_GOTO.S */
1069    /*
1070     * Unconditional branch, 8-bit offset.
1071     *
1072     * The branch distance is a signed code-unit offset, which we need to
1073     * double to get a byte offset.
1074     */
1075    /* goto +AA */
1076    /* tuning: use sbfx for 6t2+ targets */
1077    mov     r0, rINST, lsl #16          @ r0<- AAxx0000
1078    movs    r1, r0, asr #24             @ r1<- ssssssAA (sign-extended)
1079    add     r2, r1, r1                  @ r2<- byte offset, set flags
1080       @ If backwards branch refresh rIBASE
1081    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1082    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1083#if defined(WITH_JIT)
1084    ldr     r0, [rSELF, #offThread_pJitProfTable]
1085    bmi     common_testUpdateProfile    @ (r0) check for trace hotness
1086#endif
1087    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1088    GOTO_OPCODE(ip)                     @ jump to next instruction
1089
1090/* ------------------------------ */
1091    .balign 64
1092.L_OP_GOTO_16: /* 0x29 */
1093/* File: armv5te/OP_GOTO_16.S */
1094    /*
1095     * Unconditional branch, 16-bit offset.
1096     *
1097     * The branch distance is a signed code-unit offset, which we need to
1098     * double to get a byte offset.
1099     */
1100    /* goto/16 +AAAA */
1101    FETCH_S(r0, 1)                      @ r0<- ssssAAAA (sign-extended)
1102    adds    r1, r0, r0                  @ r1<- byte offset, flags set
1103    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1104    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1105#if defined(WITH_JIT)
1106    ldr     r0, [rSELF, #offThread_pJitProfTable]
1107    bmi     common_testUpdateProfile    @ (r0) hot trace head?
1108#endif
1109    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1110    GOTO_OPCODE(ip)                     @ jump to next instruction
1111
1112/* ------------------------------ */
1113    .balign 64
1114.L_OP_GOTO_32: /* 0x2a */
1115/* File: armv5te/OP_GOTO_32.S */
1116    /*
1117     * Unconditional branch, 32-bit offset.
1118     *
1119     * The branch distance is a signed code-unit offset, which we need to
1120     * double to get a byte offset.
1121     *
1122     * Unlike most opcodes, this one is allowed to branch to itself, so
1123     * our "backward branch" test must be "<=0" instead of "<0".  Because
1124     * we need the V bit set, we'll use an adds to convert from Dalvik
1125     * offset to byte offset.
1126     */
1127    /* goto/32 +AAAAAAAA */
1128    FETCH(r0, 1)                        @ r0<- aaaa (lo)
1129    FETCH(r1, 2)                        @ r1<- AAAA (hi)
1130    orr     r0, r0, r1, lsl #16         @ r0<- AAAAaaaa
1131    adds    r1, r0, r0                  @ r1<- byte offset
1132#if defined(WITH_JIT)
1133    ldr     r0, [rSELF, #offThread_pJitProfTable]
1134    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1135    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1136    ble     common_testUpdateProfile    @ (r0) hot trace head?
1137#else
1138    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1139    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1140#endif
1141    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1142    GOTO_OPCODE(ip)                     @ jump to next instruction
1143
1144/* ------------------------------ */
1145    .balign 64
1146.L_OP_PACKED_SWITCH: /* 0x2b */
1147/* File: armv5te/OP_PACKED_SWITCH.S */
1148    /*
1149     * Handle a packed-switch or sparse-switch instruction.  In both cases
1150     * we decode it and hand it off to a helper function.
1151     *
1152     * We don't really expect backward branches in a switch statement, but
1153     * they're perfectly legal, so we check for them here.
1154     *
1155     * When the JIT is present, all targets are considered treated as
1156     * a potential trace heads regardless of branch direction.
1157     *
1158     * for: packed-switch, sparse-switch
1159     */
1160    /* op vAA, +BBBB */
1161    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1162    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1163    mov     r3, rINST, lsr #8           @ r3<- AA
1164    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
1165    GET_VREG(r1, r3)                    @ r1<- vAA
1166    add     r0, rPC, r0, lsl #1         @ r0<- PC + BBBBbbbb*2
1167    bl      dvmInterpHandlePackedSwitch                       @ r0<- code-unit branch offset
1168    adds    r1, r0, r0                  @ r1<- byte offset; clear V
1169#if defined(WITH_JIT)
1170    ldr     r0, [rSELF, #offThread_pJitProfTable]
1171    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1172    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1173    cmp     r0, #0
1174    bne     common_updateProfile
1175#else
1176    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1177    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1178#endif
1179    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1180    GOTO_OPCODE(ip)                     @ jump to next instruction
1181
1182/* ------------------------------ */
1183    .balign 64
1184.L_OP_SPARSE_SWITCH: /* 0x2c */
1185/* File: armv5te/OP_SPARSE_SWITCH.S */
1186/* File: armv5te/OP_PACKED_SWITCH.S */
1187    /*
1188     * Handle a packed-switch or sparse-switch instruction.  In both cases
1189     * we decode it and hand it off to a helper function.
1190     *
1191     * We don't really expect backward branches in a switch statement, but
1192     * they're perfectly legal, so we check for them here.
1193     *
1194     * When the JIT is present, all targets are considered treated as
1195     * a potential trace heads regardless of branch direction.
1196     *
1197     * for: packed-switch, sparse-switch
1198     */
1199    /* op vAA, +BBBB */
1200    FETCH(r0, 1)                        @ r0<- bbbb (lo)
1201    FETCH(r1, 2)                        @ r1<- BBBB (hi)
1202    mov     r3, rINST, lsr #8           @ r3<- AA
1203    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
1204    GET_VREG(r1, r3)                    @ r1<- vAA
1205    add     r0, rPC, r0, lsl #1         @ r0<- PC + BBBBbbbb*2
1206    bl      dvmInterpHandleSparseSwitch                       @ r0<- code-unit branch offset
1207    adds    r1, r0, r0                  @ r1<- byte offset; clear V
1208#if defined(WITH_JIT)
1209    ldr     r0, [rSELF, #offThread_pJitProfTable]
1210    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1211    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1212    cmp     r0, #0
1213    bne     common_updateProfile
1214#else
1215    ldrle   rIBASE, [rSELF, #offThread_curHandlerTable] @ refresh handler base
1216    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1217#endif
1218    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1219    GOTO_OPCODE(ip)                     @ jump to next instruction
1220
1221
1222/* ------------------------------ */
1223    .balign 64
1224.L_OP_CMPL_FLOAT: /* 0x2d */
1225/* File: armv5te/OP_CMPL_FLOAT.S */
1226    /*
1227     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1228     * destination register based on the results of the comparison.
1229     *
1230     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
1231     * on what value we'd like to return when one of the operands is NaN.
1232     *
1233     * The operation we're implementing is:
1234     *   if (x == y)
1235     *     return 0;
1236     *   else if (x < y)
1237     *     return -1;
1238     *   else if (x > y)
1239     *     return 1;
1240     *   else
1241     *     return {-1,1};  // one or both operands was NaN
1242     *
1243     * The straightforward implementation requires 3 calls to functions
1244     * that return a result in r0.  We can do it with two calls if our
1245     * EABI library supports __aeabi_cfcmple (only one if we want to check
1246     * for NaN directly):
1247     *   check x <= y
1248     *     if <, return -1
1249     *     if ==, return 0
1250     *   check y <= x
1251     *     if <, return 1
1252     *   return {-1,1}
1253     *
1254     * for: cmpl-float, cmpg-float
1255     */
1256    /* op vAA, vBB, vCC */
1257    FETCH(r0, 1)                        @ r0<- CCBB
1258    and     r2, r0, #255                @ r2<- BB
1259    mov     r3, r0, lsr #8              @ r3<- CC
1260    GET_VREG(r9, r2)                    @ r9<- vBB
1261    GET_VREG(r10, r3)                   @ r10<- vCC
1262    mov     r0, r9                      @ copy to arg registers
1263    mov     r1, r10
1264    bl      __aeabi_cfcmple             @ cmp <=: C clear if <, Z set if eq
1265    bhi     .LOP_CMPL_FLOAT_gt_or_nan       @ C set and Z clear, disambiguate
1266    mvncc   r1, #0                      @ (less than) r1<- -1
1267    moveq   r1, #0                      @ (equal) r1<- 0, trumps less than
1268.LOP_CMPL_FLOAT_finish:
1269    mov     r3, rINST, lsr #8           @ r3<- AA
1270    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1271    SET_VREG(r1, r3)                    @ vAA<- r1
1272    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1273    GOTO_OPCODE(ip)                     @ jump to next instruction
1274
1275/* ------------------------------ */
1276    .balign 64
1277.L_OP_CMPG_FLOAT: /* 0x2e */
1278/* File: armv5te/OP_CMPG_FLOAT.S */
1279/* File: armv5te/OP_CMPL_FLOAT.S */
1280    /*
1281     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1282     * destination register based on the results of the comparison.
1283     *
1284     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
1285     * on what value we'd like to return when one of the operands is NaN.
1286     *
1287     * The operation we're implementing is:
1288     *   if (x == y)
1289     *     return 0;
1290     *   else if (x < y)
1291     *     return -1;
1292     *   else if (x > y)
1293     *     return 1;
1294     *   else
1295     *     return {-1,1};  // one or both operands was NaN
1296     *
1297     * The straightforward implementation requires 3 calls to functions
1298     * that return a result in r0.  We can do it with two calls if our
1299     * EABI library supports __aeabi_cfcmple (only one if we want to check
1300     * for NaN directly):
1301     *   check x <= y
1302     *     if <, return -1
1303     *     if ==, return 0
1304     *   check y <= x
1305     *     if <, return 1
1306     *   return {-1,1}
1307     *
1308     * for: cmpl-float, cmpg-float
1309     */
1310    /* op vAA, vBB, vCC */
1311    FETCH(r0, 1)                        @ r0<- CCBB
1312    and     r2, r0, #255                @ r2<- BB
1313    mov     r3, r0, lsr #8              @ r3<- CC
1314    GET_VREG(r9, r2)                    @ r9<- vBB
1315    GET_VREG(r10, r3)                   @ r10<- vCC
1316    mov     r0, r9                      @ copy to arg registers
1317    mov     r1, r10
1318    bl      __aeabi_cfcmple             @ cmp <=: C clear if <, Z set if eq
1319    bhi     .LOP_CMPG_FLOAT_gt_or_nan       @ C set and Z clear, disambiguate
1320    mvncc   r1, #0                      @ (less than) r1<- -1
1321    moveq   r1, #0                      @ (equal) r1<- 0, trumps less than
1322.LOP_CMPG_FLOAT_finish:
1323    mov     r3, rINST, lsr #8           @ r3<- AA
1324    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1325    SET_VREG(r1, r3)                    @ vAA<- r1
1326    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1327    GOTO_OPCODE(ip)                     @ jump to next instruction
1328
1329
1330/* ------------------------------ */
1331    .balign 64
1332.L_OP_CMPL_DOUBLE: /* 0x2f */
1333/* File: armv5te/OP_CMPL_DOUBLE.S */
1334    /*
1335     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1336     * destination register based on the results of the comparison.
1337     *
1338     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
1339     * on what value we'd like to return when one of the operands is NaN.
1340     *
1341     * See OP_CMPL_FLOAT for an explanation.
1342     *
1343     * For: cmpl-double, cmpg-double
1344     */
1345    /* op vAA, vBB, vCC */
1346    FETCH(r0, 1)                        @ r0<- CCBB
1347    and     r9, r0, #255                @ r9<- BB
1348    mov     r10, r0, lsr #8             @ r10<- CC
1349    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BB]
1350    add     r10, rFP, r10, lsl #2       @ r10<- &fp[CC]
1351    ldmia   r9, {r0-r1}                 @ r0/r1<- vBB/vBB+1
1352    ldmia   r10, {r2-r3}                @ r2/r3<- vCC/vCC+1
1353    bl      __aeabi_cdcmple             @ cmp <=: C clear if <, Z set if eq
1354    bhi     .LOP_CMPL_DOUBLE_gt_or_nan       @ C set and Z clear, disambiguate
1355    mvncc   r1, #0                      @ (less than) r1<- -1
1356    moveq   r1, #0                      @ (equal) r1<- 0, trumps less than
1357.LOP_CMPL_DOUBLE_finish:
1358    mov     r3, rINST, lsr #8           @ r3<- AA
1359    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1360    SET_VREG(r1, r3)                    @ vAA<- r1
1361    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1362    GOTO_OPCODE(ip)                     @ jump to next instruction
1363
1364/* ------------------------------ */
1365    .balign 64
1366.L_OP_CMPG_DOUBLE: /* 0x30 */
1367/* File: armv5te/OP_CMPG_DOUBLE.S */
1368/* File: armv5te/OP_CMPL_DOUBLE.S */
1369    /*
1370     * Compare two floating-point values.  Puts 0, 1, or -1 into the
1371     * destination register based on the results of the comparison.
1372     *
1373     * Provide a "naninst" instruction that puts 1 or -1 into r1 depending
1374     * on what value we'd like to return when one of the operands is NaN.
1375     *
1376     * See OP_CMPL_FLOAT for an explanation.
1377     *
1378     * For: cmpl-double, cmpg-double
1379     */
1380    /* op vAA, vBB, vCC */
1381    FETCH(r0, 1)                        @ r0<- CCBB
1382    and     r9, r0, #255                @ r9<- BB
1383    mov     r10, r0, lsr #8             @ r10<- CC
1384    add     r9, rFP, r9, lsl #2         @ r9<- &fp[BB]
1385    add     r10, rFP, r10, lsl #2       @ r10<- &fp[CC]
1386    ldmia   r9, {r0-r1}                 @ r0/r1<- vBB/vBB+1
1387    ldmia   r10, {r2-r3}                @ r2/r3<- vCC/vCC+1
1388    bl      __aeabi_cdcmple             @ cmp <=: C clear if <, Z set if eq
1389    bhi     .LOP_CMPG_DOUBLE_gt_or_nan       @ C set and Z clear, disambiguate
1390    mvncc   r1, #0                      @ (less than) r1<- -1
1391    moveq   r1, #0                      @ (equal) r1<- 0, trumps less than
1392.LOP_CMPG_DOUBLE_finish:
1393    mov     r3, rINST, lsr #8           @ r3<- AA
1394    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1395    SET_VREG(r1, r3)                    @ vAA<- r1
1396    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1397    GOTO_OPCODE(ip)                     @ jump to next instruction
1398
1399
1400/* ------------------------------ */
1401    .balign 64
1402.L_OP_CMP_LONG: /* 0x31 */
1403/* File: armv5te/OP_CMP_LONG.S */
1404    /*
1405     * Compare two 64-bit values.  Puts 0, 1, or -1 into the destination
1406     * register based on the results of the comparison.
1407     *
1408     * We load the full values with LDM, but in practice many values could
1409     * be resolved by only looking at the high word.  This could be made
1410     * faster or slower by splitting the LDM into a pair of LDRs.
1411     *
1412     * If we just wanted to set condition flags, we could do this:
1413     *  subs    ip, r0, r2
1414     *  sbcs    ip, r1, r3
1415     *  subeqs  ip, r0, r2
1416     * Leaving { <0, 0, >0 } in ip.  However, we have to set it to a specific
1417     * integer value, which we can do with 2 conditional mov/mvn instructions
1418     * (set 1, set -1; if they're equal we already have 0 in ip), giving
1419     * us a constant 5-cycle path plus a branch at the end to the
1420     * instruction epilogue code.  The multi-compare approach below needs
1421     * 2 or 3 cycles + branch if the high word doesn't match, 6 + branch
1422     * in the worst case (the 64-bit values are equal).
1423     */
1424    /* cmp-long vAA, vBB, vCC */
1425    FETCH(r0, 1)                        @ r0<- CCBB
1426    mov     r9, rINST, lsr #8           @ r9<- AA
1427    and     r2, r0, #255                @ r2<- BB
1428    mov     r3, r0, lsr #8              @ r3<- CC
1429    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
1430    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
1431    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
1432    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
1433    cmp     r1, r3                      @ compare (vBB+1, vCC+1)
1434    blt     .LOP_CMP_LONG_less            @ signed compare on high part
1435    bgt     .LOP_CMP_LONG_greater
1436    subs    r1, r0, r2                  @ r1<- r0 - r2
1437    bhi     .LOP_CMP_LONG_greater         @ unsigned compare on low part
1438    bne     .LOP_CMP_LONG_less
1439    b       .LOP_CMP_LONG_finish          @ equal; r1 already holds 0
1440
1441/* ------------------------------ */
1442    .balign 64
1443.L_OP_IF_EQ: /* 0x32 */
1444/* File: armv5te/OP_IF_EQ.S */
1445/* File: armv5te/bincmp.S */
1446    /*
1447     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1448     * fragment that specifies the *reverse* comparison to perform, e.g.
1449     * for "if-le" you would use "gt".
1450     *
1451     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1452     */
1453    /* if-cmp vA, vB, +CCCC */
1454    mov     r0, rINST, lsr #8           @ r0<- A+
1455    mov     r1, rINST, lsr #12          @ r1<- B
1456    and     r0, r0, #15
1457    GET_VREG(r3, r1)                    @ r3<- vB
1458    GET_VREG(r2, r0)                    @ r2<- vA
1459    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1460    cmp     r2, r3                      @ compare (vA, vB)
1461    movne r1, #2                 @ r1<- BYTE branch dist for not-taken
1462    adds    r2, r1, r1                  @ convert to bytes, check sign
1463    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1464#if defined(WITH_JIT)
1465    ldr     r0, [rSELF, #offThread_pJitProfTable]
1466    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1467    cmp     r0,#0
1468    bne     common_updateProfile
1469#else
1470    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1471#endif
1472    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1473    GOTO_OPCODE(ip)                     @ jump to next instruction
1474
1475
1476/* ------------------------------ */
1477    .balign 64
1478.L_OP_IF_NE: /* 0x33 */
1479/* File: armv5te/OP_IF_NE.S */
1480/* File: armv5te/bincmp.S */
1481    /*
1482     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1483     * fragment that specifies the *reverse* comparison to perform, e.g.
1484     * for "if-le" you would use "gt".
1485     *
1486     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1487     */
1488    /* if-cmp vA, vB, +CCCC */
1489    mov     r0, rINST, lsr #8           @ r0<- A+
1490    mov     r1, rINST, lsr #12          @ r1<- B
1491    and     r0, r0, #15
1492    GET_VREG(r3, r1)                    @ r3<- vB
1493    GET_VREG(r2, r0)                    @ r2<- vA
1494    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1495    cmp     r2, r3                      @ compare (vA, vB)
1496    moveq r1, #2                 @ r1<- BYTE branch dist for not-taken
1497    adds    r2, r1, r1                  @ convert to bytes, check sign
1498    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1499#if defined(WITH_JIT)
1500    ldr     r0, [rSELF, #offThread_pJitProfTable]
1501    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1502    cmp     r0,#0
1503    bne     common_updateProfile
1504#else
1505    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1506#endif
1507    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1508    GOTO_OPCODE(ip)                     @ jump to next instruction
1509
1510
1511/* ------------------------------ */
1512    .balign 64
1513.L_OP_IF_LT: /* 0x34 */
1514/* File: armv5te/OP_IF_LT.S */
1515/* File: armv5te/bincmp.S */
1516    /*
1517     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1518     * fragment that specifies the *reverse* comparison to perform, e.g.
1519     * for "if-le" you would use "gt".
1520     *
1521     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1522     */
1523    /* if-cmp vA, vB, +CCCC */
1524    mov     r0, rINST, lsr #8           @ r0<- A+
1525    mov     r1, rINST, lsr #12          @ r1<- B
1526    and     r0, r0, #15
1527    GET_VREG(r3, r1)                    @ r3<- vB
1528    GET_VREG(r2, r0)                    @ r2<- vA
1529    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1530    cmp     r2, r3                      @ compare (vA, vB)
1531    movge r1, #2                 @ r1<- BYTE branch dist for not-taken
1532    adds    r2, r1, r1                  @ convert to bytes, check sign
1533    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1534#if defined(WITH_JIT)
1535    ldr     r0, [rSELF, #offThread_pJitProfTable]
1536    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1537    cmp     r0,#0
1538    bne     common_updateProfile
1539#else
1540    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1541#endif
1542    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1543    GOTO_OPCODE(ip)                     @ jump to next instruction
1544
1545
1546/* ------------------------------ */
1547    .balign 64
1548.L_OP_IF_GE: /* 0x35 */
1549/* File: armv5te/OP_IF_GE.S */
1550/* File: armv5te/bincmp.S */
1551    /*
1552     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1553     * fragment that specifies the *reverse* comparison to perform, e.g.
1554     * for "if-le" you would use "gt".
1555     *
1556     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1557     */
1558    /* if-cmp vA, vB, +CCCC */
1559    mov     r0, rINST, lsr #8           @ r0<- A+
1560    mov     r1, rINST, lsr #12          @ r1<- B
1561    and     r0, r0, #15
1562    GET_VREG(r3, r1)                    @ r3<- vB
1563    GET_VREG(r2, r0)                    @ r2<- vA
1564    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1565    cmp     r2, r3                      @ compare (vA, vB)
1566    movlt r1, #2                 @ r1<- BYTE branch dist for not-taken
1567    adds    r2, r1, r1                  @ convert to bytes, check sign
1568    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1569#if defined(WITH_JIT)
1570    ldr     r0, [rSELF, #offThread_pJitProfTable]
1571    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1572    cmp     r0,#0
1573    bne     common_updateProfile
1574#else
1575    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1576#endif
1577    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1578    GOTO_OPCODE(ip)                     @ jump to next instruction
1579
1580
1581/* ------------------------------ */
1582    .balign 64
1583.L_OP_IF_GT: /* 0x36 */
1584/* File: armv5te/OP_IF_GT.S */
1585/* File: armv5te/bincmp.S */
1586    /*
1587     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1588     * fragment that specifies the *reverse* comparison to perform, e.g.
1589     * for "if-le" you would use "gt".
1590     *
1591     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1592     */
1593    /* if-cmp vA, vB, +CCCC */
1594    mov     r0, rINST, lsr #8           @ r0<- A+
1595    mov     r1, rINST, lsr #12          @ r1<- B
1596    and     r0, r0, #15
1597    GET_VREG(r3, r1)                    @ r3<- vB
1598    GET_VREG(r2, r0)                    @ r2<- vA
1599    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1600    cmp     r2, r3                      @ compare (vA, vB)
1601    movle r1, #2                 @ r1<- BYTE branch dist for not-taken
1602    adds    r2, r1, r1                  @ convert to bytes, check sign
1603    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1604#if defined(WITH_JIT)
1605    ldr     r0, [rSELF, #offThread_pJitProfTable]
1606    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1607    cmp     r0,#0
1608    bne     common_updateProfile
1609#else
1610    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1611#endif
1612    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1613    GOTO_OPCODE(ip)                     @ jump to next instruction
1614
1615
1616/* ------------------------------ */
1617    .balign 64
1618.L_OP_IF_LE: /* 0x37 */
1619/* File: armv5te/OP_IF_LE.S */
1620/* File: armv5te/bincmp.S */
1621    /*
1622     * Generic two-operand compare-and-branch operation.  Provide a "revcmp"
1623     * fragment that specifies the *reverse* comparison to perform, e.g.
1624     * for "if-le" you would use "gt".
1625     *
1626     * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le
1627     */
1628    /* if-cmp vA, vB, +CCCC */
1629    mov     r0, rINST, lsr #8           @ r0<- A+
1630    mov     r1, rINST, lsr #12          @ r1<- B
1631    and     r0, r0, #15
1632    GET_VREG(r3, r1)                    @ r3<- vB
1633    GET_VREG(r2, r0)                    @ r2<- vA
1634    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1635    cmp     r2, r3                      @ compare (vA, vB)
1636    movgt r1, #2                 @ r1<- BYTE branch dist for not-taken
1637    adds    r2, r1, r1                  @ convert to bytes, check sign
1638    FETCH_ADVANCE_INST_RB(r2)           @ update rPC, load rINST
1639#if defined(WITH_JIT)
1640    ldr     r0, [rSELF, #offThread_pJitProfTable]
1641    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1642    cmp     r0,#0
1643    bne     common_updateProfile
1644#else
1645    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
1646#endif
1647    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1648    GOTO_OPCODE(ip)                     @ jump to next instruction
1649
1650
1651/* ------------------------------ */
1652    .balign 64
1653.L_OP_IF_EQZ: /* 0x38 */
1654/* File: armv5te/OP_IF_EQZ.S */
1655/* File: armv5te/zcmp.S */
1656    /*
1657     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1658     * fragment that specifies the *reverse* comparison to perform, e.g.
1659     * for "if-le" you would use "gt".
1660     *
1661     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1662     */
1663    /* if-cmp vAA, +BBBB */
1664    mov     r0, rINST, lsr #8           @ r0<- AA
1665    GET_VREG(r2, r0)                    @ r2<- vAA
1666    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1667    cmp     r2, #0                      @ compare (vA, 0)
1668    movne r1, #2                 @ r1<- inst branch dist for not-taken
1669    adds    r1, r1, r1                  @ convert to bytes & set flags
1670    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1671#if defined(WITH_JIT)
1672    ldr     r0, [rSELF, #offThread_pJitProfTable]
1673    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1674    cmp     r0,#0
1675    bne     common_updateProfile        @ test for JIT off at target
1676#else
1677    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1678#endif
1679    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1680    GOTO_OPCODE(ip)                     @ jump to next instruction
1681
1682
1683/* ------------------------------ */
1684    .balign 64
1685.L_OP_IF_NEZ: /* 0x39 */
1686/* File: armv5te/OP_IF_NEZ.S */
1687/* File: armv5te/zcmp.S */
1688    /*
1689     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1690     * fragment that specifies the *reverse* comparison to perform, e.g.
1691     * for "if-le" you would use "gt".
1692     *
1693     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1694     */
1695    /* if-cmp vAA, +BBBB */
1696    mov     r0, rINST, lsr #8           @ r0<- AA
1697    GET_VREG(r2, r0)                    @ r2<- vAA
1698    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1699    cmp     r2, #0                      @ compare (vA, 0)
1700    moveq r1, #2                 @ r1<- inst branch dist for not-taken
1701    adds    r1, r1, r1                  @ convert to bytes & set flags
1702    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1703#if defined(WITH_JIT)
1704    ldr     r0, [rSELF, #offThread_pJitProfTable]
1705    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1706    cmp     r0,#0
1707    bne     common_updateProfile        @ test for JIT off at target
1708#else
1709    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1710#endif
1711    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1712    GOTO_OPCODE(ip)                     @ jump to next instruction
1713
1714
1715/* ------------------------------ */
1716    .balign 64
1717.L_OP_IF_LTZ: /* 0x3a */
1718/* File: armv5te/OP_IF_LTZ.S */
1719/* File: armv5te/zcmp.S */
1720    /*
1721     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1722     * fragment that specifies the *reverse* comparison to perform, e.g.
1723     * for "if-le" you would use "gt".
1724     *
1725     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1726     */
1727    /* if-cmp vAA, +BBBB */
1728    mov     r0, rINST, lsr #8           @ r0<- AA
1729    GET_VREG(r2, r0)                    @ r2<- vAA
1730    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1731    cmp     r2, #0                      @ compare (vA, 0)
1732    movge r1, #2                 @ r1<- inst branch dist for not-taken
1733    adds    r1, r1, r1                  @ convert to bytes & set flags
1734    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1735#if defined(WITH_JIT)
1736    ldr     r0, [rSELF, #offThread_pJitProfTable]
1737    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1738    cmp     r0,#0
1739    bne     common_updateProfile        @ test for JIT off at target
1740#else
1741    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1742#endif
1743    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1744    GOTO_OPCODE(ip)                     @ jump to next instruction
1745
1746
1747/* ------------------------------ */
1748    .balign 64
1749.L_OP_IF_GEZ: /* 0x3b */
1750/* File: armv5te/OP_IF_GEZ.S */
1751/* File: armv5te/zcmp.S */
1752    /*
1753     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1754     * fragment that specifies the *reverse* comparison to perform, e.g.
1755     * for "if-le" you would use "gt".
1756     *
1757     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1758     */
1759    /* if-cmp vAA, +BBBB */
1760    mov     r0, rINST, lsr #8           @ r0<- AA
1761    GET_VREG(r2, r0)                    @ r2<- vAA
1762    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1763    cmp     r2, #0                      @ compare (vA, 0)
1764    movlt r1, #2                 @ r1<- inst branch dist for not-taken
1765    adds    r1, r1, r1                  @ convert to bytes & set flags
1766    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1767#if defined(WITH_JIT)
1768    ldr     r0, [rSELF, #offThread_pJitProfTable]
1769    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1770    cmp     r0,#0
1771    bne     common_updateProfile        @ test for JIT off at target
1772#else
1773    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1774#endif
1775    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1776    GOTO_OPCODE(ip)                     @ jump to next instruction
1777
1778
1779/* ------------------------------ */
1780    .balign 64
1781.L_OP_IF_GTZ: /* 0x3c */
1782/* File: armv5te/OP_IF_GTZ.S */
1783/* File: armv5te/zcmp.S */
1784    /*
1785     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1786     * fragment that specifies the *reverse* comparison to perform, e.g.
1787     * for "if-le" you would use "gt".
1788     *
1789     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1790     */
1791    /* if-cmp vAA, +BBBB */
1792    mov     r0, rINST, lsr #8           @ r0<- AA
1793    GET_VREG(r2, r0)                    @ r2<- vAA
1794    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1795    cmp     r2, #0                      @ compare (vA, 0)
1796    movle r1, #2                 @ r1<- inst branch dist for not-taken
1797    adds    r1, r1, r1                  @ convert to bytes & set flags
1798    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1799#if defined(WITH_JIT)
1800    ldr     r0, [rSELF, #offThread_pJitProfTable]
1801    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1802    cmp     r0,#0
1803    bne     common_updateProfile        @ test for JIT off at target
1804#else
1805    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1806#endif
1807    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1808    GOTO_OPCODE(ip)                     @ jump to next instruction
1809
1810
1811/* ------------------------------ */
1812    .balign 64
1813.L_OP_IF_LEZ: /* 0x3d */
1814/* File: armv5te/OP_IF_LEZ.S */
1815/* File: armv5te/zcmp.S */
1816    /*
1817     * Generic one-operand compare-and-branch operation.  Provide a "revcmp"
1818     * fragment that specifies the *reverse* comparison to perform, e.g.
1819     * for "if-le" you would use "gt".
1820     *
1821     * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez
1822     */
1823    /* if-cmp vAA, +BBBB */
1824    mov     r0, rINST, lsr #8           @ r0<- AA
1825    GET_VREG(r2, r0)                    @ r2<- vAA
1826    FETCH_S(r1, 1)                      @ r1<- branch offset, in code units
1827    cmp     r2, #0                      @ compare (vA, 0)
1828    movgt r1, #2                 @ r1<- inst branch dist for not-taken
1829    adds    r1, r1, r1                  @ convert to bytes & set flags
1830    FETCH_ADVANCE_INST_RB(r1)           @ update rPC, load rINST
1831#if defined(WITH_JIT)
1832    ldr     r0, [rSELF, #offThread_pJitProfTable]
1833    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1834    cmp     r0,#0
1835    bne     common_updateProfile        @ test for JIT off at target
1836#else
1837    ldrmi   rIBASE, [rSELF, #offThread_curHandlerTable]   @ refresh table base
1838#endif
1839    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1840    GOTO_OPCODE(ip)                     @ jump to next instruction
1841
1842
1843/* ------------------------------ */
1844    .balign 64
1845.L_OP_UNUSED_3E: /* 0x3e */
1846/* File: armv5te/OP_UNUSED_3E.S */
1847/* File: armv5te/unused.S */
1848    bl      common_abort
1849
1850
1851/* ------------------------------ */
1852    .balign 64
1853.L_OP_UNUSED_3F: /* 0x3f */
1854/* File: armv5te/OP_UNUSED_3F.S */
1855/* File: armv5te/unused.S */
1856    bl      common_abort
1857
1858
1859/* ------------------------------ */
1860    .balign 64
1861.L_OP_UNUSED_40: /* 0x40 */
1862/* File: armv5te/OP_UNUSED_40.S */
1863/* File: armv5te/unused.S */
1864    bl      common_abort
1865
1866
1867/* ------------------------------ */
1868    .balign 64
1869.L_OP_UNUSED_41: /* 0x41 */
1870/* File: armv5te/OP_UNUSED_41.S */
1871/* File: armv5te/unused.S */
1872    bl      common_abort
1873
1874
1875/* ------------------------------ */
1876    .balign 64
1877.L_OP_UNUSED_42: /* 0x42 */
1878/* File: armv5te/OP_UNUSED_42.S */
1879/* File: armv5te/unused.S */
1880    bl      common_abort
1881
1882
1883/* ------------------------------ */
1884    .balign 64
1885.L_OP_UNUSED_43: /* 0x43 */
1886/* File: armv5te/OP_UNUSED_43.S */
1887/* File: armv5te/unused.S */
1888    bl      common_abort
1889
1890
1891/* ------------------------------ */
1892    .balign 64
1893.L_OP_AGET: /* 0x44 */
1894/* File: armv5te/OP_AGET.S */
1895    /*
1896     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1897     *
1898     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
1899     * instructions.  We use a pair of FETCH_Bs instead.
1900     *
1901     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1902     */
1903    /* op vAA, vBB, vCC */
1904    FETCH_B(r2, 1, 0)                   @ r2<- BB
1905    mov     r9, rINST, lsr #8           @ r9<- AA
1906    FETCH_B(r3, 1, 1)                   @ r3<- CC
1907    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1908    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1909    cmp     r0, #0                      @ null array object?
1910    beq     common_errNullObject        @ yes, bail
1911    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1912    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
1913    cmp     r1, r3                      @ compare unsigned index, length
1914    bcs     common_errArrayIndex        @ index >= length, bail
1915    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1916    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
1917    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1918    SET_VREG(r2, r9)                    @ vAA<- r2
1919    GOTO_OPCODE(ip)                     @ jump to next instruction
1920
1921/* ------------------------------ */
1922    .balign 64
1923.L_OP_AGET_WIDE: /* 0x45 */
1924/* File: armv5te/OP_AGET_WIDE.S */
1925    /*
1926     * Array get, 64 bits.  vAA <- vBB[vCC].
1927     *
1928     * Arrays of long/double are 64-bit aligned, so it's okay to use LDRD.
1929     */
1930    /* aget-wide vAA, vBB, vCC */
1931    FETCH(r0, 1)                        @ r0<- CCBB
1932    mov     r9, rINST, lsr #8           @ r9<- AA
1933    and     r2, r0, #255                @ r2<- BB
1934    mov     r3, r0, lsr #8              @ r3<- CC
1935    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1936    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1937    cmp     r0, #0                      @ null array object?
1938    beq     common_errNullObject        @ yes, bail
1939    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1940    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
1941    cmp     r1, r3                      @ compare unsigned index, length
1942    bcc     .LOP_AGET_WIDE_finish          @ okay, continue below
1943    b       common_errArrayIndex        @ index >= length, bail
1944    @ May want to swap the order of these two branches depending on how the
1945    @ branch prediction (if any) handles conditional forward branches vs.
1946    @ unconditional forward branches.
1947
1948/* ------------------------------ */
1949    .balign 64
1950.L_OP_AGET_OBJECT: /* 0x46 */
1951/* File: armv5te/OP_AGET_OBJECT.S */
1952/* File: armv5te/OP_AGET.S */
1953    /*
1954     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1955     *
1956     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
1957     * instructions.  We use a pair of FETCH_Bs instead.
1958     *
1959     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1960     */
1961    /* op vAA, vBB, vCC */
1962    FETCH_B(r2, 1, 0)                   @ r2<- BB
1963    mov     r9, rINST, lsr #8           @ r9<- AA
1964    FETCH_B(r3, 1, 1)                   @ r3<- CC
1965    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1966    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1967    cmp     r0, #0                      @ null array object?
1968    beq     common_errNullObject        @ yes, bail
1969    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
1970    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
1971    cmp     r1, r3                      @ compare unsigned index, length
1972    bcs     common_errArrayIndex        @ index >= length, bail
1973    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
1974    ldr   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
1975    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
1976    SET_VREG(r2, r9)                    @ vAA<- r2
1977    GOTO_OPCODE(ip)                     @ jump to next instruction
1978
1979
1980/* ------------------------------ */
1981    .balign 64
1982.L_OP_AGET_BOOLEAN: /* 0x47 */
1983/* File: armv5te/OP_AGET_BOOLEAN.S */
1984/* File: armv5te/OP_AGET.S */
1985    /*
1986     * Array get, 32 bits or less.  vAA <- vBB[vCC].
1987     *
1988     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
1989     * instructions.  We use a pair of FETCH_Bs instead.
1990     *
1991     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
1992     */
1993    /* op vAA, vBB, vCC */
1994    FETCH_B(r2, 1, 0)                   @ r2<- BB
1995    mov     r9, rINST, lsr #8           @ r9<- AA
1996    FETCH_B(r3, 1, 1)                   @ r3<- CC
1997    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
1998    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
1999    cmp     r0, #0                      @ null array object?
2000    beq     common_errNullObject        @ yes, bail
2001    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2002    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2003    cmp     r1, r3                      @ compare unsigned index, length
2004    bcs     common_errArrayIndex        @ index >= length, bail
2005    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2006    ldrb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2007    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2008    SET_VREG(r2, r9)                    @ vAA<- r2
2009    GOTO_OPCODE(ip)                     @ jump to next instruction
2010
2011
2012/* ------------------------------ */
2013    .balign 64
2014.L_OP_AGET_BYTE: /* 0x48 */
2015/* File: armv5te/OP_AGET_BYTE.S */
2016/* File: armv5te/OP_AGET.S */
2017    /*
2018     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2019     *
2020     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2021     * instructions.  We use a pair of FETCH_Bs instead.
2022     *
2023     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2024     */
2025    /* op vAA, vBB, vCC */
2026    FETCH_B(r2, 1, 0)                   @ r2<- BB
2027    mov     r9, rINST, lsr #8           @ r9<- AA
2028    FETCH_B(r3, 1, 1)                   @ r3<- CC
2029    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2030    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2031    cmp     r0, #0                      @ null array object?
2032    beq     common_errNullObject        @ yes, bail
2033    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2034    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2035    cmp     r1, r3                      @ compare unsigned index, length
2036    bcs     common_errArrayIndex        @ index >= length, bail
2037    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2038    ldrsb   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2039    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2040    SET_VREG(r2, r9)                    @ vAA<- r2
2041    GOTO_OPCODE(ip)                     @ jump to next instruction
2042
2043
2044/* ------------------------------ */
2045    .balign 64
2046.L_OP_AGET_CHAR: /* 0x49 */
2047/* File: armv5te/OP_AGET_CHAR.S */
2048/* File: armv5te/OP_AGET.S */
2049    /*
2050     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2051     *
2052     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2053     * instructions.  We use a pair of FETCH_Bs instead.
2054     *
2055     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2056     */
2057    /* op vAA, vBB, vCC */
2058    FETCH_B(r2, 1, 0)                   @ r2<- BB
2059    mov     r9, rINST, lsr #8           @ r9<- AA
2060    FETCH_B(r3, 1, 1)                   @ r3<- CC
2061    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2062    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2063    cmp     r0, #0                      @ null array object?
2064    beq     common_errNullObject        @ yes, bail
2065    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2066    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2067    cmp     r1, r3                      @ compare unsigned index, length
2068    bcs     common_errArrayIndex        @ index >= length, bail
2069    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2070    ldrh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2071    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2072    SET_VREG(r2, r9)                    @ vAA<- r2
2073    GOTO_OPCODE(ip)                     @ jump to next instruction
2074
2075
2076/* ------------------------------ */
2077    .balign 64
2078.L_OP_AGET_SHORT: /* 0x4a */
2079/* File: armv5te/OP_AGET_SHORT.S */
2080/* File: armv5te/OP_AGET.S */
2081    /*
2082     * Array get, 32 bits or less.  vAA <- vBB[vCC].
2083     *
2084     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2085     * instructions.  We use a pair of FETCH_Bs instead.
2086     *
2087     * for: aget, aget-object, aget-boolean, aget-byte, aget-char, aget-short
2088     */
2089    /* op vAA, vBB, vCC */
2090    FETCH_B(r2, 1, 0)                   @ r2<- BB
2091    mov     r9, rINST, lsr #8           @ r9<- AA
2092    FETCH_B(r3, 1, 1)                   @ r3<- CC
2093    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2094    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2095    cmp     r0, #0                      @ null array object?
2096    beq     common_errNullObject        @ yes, bail
2097    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2098    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2099    cmp     r1, r3                      @ compare unsigned index, length
2100    bcs     common_errArrayIndex        @ index >= length, bail
2101    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2102    ldrsh   r2, [r0, #offArrayObject_contents]  @ r2<- vBB[vCC]
2103    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2104    SET_VREG(r2, r9)                    @ vAA<- r2
2105    GOTO_OPCODE(ip)                     @ jump to next instruction
2106
2107
2108/* ------------------------------ */
2109    .balign 64
2110.L_OP_APUT: /* 0x4b */
2111/* File: armv5te/OP_APUT.S */
2112    /*
2113     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2114     *
2115     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2116     * instructions.  We use a pair of FETCH_Bs instead.
2117     *
2118     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2119     */
2120    /* op vAA, vBB, vCC */
2121    FETCH_B(r2, 1, 0)                   @ r2<- BB
2122    mov     r9, rINST, lsr #8           @ r9<- AA
2123    FETCH_B(r3, 1, 1)                   @ r3<- CC
2124    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2125    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2126    cmp     r0, #0                      @ null array object?
2127    beq     common_errNullObject        @ yes, bail
2128    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2129    add     r0, r0, r1, lsl #2     @ r0<- arrayObj + index*width
2130    cmp     r1, r3                      @ compare unsigned index, length
2131    bcs     common_errArrayIndex        @ index >= length, bail
2132    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2133    GET_VREG(r2, r9)                    @ r2<- vAA
2134    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2135    str  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2136    GOTO_OPCODE(ip)                     @ jump to next instruction
2137
2138/* ------------------------------ */
2139    .balign 64
2140.L_OP_APUT_WIDE: /* 0x4c */
2141/* File: armv5te/OP_APUT_WIDE.S */
2142    /*
2143     * Array put, 64 bits.  vBB[vCC] <- vAA.
2144     *
2145     * Arrays of long/double are 64-bit aligned, so it's okay to use STRD.
2146     */
2147    /* aput-wide vAA, vBB, vCC */
2148    FETCH(r0, 1)                        @ r0<- CCBB
2149    mov     r9, rINST, lsr #8           @ r9<- AA
2150    and     r2, r0, #255                @ r2<- BB
2151    mov     r3, r0, lsr #8              @ r3<- CC
2152    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2153    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2154    cmp     r0, #0                      @ null array object?
2155    beq     common_errNullObject        @ yes, bail
2156    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2157    add     r0, r0, r1, lsl #3          @ r0<- arrayObj + index*width
2158    cmp     r1, r3                      @ compare unsigned index, length
2159    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2160    bcc     .LOP_APUT_WIDE_finish          @ okay, continue below
2161    b       common_errArrayIndex        @ index >= length, bail
2162    @ May want to swap the order of these two branches depending on how the
2163    @ branch prediction (if any) handles conditional forward branches vs.
2164    @ unconditional forward branches.
2165
2166/* ------------------------------ */
2167    .balign 64
2168.L_OP_APUT_OBJECT: /* 0x4d */
2169/* File: armv5te/OP_APUT_OBJECT.S */
2170    /*
2171     * Store an object into an array.  vBB[vCC] <- vAA.
2172     */
2173    /* op vAA, vBB, vCC */
2174    FETCH(r0, 1)                        @ r0<- CCBB
2175    mov     r9, rINST, lsr #8           @ r9<- AA
2176    and     r2, r0, #255                @ r2<- BB
2177    mov     r3, r0, lsr #8              @ r3<- CC
2178    GET_VREG(rINST, r2)                 @ rINST<- vBB (array object)
2179    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2180    cmp     rINST, #0                   @ null array object?
2181    GET_VREG(r9, r9)                    @ r9<- vAA
2182    beq     common_errNullObject        @ yes, bail
2183    ldr     r3, [rINST, #offArrayObject_length]   @ r3<- arrayObj->length
2184    add     r10, rINST, r1, lsl #2      @ r10<- arrayObj + index*width
2185    cmp     r1, r3                      @ compare unsigned index, length
2186    bcc     .LOP_APUT_OBJECT_finish          @ we're okay, continue on
2187    b       common_errArrayIndex        @ index >= length, bail
2188
2189
2190/* ------------------------------ */
2191    .balign 64
2192.L_OP_APUT_BOOLEAN: /* 0x4e */
2193/* File: armv5te/OP_APUT_BOOLEAN.S */
2194/* File: armv5te/OP_APUT.S */
2195    /*
2196     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2197     *
2198     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2199     * instructions.  We use a pair of FETCH_Bs instead.
2200     *
2201     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2202     */
2203    /* op vAA, vBB, vCC */
2204    FETCH_B(r2, 1, 0)                   @ r2<- BB
2205    mov     r9, rINST, lsr #8           @ r9<- AA
2206    FETCH_B(r3, 1, 1)                   @ r3<- CC
2207    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2208    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2209    cmp     r0, #0                      @ null array object?
2210    beq     common_errNullObject        @ yes, bail
2211    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2212    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2213    cmp     r1, r3                      @ compare unsigned index, length
2214    bcs     common_errArrayIndex        @ index >= length, bail
2215    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2216    GET_VREG(r2, r9)                    @ r2<- vAA
2217    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2218    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2219    GOTO_OPCODE(ip)                     @ jump to next instruction
2220
2221
2222/* ------------------------------ */
2223    .balign 64
2224.L_OP_APUT_BYTE: /* 0x4f */
2225/* File: armv5te/OP_APUT_BYTE.S */
2226/* File: armv5te/OP_APUT.S */
2227    /*
2228     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2229     *
2230     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2231     * instructions.  We use a pair of FETCH_Bs instead.
2232     *
2233     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2234     */
2235    /* op vAA, vBB, vCC */
2236    FETCH_B(r2, 1, 0)                   @ r2<- BB
2237    mov     r9, rINST, lsr #8           @ r9<- AA
2238    FETCH_B(r3, 1, 1)                   @ r3<- CC
2239    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2240    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2241    cmp     r0, #0                      @ null array object?
2242    beq     common_errNullObject        @ yes, bail
2243    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2244    add     r0, r0, r1, lsl #0     @ r0<- arrayObj + index*width
2245    cmp     r1, r3                      @ compare unsigned index, length
2246    bcs     common_errArrayIndex        @ index >= length, bail
2247    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2248    GET_VREG(r2, r9)                    @ r2<- vAA
2249    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2250    strb  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2251    GOTO_OPCODE(ip)                     @ jump to next instruction
2252
2253
2254/* ------------------------------ */
2255    .balign 64
2256.L_OP_APUT_CHAR: /* 0x50 */
2257/* File: armv5te/OP_APUT_CHAR.S */
2258/* File: armv5te/OP_APUT.S */
2259    /*
2260     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2261     *
2262     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2263     * instructions.  We use a pair of FETCH_Bs instead.
2264     *
2265     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2266     */
2267    /* op vAA, vBB, vCC */
2268    FETCH_B(r2, 1, 0)                   @ r2<- BB
2269    mov     r9, rINST, lsr #8           @ r9<- AA
2270    FETCH_B(r3, 1, 1)                   @ r3<- CC
2271    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2272    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2273    cmp     r0, #0                      @ null array object?
2274    beq     common_errNullObject        @ yes, bail
2275    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2276    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2277    cmp     r1, r3                      @ compare unsigned index, length
2278    bcs     common_errArrayIndex        @ index >= length, bail
2279    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2280    GET_VREG(r2, r9)                    @ r2<- vAA
2281    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2282    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2283    GOTO_OPCODE(ip)                     @ jump to next instruction
2284
2285
2286/* ------------------------------ */
2287    .balign 64
2288.L_OP_APUT_SHORT: /* 0x51 */
2289/* File: armv5te/OP_APUT_SHORT.S */
2290/* File: armv5te/OP_APUT.S */
2291    /*
2292     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
2293     *
2294     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
2295     * instructions.  We use a pair of FETCH_Bs instead.
2296     *
2297     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
2298     */
2299    /* op vAA, vBB, vCC */
2300    FETCH_B(r2, 1, 0)                   @ r2<- BB
2301    mov     r9, rINST, lsr #8           @ r9<- AA
2302    FETCH_B(r3, 1, 1)                   @ r3<- CC
2303    GET_VREG(r0, r2)                    @ r0<- vBB (array object)
2304    GET_VREG(r1, r3)                    @ r1<- vCC (requested index)
2305    cmp     r0, #0                      @ null array object?
2306    beq     common_errNullObject        @ yes, bail
2307    ldr     r3, [r0, #offArrayObject_length]    @ r3<- arrayObj->length
2308    add     r0, r0, r1, lsl #1     @ r0<- arrayObj + index*width
2309    cmp     r1, r3                      @ compare unsigned index, length
2310    bcs     common_errArrayIndex        @ index >= length, bail
2311    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2312    GET_VREG(r2, r9)                    @ r2<- vAA
2313    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2314    strh  r2, [r0, #offArrayObject_contents]  @ vBB[vCC]<- r2
2315    GOTO_OPCODE(ip)                     @ jump to next instruction
2316
2317
2318/* ------------------------------ */
2319    .balign 64
2320.L_OP_IGET: /* 0x52 */
2321/* File: armv5te/OP_IGET.S */
2322    /*
2323     * General 32-bit instance field get.
2324     *
2325     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2326     */
2327    /* op vA, vB, field@CCCC */
2328    mov     r0, rINST, lsr #12          @ r0<- B
2329    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2330    FETCH(r1, 1)                        @ r1<- field ref CCCC
2331    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2332    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2333    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2334    cmp     r0, #0                      @ is resolved entry null?
2335    bne     .LOP_IGET_finish          @ no, already resolved
23368:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2337    EXPORT_PC()                         @ resolve() could throw
2338    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2339    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2340    cmp     r0, #0
2341    bne     .LOP_IGET_finish
2342    b       common_exceptionThrown
2343
2344/* ------------------------------ */
2345    .balign 64
2346.L_OP_IGET_WIDE: /* 0x53 */
2347/* File: armv5te/OP_IGET_WIDE.S */
2348    /*
2349     * Wide 32-bit instance field get.
2350     */
2351    /* iget-wide vA, vB, field@CCCC */
2352    mov     r0, rINST, lsr #12          @ r0<- B
2353    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2354    FETCH(r1, 1)                        @ r1<- field ref CCCC
2355    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
2356    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2357    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2358    cmp     r0, #0                      @ is resolved entry null?
2359    bne     .LOP_IGET_WIDE_finish          @ no, already resolved
23608:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
2361    EXPORT_PC()                         @ resolve() could throw
2362    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2363    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2364    cmp     r0, #0
2365    bne     .LOP_IGET_WIDE_finish
2366    b       common_exceptionThrown
2367
2368/* ------------------------------ */
2369    .balign 64
2370.L_OP_IGET_OBJECT: /* 0x54 */
2371/* File: armv5te/OP_IGET_OBJECT.S */
2372/* File: armv5te/OP_IGET.S */
2373    /*
2374     * General 32-bit instance field get.
2375     *
2376     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2377     */
2378    /* op vA, vB, field@CCCC */
2379    mov     r0, rINST, lsr #12          @ r0<- B
2380    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2381    FETCH(r1, 1)                        @ r1<- field ref CCCC
2382    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2383    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2384    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2385    cmp     r0, #0                      @ is resolved entry null?
2386    bne     .LOP_IGET_OBJECT_finish          @ no, already resolved
23878:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2388    EXPORT_PC()                         @ resolve() could throw
2389    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2390    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2391    cmp     r0, #0
2392    bne     .LOP_IGET_OBJECT_finish
2393    b       common_exceptionThrown
2394
2395
2396/* ------------------------------ */
2397    .balign 64
2398.L_OP_IGET_BOOLEAN: /* 0x55 */
2399/* File: armv5te/OP_IGET_BOOLEAN.S */
2400@include "armv5te/OP_IGET.S" { "load":"ldrb", "sqnum":"1" }
2401/* File: armv5te/OP_IGET.S */
2402    /*
2403     * General 32-bit instance field get.
2404     *
2405     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2406     */
2407    /* op vA, vB, field@CCCC */
2408    mov     r0, rINST, lsr #12          @ r0<- B
2409    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2410    FETCH(r1, 1)                        @ r1<- field ref CCCC
2411    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2412    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2413    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2414    cmp     r0, #0                      @ is resolved entry null?
2415    bne     .LOP_IGET_BOOLEAN_finish          @ no, already resolved
24168:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2417    EXPORT_PC()                         @ resolve() could throw
2418    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2419    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2420    cmp     r0, #0
2421    bne     .LOP_IGET_BOOLEAN_finish
2422    b       common_exceptionThrown
2423
2424
2425/* ------------------------------ */
2426    .balign 64
2427.L_OP_IGET_BYTE: /* 0x56 */
2428/* File: armv5te/OP_IGET_BYTE.S */
2429@include "armv5te/OP_IGET.S" { "load":"ldrsb", "sqnum":"2" }
2430/* File: armv5te/OP_IGET.S */
2431    /*
2432     * General 32-bit instance field get.
2433     *
2434     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2435     */
2436    /* op vA, vB, field@CCCC */
2437    mov     r0, rINST, lsr #12          @ r0<- B
2438    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2439    FETCH(r1, 1)                        @ r1<- field ref CCCC
2440    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2441    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2442    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2443    cmp     r0, #0                      @ is resolved entry null?
2444    bne     .LOP_IGET_BYTE_finish          @ no, already resolved
24458:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2446    EXPORT_PC()                         @ resolve() could throw
2447    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2448    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2449    cmp     r0, #0
2450    bne     .LOP_IGET_BYTE_finish
2451    b       common_exceptionThrown
2452
2453
2454/* ------------------------------ */
2455    .balign 64
2456.L_OP_IGET_CHAR: /* 0x57 */
2457/* File: armv5te/OP_IGET_CHAR.S */
2458@include "armv5te/OP_IGET.S" { "load":"ldrh", "sqnum":"3" }
2459/* File: armv5te/OP_IGET.S */
2460    /*
2461     * General 32-bit instance field get.
2462     *
2463     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2464     */
2465    /* op vA, vB, field@CCCC */
2466    mov     r0, rINST, lsr #12          @ r0<- B
2467    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2468    FETCH(r1, 1)                        @ r1<- field ref CCCC
2469    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2470    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2471    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2472    cmp     r0, #0                      @ is resolved entry null?
2473    bne     .LOP_IGET_CHAR_finish          @ no, already resolved
24748:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2475    EXPORT_PC()                         @ resolve() could throw
2476    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2477    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2478    cmp     r0, #0
2479    bne     .LOP_IGET_CHAR_finish
2480    b       common_exceptionThrown
2481
2482
2483/* ------------------------------ */
2484    .balign 64
2485.L_OP_IGET_SHORT: /* 0x58 */
2486/* File: armv5te/OP_IGET_SHORT.S */
2487@include "armv5te/OP_IGET.S" { "load":"ldrsh", "sqnum":"4" }
2488/* File: armv5te/OP_IGET.S */
2489    /*
2490     * General 32-bit instance field get.
2491     *
2492     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
2493     */
2494    /* op vA, vB, field@CCCC */
2495    mov     r0, rINST, lsr #12          @ r0<- B
2496    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2497    FETCH(r1, 1)                        @ r1<- field ref CCCC
2498    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2499    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2500    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2501    cmp     r0, #0                      @ is resolved entry null?
2502    bne     .LOP_IGET_SHORT_finish          @ no, already resolved
25038:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2504    EXPORT_PC()                         @ resolve() could throw
2505    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2506    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2507    cmp     r0, #0
2508    bne     .LOP_IGET_SHORT_finish
2509    b       common_exceptionThrown
2510
2511
2512/* ------------------------------ */
2513    .balign 64
2514.L_OP_IPUT: /* 0x59 */
2515/* File: armv5te/OP_IPUT.S */
2516    /*
2517     * General 32-bit instance field put.
2518     *
2519     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2520     */
2521    /* op vA, vB, field@CCCC */
2522    mov     r0, rINST, lsr #12          @ r0<- B
2523    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2524    FETCH(r1, 1)                        @ r1<- field ref CCCC
2525    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2526    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2527    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2528    cmp     r0, #0                      @ is resolved entry null?
2529    bne     .LOP_IPUT_finish          @ no, already resolved
25308:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2531    EXPORT_PC()                         @ resolve() could throw
2532    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2533    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2534    cmp     r0, #0                      @ success?
2535    bne     .LOP_IPUT_finish          @ yes, finish up
2536    b       common_exceptionThrown
2537
2538/* ------------------------------ */
2539    .balign 64
2540.L_OP_IPUT_WIDE: /* 0x5a */
2541/* File: armv5te/OP_IPUT_WIDE.S */
2542    /* iput-wide vA, vB, field@CCCC */
2543    mov     r0, rINST, lsr #12          @ r0<- B
2544    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2545    FETCH(r1, 1)                        @ r1<- field ref CCCC
2546    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
2547    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2548    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2549    cmp     r0, #0                      @ is resolved entry null?
2550    bne     .LOP_IPUT_WIDE_finish          @ no, already resolved
25518:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
2552    EXPORT_PC()                         @ resolve() could throw
2553    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2554    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2555    cmp     r0, #0                      @ success?
2556    bne     .LOP_IPUT_WIDE_finish          @ yes, finish up
2557    b       common_exceptionThrown
2558
2559/* ------------------------------ */
2560    .balign 64
2561.L_OP_IPUT_OBJECT: /* 0x5b */
2562/* File: armv5te/OP_IPUT_OBJECT.S */
2563    /*
2564     * 32-bit instance field put.
2565     *
2566     * for: iput-object, iput-object-volatile
2567     */
2568    /* op vA, vB, field@CCCC */
2569    mov     r0, rINST, lsr #12          @ r0<- B
2570    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2571    FETCH(r1, 1)                        @ r1<- field ref CCCC
2572    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2573    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2574    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2575    cmp     r0, #0                      @ is resolved entry null?
2576    bne     .LOP_IPUT_OBJECT_finish          @ no, already resolved
25778:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2578    EXPORT_PC()                         @ resolve() could throw
2579    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2580    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2581    cmp     r0, #0                      @ success?
2582    bne     .LOP_IPUT_OBJECT_finish          @ yes, finish up
2583    b       common_exceptionThrown
2584
2585/* ------------------------------ */
2586    .balign 64
2587.L_OP_IPUT_BOOLEAN: /* 0x5c */
2588/* File: armv5te/OP_IPUT_BOOLEAN.S */
2589@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"1" }
2590/* File: armv5te/OP_IPUT.S */
2591    /*
2592     * General 32-bit instance field put.
2593     *
2594     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2595     */
2596    /* op vA, vB, field@CCCC */
2597    mov     r0, rINST, lsr #12          @ r0<- B
2598    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2599    FETCH(r1, 1)                        @ r1<- field ref CCCC
2600    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2601    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2602    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2603    cmp     r0, #0                      @ is resolved entry null?
2604    bne     .LOP_IPUT_BOOLEAN_finish          @ no, already resolved
26058:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2606    EXPORT_PC()                         @ resolve() could throw
2607    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2608    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2609    cmp     r0, #0                      @ success?
2610    bne     .LOP_IPUT_BOOLEAN_finish          @ yes, finish up
2611    b       common_exceptionThrown
2612
2613
2614/* ------------------------------ */
2615    .balign 64
2616.L_OP_IPUT_BYTE: /* 0x5d */
2617/* File: armv5te/OP_IPUT_BYTE.S */
2618@include "armv5te/OP_IPUT.S" { "store":"strb", "sqnum":"2" }
2619/* File: armv5te/OP_IPUT.S */
2620    /*
2621     * General 32-bit instance field put.
2622     *
2623     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2624     */
2625    /* op vA, vB, field@CCCC */
2626    mov     r0, rINST, lsr #12          @ r0<- B
2627    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2628    FETCH(r1, 1)                        @ r1<- field ref CCCC
2629    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2630    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2631    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2632    cmp     r0, #0                      @ is resolved entry null?
2633    bne     .LOP_IPUT_BYTE_finish          @ no, already resolved
26348:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2635    EXPORT_PC()                         @ resolve() could throw
2636    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2637    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2638    cmp     r0, #0                      @ success?
2639    bne     .LOP_IPUT_BYTE_finish          @ yes, finish up
2640    b       common_exceptionThrown
2641
2642
2643/* ------------------------------ */
2644    .balign 64
2645.L_OP_IPUT_CHAR: /* 0x5e */
2646/* File: armv5te/OP_IPUT_CHAR.S */
2647@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"3" }
2648/* File: armv5te/OP_IPUT.S */
2649    /*
2650     * General 32-bit instance field put.
2651     *
2652     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2653     */
2654    /* op vA, vB, field@CCCC */
2655    mov     r0, rINST, lsr #12          @ r0<- B
2656    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2657    FETCH(r1, 1)                        @ r1<- field ref CCCC
2658    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2659    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2660    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2661    cmp     r0, #0                      @ is resolved entry null?
2662    bne     .LOP_IPUT_CHAR_finish          @ no, already resolved
26638:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2664    EXPORT_PC()                         @ resolve() could throw
2665    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2666    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2667    cmp     r0, #0                      @ success?
2668    bne     .LOP_IPUT_CHAR_finish          @ yes, finish up
2669    b       common_exceptionThrown
2670
2671
2672/* ------------------------------ */
2673    .balign 64
2674.L_OP_IPUT_SHORT: /* 0x5f */
2675/* File: armv5te/OP_IPUT_SHORT.S */
2676@include "armv5te/OP_IPUT.S" { "store":"strh", "sqnum":"4" }
2677/* File: armv5te/OP_IPUT.S */
2678    /*
2679     * General 32-bit instance field put.
2680     *
2681     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
2682     */
2683    /* op vA, vB, field@CCCC */
2684    mov     r0, rINST, lsr #12          @ r0<- B
2685    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
2686    FETCH(r1, 1)                        @ r1<- field ref CCCC
2687    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
2688    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
2689    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
2690    cmp     r0, #0                      @ is resolved entry null?
2691    bne     .LOP_IPUT_SHORT_finish          @ no, already resolved
26928:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
2693    EXPORT_PC()                         @ resolve() could throw
2694    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
2695    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
2696    cmp     r0, #0                      @ success?
2697    bne     .LOP_IPUT_SHORT_finish          @ yes, finish up
2698    b       common_exceptionThrown
2699
2700
2701/* ------------------------------ */
2702    .balign 64
2703.L_OP_SGET: /* 0x60 */
2704/* File: armv5te/OP_SGET.S */
2705    /*
2706     * General 32-bit SGET handler.
2707     *
2708     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2709     */
2710    /* op vAA, field@BBBB */
2711    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2712    FETCH(r1, 1)                        @ r1<- field ref BBBB
2713    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2714    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2715    cmp     r0, #0                      @ is resolved entry null?
2716    beq     .LOP_SGET_resolve         @ yes, do resolve
2717.LOP_SGET_finish: @ field ptr in r0
2718    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2719    @ no-op                             @ acquiring load
2720    mov     r2, rINST, lsr #8           @ r2<- AA
2721    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2722    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2723    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2724    GOTO_OPCODE(ip)                     @ jump to next instruction
2725
2726/* ------------------------------ */
2727    .balign 64
2728.L_OP_SGET_WIDE: /* 0x61 */
2729/* File: armv5te/OP_SGET_WIDE.S */
2730    /*
2731     * 64-bit SGET handler.
2732     */
2733    /* sget-wide vAA, field@BBBB */
2734    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2735    FETCH(r1, 1)                        @ r1<- field ref BBBB
2736    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2737    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2738    cmp     r0, #0                      @ is resolved entry null?
2739    beq     .LOP_SGET_WIDE_resolve         @ yes, do resolve
2740.LOP_SGET_WIDE_finish:
2741    mov     r9, rINST, lsr #8           @ r9<- AA
2742    .if 0
2743    add     r0, r0, #offStaticField_value @ r0<- pointer to data
2744    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
2745    .else
2746    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
2747    .endif
2748    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2749    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2750    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
2751    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2752    GOTO_OPCODE(ip)                     @ jump to next instruction
2753
2754/* ------------------------------ */
2755    .balign 64
2756.L_OP_SGET_OBJECT: /* 0x62 */
2757/* File: armv5te/OP_SGET_OBJECT.S */
2758/* File: armv5te/OP_SGET.S */
2759    /*
2760     * General 32-bit SGET handler.
2761     *
2762     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2763     */
2764    /* op vAA, field@BBBB */
2765    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2766    FETCH(r1, 1)                        @ r1<- field ref BBBB
2767    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2768    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2769    cmp     r0, #0                      @ is resolved entry null?
2770    beq     .LOP_SGET_OBJECT_resolve         @ yes, do resolve
2771.LOP_SGET_OBJECT_finish: @ field ptr in r0
2772    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2773    @ no-op                             @ acquiring load
2774    mov     r2, rINST, lsr #8           @ r2<- AA
2775    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2776    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2777    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2778    GOTO_OPCODE(ip)                     @ jump to next instruction
2779
2780
2781/* ------------------------------ */
2782    .balign 64
2783.L_OP_SGET_BOOLEAN: /* 0x63 */
2784/* File: armv5te/OP_SGET_BOOLEAN.S */
2785/* File: armv5te/OP_SGET.S */
2786    /*
2787     * General 32-bit SGET handler.
2788     *
2789     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2790     */
2791    /* op vAA, field@BBBB */
2792    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2793    FETCH(r1, 1)                        @ r1<- field ref BBBB
2794    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2795    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2796    cmp     r0, #0                      @ is resolved entry null?
2797    beq     .LOP_SGET_BOOLEAN_resolve         @ yes, do resolve
2798.LOP_SGET_BOOLEAN_finish: @ field ptr in r0
2799    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2800    @ no-op                             @ acquiring load
2801    mov     r2, rINST, lsr #8           @ r2<- AA
2802    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2803    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2804    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2805    GOTO_OPCODE(ip)                     @ jump to next instruction
2806
2807
2808/* ------------------------------ */
2809    .balign 64
2810.L_OP_SGET_BYTE: /* 0x64 */
2811/* File: armv5te/OP_SGET_BYTE.S */
2812/* File: armv5te/OP_SGET.S */
2813    /*
2814     * General 32-bit SGET handler.
2815     *
2816     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2817     */
2818    /* op vAA, field@BBBB */
2819    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2820    FETCH(r1, 1)                        @ r1<- field ref BBBB
2821    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2822    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2823    cmp     r0, #0                      @ is resolved entry null?
2824    beq     .LOP_SGET_BYTE_resolve         @ yes, do resolve
2825.LOP_SGET_BYTE_finish: @ field ptr in r0
2826    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2827    @ no-op                             @ acquiring load
2828    mov     r2, rINST, lsr #8           @ r2<- AA
2829    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2830    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2831    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2832    GOTO_OPCODE(ip)                     @ jump to next instruction
2833
2834
2835/* ------------------------------ */
2836    .balign 64
2837.L_OP_SGET_CHAR: /* 0x65 */
2838/* File: armv5te/OP_SGET_CHAR.S */
2839/* File: armv5te/OP_SGET.S */
2840    /*
2841     * General 32-bit SGET handler.
2842     *
2843     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2844     */
2845    /* op vAA, field@BBBB */
2846    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2847    FETCH(r1, 1)                        @ r1<- field ref BBBB
2848    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2849    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2850    cmp     r0, #0                      @ is resolved entry null?
2851    beq     .LOP_SGET_CHAR_resolve         @ yes, do resolve
2852.LOP_SGET_CHAR_finish: @ field ptr in r0
2853    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2854    @ no-op                             @ acquiring load
2855    mov     r2, rINST, lsr #8           @ r2<- AA
2856    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2857    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2858    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2859    GOTO_OPCODE(ip)                     @ jump to next instruction
2860
2861
2862/* ------------------------------ */
2863    .balign 64
2864.L_OP_SGET_SHORT: /* 0x66 */
2865/* File: armv5te/OP_SGET_SHORT.S */
2866/* File: armv5te/OP_SGET.S */
2867    /*
2868     * General 32-bit SGET handler.
2869     *
2870     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
2871     */
2872    /* op vAA, field@BBBB */
2873    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2874    FETCH(r1, 1)                        @ r1<- field ref BBBB
2875    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2876    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
2877    cmp     r0, #0                      @ is resolved entry null?
2878    beq     .LOP_SGET_SHORT_resolve         @ yes, do resolve
2879.LOP_SGET_SHORT_finish: @ field ptr in r0
2880    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
2881    @ no-op                             @ acquiring load
2882    mov     r2, rINST, lsr #8           @ r2<- AA
2883    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2884    SET_VREG(r1, r2)                    @ fp[AA]<- r1
2885    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2886    GOTO_OPCODE(ip)                     @ jump to next instruction
2887
2888
2889/* ------------------------------ */
2890    .balign 64
2891.L_OP_SPUT: /* 0x67 */
2892/* File: armv5te/OP_SPUT.S */
2893    /*
2894     * General 32-bit SPUT handler.
2895     *
2896     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2897     */
2898    /* op vAA, field@BBBB */
2899    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2900    FETCH(r1, 1)                        @ r1<- field ref BBBB
2901    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2902    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
2903    cmp     r0, #0                      @ is resolved entry null?
2904    beq     .LOP_SPUT_resolve         @ yes, do resolve
2905.LOP_SPUT_finish:   @ field ptr in r0
2906    mov     r2, rINST, lsr #8           @ r2<- AA
2907    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2908    GET_VREG(r1, r2)                    @ r1<- fp[AA]
2909    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2910    @ no-op                        @ releasing store
2911    str     r1, [r0, #offStaticField_value] @ field<- vAA
2912    @ no-op
2913    GOTO_OPCODE(ip)                     @ jump to next instruction
2914
2915/* ------------------------------ */
2916    .balign 64
2917.L_OP_SPUT_WIDE: /* 0x68 */
2918/* File: armv5te/OP_SPUT_WIDE.S */
2919    /*
2920     * 64-bit SPUT handler.
2921     */
2922    /* sput-wide vAA, field@BBBB */
2923    ldr     r0, [rSELF, #offThread_methodClassDex]  @ r0<- DvmDex
2924    FETCH(r1, 1)                        @ r1<- field ref BBBB
2925    ldr     r10, [r0, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2926    mov     r9, rINST, lsr #8           @ r9<- AA
2927    ldr     r2, [r10, r1, lsl #2]        @ r2<- resolved StaticField ptr
2928    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
2929    cmp     r2, #0                      @ is resolved entry null?
2930    beq     .LOP_SPUT_WIDE_resolve         @ yes, do resolve
2931.LOP_SPUT_WIDE_finish: @ field ptr in r2, AA in r9
2932    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2933    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
2934    GET_INST_OPCODE(r10)                @ extract opcode from rINST
2935    .if 0
2936    add     r2, r2, #offStaticField_value @ r2<- pointer to data
2937    bl      dvmQuasiAtomicSwap64Sync    @ stores r0/r1 into addr r2
2938    .else
2939    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
2940    .endif
2941    GOTO_OPCODE(r10)                    @ jump to next instruction
2942
2943/* ------------------------------ */
2944    .balign 64
2945.L_OP_SPUT_OBJECT: /* 0x69 */
2946/* File: armv5te/OP_SPUT_OBJECT.S */
2947    /*
2948     * 32-bit SPUT handler for objects
2949     *
2950     * for: sput-object, sput-object-volatile
2951     */
2952    /* op vAA, field@BBBB */
2953    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2954    FETCH(r1, 1)                        @ r1<- field ref BBBB
2955    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2956    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
2957    cmp     r0, #0                      @ is resolved entry null?
2958    beq     .LOP_SPUT_OBJECT_resolve         @ yes, do resolve
2959.LOP_SPUT_OBJECT_finish:   @ field ptr in r0
2960    mov     r2, rINST, lsr #8           @ r2<- AA
2961    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2962    GET_VREG(r1, r2)                    @ r1<- fp[AA]
2963    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
2964    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
2965    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2966    @ no-op                         @ releasing store
2967    b       .LOP_SPUT_OBJECT_end
2968
2969/* ------------------------------ */
2970    .balign 64
2971.L_OP_SPUT_BOOLEAN: /* 0x6a */
2972/* File: armv5te/OP_SPUT_BOOLEAN.S */
2973/* File: armv5te/OP_SPUT.S */
2974    /*
2975     * General 32-bit SPUT handler.
2976     *
2977     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
2978     */
2979    /* op vAA, field@BBBB */
2980    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
2981    FETCH(r1, 1)                        @ r1<- field ref BBBB
2982    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
2983    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
2984    cmp     r0, #0                      @ is resolved entry null?
2985    beq     .LOP_SPUT_BOOLEAN_resolve         @ yes, do resolve
2986.LOP_SPUT_BOOLEAN_finish:   @ field ptr in r0
2987    mov     r2, rINST, lsr #8           @ r2<- AA
2988    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
2989    GET_VREG(r1, r2)                    @ r1<- fp[AA]
2990    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
2991    @ no-op                        @ releasing store
2992    str     r1, [r0, #offStaticField_value] @ field<- vAA
2993    @ no-op
2994    GOTO_OPCODE(ip)                     @ jump to next instruction
2995
2996
2997/* ------------------------------ */
2998    .balign 64
2999.L_OP_SPUT_BYTE: /* 0x6b */
3000/* File: armv5te/OP_SPUT_BYTE.S */
3001/* File: armv5te/OP_SPUT.S */
3002    /*
3003     * General 32-bit SPUT handler.
3004     *
3005     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3006     */
3007    /* op vAA, field@BBBB */
3008    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
3009    FETCH(r1, 1)                        @ r1<- field ref BBBB
3010    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
3011    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
3012    cmp     r0, #0                      @ is resolved entry null?
3013    beq     .LOP_SPUT_BYTE_resolve         @ yes, do resolve
3014.LOP_SPUT_BYTE_finish:   @ field ptr in r0
3015    mov     r2, rINST, lsr #8           @ r2<- AA
3016    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3017    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3018    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3019    @ no-op                        @ releasing store
3020    str     r1, [r0, #offStaticField_value] @ field<- vAA
3021    @ no-op
3022    GOTO_OPCODE(ip)                     @ jump to next instruction
3023
3024
3025/* ------------------------------ */
3026    .balign 64
3027.L_OP_SPUT_CHAR: /* 0x6c */
3028/* File: armv5te/OP_SPUT_CHAR.S */
3029/* File: armv5te/OP_SPUT.S */
3030    /*
3031     * General 32-bit SPUT handler.
3032     *
3033     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3034     */
3035    /* op vAA, field@BBBB */
3036    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
3037    FETCH(r1, 1)                        @ r1<- field ref BBBB
3038    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
3039    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
3040    cmp     r0, #0                      @ is resolved entry null?
3041    beq     .LOP_SPUT_CHAR_resolve         @ yes, do resolve
3042.LOP_SPUT_CHAR_finish:   @ field ptr in r0
3043    mov     r2, rINST, lsr #8           @ r2<- AA
3044    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3045    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3046    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3047    @ no-op                        @ releasing store
3048    str     r1, [r0, #offStaticField_value] @ field<- vAA
3049    @ no-op
3050    GOTO_OPCODE(ip)                     @ jump to next instruction
3051
3052
3053/* ------------------------------ */
3054    .balign 64
3055.L_OP_SPUT_SHORT: /* 0x6d */
3056/* File: armv5te/OP_SPUT_SHORT.S */
3057/* File: armv5te/OP_SPUT.S */
3058    /*
3059     * General 32-bit SPUT handler.
3060     *
3061     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
3062     */
3063    /* op vAA, field@BBBB */
3064    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
3065    FETCH(r1, 1)                        @ r1<- field ref BBBB
3066    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
3067    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
3068    cmp     r0, #0                      @ is resolved entry null?
3069    beq     .LOP_SPUT_SHORT_resolve         @ yes, do resolve
3070.LOP_SPUT_SHORT_finish:   @ field ptr in r0
3071    mov     r2, rINST, lsr #8           @ r2<- AA
3072    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
3073    GET_VREG(r1, r2)                    @ r1<- fp[AA]
3074    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3075    @ no-op                        @ releasing store
3076    str     r1, [r0, #offStaticField_value] @ field<- vAA
3077    @ no-op
3078    GOTO_OPCODE(ip)                     @ jump to next instruction
3079
3080
3081/* ------------------------------ */
3082    .balign 64
3083.L_OP_INVOKE_VIRTUAL: /* 0x6e */
3084/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3085    /*
3086     * Handle a virtual method call.
3087     *
3088     * for: invoke-virtual, invoke-virtual/range
3089     */
3090    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3091    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3092    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3093    FETCH(r1, 1)                        @ r1<- BBBB
3094    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3095    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3096    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3097    .if     (!0)
3098    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3099    .endif
3100    cmp     r0, #0                      @ already resolved?
3101    EXPORT_PC()                         @ must export for invoke
3102    bne     .LOP_INVOKE_VIRTUAL_continue        @ yes, continue on
3103    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
3104    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3105    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3106    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3107    cmp     r0, #0                      @ got null?
3108    bne     .LOP_INVOKE_VIRTUAL_continue        @ no, continue
3109    b       common_exceptionThrown      @ yes, handle exception
3110
3111/* ------------------------------ */
3112    .balign 64
3113.L_OP_INVOKE_SUPER: /* 0x6f */
3114/* File: armv5te/OP_INVOKE_SUPER.S */
3115    /*
3116     * Handle a "super" method call.
3117     *
3118     * for: invoke-super, invoke-super/range
3119     */
3120    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3121    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3122    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3123    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3124    .if     (!0)
3125    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3126    .endif
3127    FETCH(r1, 1)                        @ r1<- BBBB
3128    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3129    GET_VREG(r9, r10)                   @ r9<- "this" ptr
3130    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3131    cmp     r9, #0                      @ null "this"?
3132    ldr     r10, [rSELF, #offThread_method] @ r10<- current method
3133    beq     common_errNullObject        @ null "this", throw exception
3134    cmp     r0, #0                      @ already resolved?
3135    ldr     r10, [r10, #offMethod_clazz]  @ r10<- method->clazz
3136    EXPORT_PC()                         @ must export for invoke
3137    bne     .LOP_INVOKE_SUPER_continue        @ resolved, continue on
3138    b       .LOP_INVOKE_SUPER_resolve         @ do resolve now
3139
3140/* ------------------------------ */
3141    .balign 64
3142.L_OP_INVOKE_DIRECT: /* 0x70 */
3143/* File: armv5te/OP_INVOKE_DIRECT.S */
3144    /*
3145     * Handle a direct method call.
3146     *
3147     * (We could defer the "is 'this' pointer null" test to the common
3148     * method invocation code, and use a flag to indicate that static
3149     * calls don't count.  If we do this as part of copying the arguments
3150     * out we could avoiding loading the first arg twice.)
3151     *
3152     * for: invoke-direct, invoke-direct/range
3153     */
3154    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3155    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3156    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3157    FETCH(r1, 1)                        @ r1<- BBBB
3158    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3159    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3160    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3161    .if     (!0)
3162    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3163    .endif
3164    cmp     r0, #0                      @ already resolved?
3165    EXPORT_PC()                         @ must export for invoke
3166    GET_VREG(r9, r10)                   @ r9<- "this" ptr
3167    beq     .LOP_INVOKE_DIRECT_resolve         @ not resolved, do it now
3168.LOP_INVOKE_DIRECT_finish:
3169    cmp     r9, #0                      @ null "this" ref?
3170    bne     common_invokeMethodNoRange   @ r0=method, r9="this"
3171    b       common_errNullObject        @ yes, throw exception
3172
3173/* ------------------------------ */
3174    .balign 64
3175.L_OP_INVOKE_STATIC: /* 0x71 */
3176/* File: armv5te/OP_INVOKE_STATIC.S */
3177    /*
3178     * Handle a static method call.
3179     *
3180     * for: invoke-static, invoke-static/range
3181     */
3182    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3183    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3184    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3185    FETCH(r1, 1)                        @ r1<- BBBB
3186    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3187    mov     r9, #0                      @ null "this" in delay slot
3188    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3189#if defined(WITH_JIT)
3190    add     r10, r3, r1, lsl #2         @ r10<- &resolved_methodToCall
3191#endif
3192    cmp     r0, #0                      @ already resolved?
3193    EXPORT_PC()                         @ must export for invoke
3194    bne     common_invokeMethodNoRange @ yes, continue on
3195    b       .LOP_INVOKE_STATIC_resolve
3196
3197/* ------------------------------ */
3198    .balign 64
3199.L_OP_INVOKE_INTERFACE: /* 0x72 */
3200/* File: armv5te/OP_INVOKE_INTERFACE.S */
3201    /*
3202     * Handle an interface method call.
3203     *
3204     * for: invoke-interface, invoke-interface/range
3205     */
3206    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3207    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3208    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3209    FETCH(r1, 1)                        @ r1<- BBBB
3210    .if     (!0)
3211    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3212    .endif
3213    EXPORT_PC()                         @ must export for invoke
3214    GET_VREG(r9, r2)                    @ r9<- first arg ("this")
3215    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- methodClassDex
3216    cmp     r9, #0                      @ null obj?
3217    ldr     r2, [rSELF, #offThread_method]  @ r2<- method
3218    beq     common_errNullObject        @ yes, fail
3219    ldr     r0, [r9, #offObject_clazz]  @ r0<- thisPtr->clazz
3220    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3221    cmp     r0, #0                      @ failed?
3222    beq     common_exceptionThrown      @ yes, handle exception
3223    b       common_invokeMethodNoRange @ (r0=method, r9="this")
3224
3225/* ------------------------------ */
3226    .balign 64
3227.L_OP_UNUSED_73: /* 0x73 */
3228/* File: armv5te/OP_UNUSED_73.S */
3229/* File: armv5te/unused.S */
3230    bl      common_abort
3231
3232
3233/* ------------------------------ */
3234    .balign 64
3235.L_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
3236/* File: armv5te/OP_INVOKE_VIRTUAL_RANGE.S */
3237/* File: armv5te/OP_INVOKE_VIRTUAL.S */
3238    /*
3239     * Handle a virtual method call.
3240     *
3241     * for: invoke-virtual, invoke-virtual/range
3242     */
3243    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3244    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3245    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3246    FETCH(r1, 1)                        @ r1<- BBBB
3247    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3248    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3249    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3250    .if     (!1)
3251    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3252    .endif
3253    cmp     r0, #0                      @ already resolved?
3254    EXPORT_PC()                         @ must export for invoke
3255    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ yes, continue on
3256    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
3257    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
3258    mov     r2, #METHOD_VIRTUAL         @ resolver method type
3259    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
3260    cmp     r0, #0                      @ got null?
3261    bne     .LOP_INVOKE_VIRTUAL_RANGE_continue        @ no, continue
3262    b       common_exceptionThrown      @ yes, handle exception
3263
3264
3265/* ------------------------------ */
3266    .balign 64
3267.L_OP_INVOKE_SUPER_RANGE: /* 0x75 */
3268/* File: armv5te/OP_INVOKE_SUPER_RANGE.S */
3269/* File: armv5te/OP_INVOKE_SUPER.S */
3270    /*
3271     * Handle a "super" method call.
3272     *
3273     * for: invoke-super, invoke-super/range
3274     */
3275    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3276    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3277    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3278    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3279    .if     (!1)
3280    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3281    .endif
3282    FETCH(r1, 1)                        @ r1<- BBBB
3283    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3284    GET_VREG(r9, r10)                   @ r9<- "this" ptr
3285    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved baseMethod
3286    cmp     r9, #0                      @ null "this"?
3287    ldr     r10, [rSELF, #offThread_method] @ r10<- current method
3288    beq     common_errNullObject        @ null "this", throw exception
3289    cmp     r0, #0                      @ already resolved?
3290    ldr     r10, [r10, #offMethod_clazz]  @ r10<- method->clazz
3291    EXPORT_PC()                         @ must export for invoke
3292    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ resolved, continue on
3293    b       .LOP_INVOKE_SUPER_RANGE_resolve         @ do resolve now
3294
3295
3296/* ------------------------------ */
3297    .balign 64
3298.L_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
3299/* File: armv5te/OP_INVOKE_DIRECT_RANGE.S */
3300/* File: armv5te/OP_INVOKE_DIRECT.S */
3301    /*
3302     * Handle a direct method call.
3303     *
3304     * (We could defer the "is 'this' pointer null" test to the common
3305     * method invocation code, and use a flag to indicate that static
3306     * calls don't count.  If we do this as part of copying the arguments
3307     * out we could avoiding loading the first arg twice.)
3308     *
3309     * for: invoke-direct, invoke-direct/range
3310     */
3311    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3312    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3313    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3314    FETCH(r1, 1)                        @ r1<- BBBB
3315    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3316    FETCH(r10, 2)                       @ r10<- GFED or CCCC
3317    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3318    .if     (!1)
3319    and     r10, r10, #15               @ r10<- D (or stays CCCC)
3320    .endif
3321    cmp     r0, #0                      @ already resolved?
3322    EXPORT_PC()                         @ must export for invoke
3323    GET_VREG(r9, r10)                   @ r9<- "this" ptr
3324    beq     .LOP_INVOKE_DIRECT_RANGE_resolve         @ not resolved, do it now
3325.LOP_INVOKE_DIRECT_RANGE_finish:
3326    cmp     r9, #0                      @ null "this" ref?
3327    bne     common_invokeMethodRange   @ r0=method, r9="this"
3328    b       common_errNullObject        @ yes, throw exception
3329
3330
3331/* ------------------------------ */
3332    .balign 64
3333.L_OP_INVOKE_STATIC_RANGE: /* 0x77 */
3334/* File: armv5te/OP_INVOKE_STATIC_RANGE.S */
3335/* File: armv5te/OP_INVOKE_STATIC.S */
3336    /*
3337     * Handle a static method call.
3338     *
3339     * for: invoke-static, invoke-static/range
3340     */
3341    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3342    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3343    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- pDvmDex
3344    FETCH(r1, 1)                        @ r1<- BBBB
3345    ldr     r3, [r3, #offDvmDex_pResMethods]    @ r3<- pDvmDex->pResMethods
3346    mov     r9, #0                      @ null "this" in delay slot
3347    ldr     r0, [r3, r1, lsl #2]        @ r0<- resolved methodToCall
3348#if defined(WITH_JIT)
3349    add     r10, r3, r1, lsl #2         @ r10<- &resolved_methodToCall
3350#endif
3351    cmp     r0, #0                      @ already resolved?
3352    EXPORT_PC()                         @ must export for invoke
3353    bne     common_invokeMethodRange @ yes, continue on
3354    b       .LOP_INVOKE_STATIC_RANGE_resolve
3355
3356
3357/* ------------------------------ */
3358    .balign 64
3359.L_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
3360/* File: armv5te/OP_INVOKE_INTERFACE_RANGE.S */
3361/* File: armv5te/OP_INVOKE_INTERFACE.S */
3362    /*
3363     * Handle an interface method call.
3364     *
3365     * for: invoke-interface, invoke-interface/range
3366     */
3367    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
3368    /* op {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
3369    FETCH(r2, 2)                        @ r2<- FEDC or CCCC
3370    FETCH(r1, 1)                        @ r1<- BBBB
3371    .if     (!1)
3372    and     r2, r2, #15                 @ r2<- C (or stays CCCC)
3373    .endif
3374    EXPORT_PC()                         @ must export for invoke
3375    GET_VREG(r9, r2)                    @ r9<- first arg ("this")
3376    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- methodClassDex
3377    cmp     r9, #0                      @ null obj?
3378    ldr     r2, [rSELF, #offThread_method]  @ r2<- method
3379    beq     common_errNullObject        @ yes, fail
3380    ldr     r0, [r9, #offObject_clazz]  @ r0<- thisPtr->clazz
3381    bl      dvmFindInterfaceMethodInCache @ r0<- call(class, ref, method, dex)
3382    cmp     r0, #0                      @ failed?
3383    beq     common_exceptionThrown      @ yes, handle exception
3384    b       common_invokeMethodRange @ (r0=method, r9="this")
3385
3386
3387/* ------------------------------ */
3388    .balign 64
3389.L_OP_UNUSED_79: /* 0x79 */
3390/* File: armv5te/OP_UNUSED_79.S */
3391/* File: armv5te/unused.S */
3392    bl      common_abort
3393
3394
3395/* ------------------------------ */
3396    .balign 64
3397.L_OP_UNUSED_7A: /* 0x7a */
3398/* File: armv5te/OP_UNUSED_7A.S */
3399/* File: armv5te/unused.S */
3400    bl      common_abort
3401
3402
3403/* ------------------------------ */
3404    .balign 64
3405.L_OP_NEG_INT: /* 0x7b */
3406/* File: armv5te/OP_NEG_INT.S */
3407/* File: armv5te/unop.S */
3408    /*
3409     * Generic 32-bit unary operation.  Provide an "instr" line that
3410     * specifies an instruction that performs "result = op r0".
3411     * This could be an ARM instruction or a function call.
3412     *
3413     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3414     *      int-to-byte, int-to-char, int-to-short
3415     */
3416    /* unop vA, vB */
3417    mov     r3, rINST, lsr #12          @ r3<- B
3418    mov     r9, rINST, lsr #8           @ r9<- A+
3419    GET_VREG(r0, r3)                    @ r0<- vB
3420    and     r9, r9, #15
3421                               @ optional op; may set condition codes
3422    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3423    rsb     r0, r0, #0                              @ r0<- op, r0-r3 changed
3424    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3425    SET_VREG(r0, r9)                    @ vAA<- r0
3426    GOTO_OPCODE(ip)                     @ jump to next instruction
3427    /* 9-10 instructions */
3428
3429
3430/* ------------------------------ */
3431    .balign 64
3432.L_OP_NOT_INT: /* 0x7c */
3433/* File: armv5te/OP_NOT_INT.S */
3434/* File: armv5te/unop.S */
3435    /*
3436     * Generic 32-bit unary operation.  Provide an "instr" line that
3437     * specifies an instruction that performs "result = op r0".
3438     * This could be an ARM instruction or a function call.
3439     *
3440     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3441     *      int-to-byte, int-to-char, int-to-short
3442     */
3443    /* unop vA, vB */
3444    mov     r3, rINST, lsr #12          @ r3<- B
3445    mov     r9, rINST, lsr #8           @ r9<- A+
3446    GET_VREG(r0, r3)                    @ r0<- vB
3447    and     r9, r9, #15
3448                               @ optional op; may set condition codes
3449    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3450    mvn     r0, r0                              @ r0<- op, r0-r3 changed
3451    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3452    SET_VREG(r0, r9)                    @ vAA<- r0
3453    GOTO_OPCODE(ip)                     @ jump to next instruction
3454    /* 9-10 instructions */
3455
3456
3457/* ------------------------------ */
3458    .balign 64
3459.L_OP_NEG_LONG: /* 0x7d */
3460/* File: armv5te/OP_NEG_LONG.S */
3461/* File: armv5te/unopWide.S */
3462    /*
3463     * Generic 64-bit unary operation.  Provide an "instr" line that
3464     * specifies an instruction that performs "result = op r0/r1".
3465     * This could be an ARM instruction or a function call.
3466     *
3467     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3468     */
3469    /* unop vA, vB */
3470    mov     r9, rINST, lsr #8           @ r9<- A+
3471    mov     r3, rINST, lsr #12          @ r3<- B
3472    and     r9, r9, #15
3473    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3474    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3475    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3476    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3477    rsbs    r0, r0, #0                           @ optional op; may set condition codes
3478    rsc     r1, r1, #0                              @ r0/r1<- op, r2-r3 changed
3479    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3480    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3481    GOTO_OPCODE(ip)                     @ jump to next instruction
3482    /* 12-13 instructions */
3483
3484
3485/* ------------------------------ */
3486    .balign 64
3487.L_OP_NOT_LONG: /* 0x7e */
3488/* File: armv5te/OP_NOT_LONG.S */
3489/* File: armv5te/unopWide.S */
3490    /*
3491     * Generic 64-bit unary operation.  Provide an "instr" line that
3492     * specifies an instruction that performs "result = op r0/r1".
3493     * This could be an ARM instruction or a function call.
3494     *
3495     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3496     */
3497    /* unop vA, vB */
3498    mov     r9, rINST, lsr #8           @ r9<- A+
3499    mov     r3, rINST, lsr #12          @ r3<- B
3500    and     r9, r9, #15
3501    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3502    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3503    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3504    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3505    mvn     r0, r0                           @ optional op; may set condition codes
3506    mvn     r1, r1                              @ r0/r1<- op, r2-r3 changed
3507    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3508    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3509    GOTO_OPCODE(ip)                     @ jump to next instruction
3510    /* 12-13 instructions */
3511
3512
3513/* ------------------------------ */
3514    .balign 64
3515.L_OP_NEG_FLOAT: /* 0x7f */
3516/* File: armv5te/OP_NEG_FLOAT.S */
3517/* File: armv5te/unop.S */
3518    /*
3519     * Generic 32-bit unary operation.  Provide an "instr" line that
3520     * specifies an instruction that performs "result = op r0".
3521     * This could be an ARM instruction or a function call.
3522     *
3523     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3524     *      int-to-byte, int-to-char, int-to-short
3525     */
3526    /* unop vA, vB */
3527    mov     r3, rINST, lsr #12          @ r3<- B
3528    mov     r9, rINST, lsr #8           @ r9<- A+
3529    GET_VREG(r0, r3)                    @ r0<- vB
3530    and     r9, r9, #15
3531                               @ optional op; may set condition codes
3532    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3533    add     r0, r0, #0x80000000                              @ r0<- op, r0-r3 changed
3534    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3535    SET_VREG(r0, r9)                    @ vAA<- r0
3536    GOTO_OPCODE(ip)                     @ jump to next instruction
3537    /* 9-10 instructions */
3538
3539
3540/* ------------------------------ */
3541    .balign 64
3542.L_OP_NEG_DOUBLE: /* 0x80 */
3543/* File: armv5te/OP_NEG_DOUBLE.S */
3544/* File: armv5te/unopWide.S */
3545    /*
3546     * Generic 64-bit unary operation.  Provide an "instr" line that
3547     * specifies an instruction that performs "result = op r0/r1".
3548     * This could be an ARM instruction or a function call.
3549     *
3550     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3551     */
3552    /* unop vA, vB */
3553    mov     r9, rINST, lsr #8           @ r9<- A+
3554    mov     r3, rINST, lsr #12          @ r3<- B
3555    and     r9, r9, #15
3556    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3557    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3558    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3559    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3560                               @ optional op; may set condition codes
3561    add     r1, r1, #0x80000000                              @ r0/r1<- op, r2-r3 changed
3562    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3563    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3564    GOTO_OPCODE(ip)                     @ jump to next instruction
3565    /* 12-13 instructions */
3566
3567
3568/* ------------------------------ */
3569    .balign 64
3570.L_OP_INT_TO_LONG: /* 0x81 */
3571/* File: armv5te/OP_INT_TO_LONG.S */
3572/* File: armv5te/unopWider.S */
3573    /*
3574     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3575     * that specifies an instruction that performs "result = op r0", where
3576     * "result" is a 64-bit quantity in r0/r1.
3577     *
3578     * For: int-to-long, int-to-double, float-to-long, float-to-double
3579     */
3580    /* unop vA, vB */
3581    mov     r9, rINST, lsr #8           @ r9<- A+
3582    mov     r3, rINST, lsr #12          @ r3<- B
3583    and     r9, r9, #15
3584    GET_VREG(r0, r3)                    @ r0<- vB
3585    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3586                               @ optional op; may set condition codes
3587    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3588    mov     r1, r0, asr #31                              @ r0<- op, r0-r3 changed
3589    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3590    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3591    GOTO_OPCODE(ip)                     @ jump to next instruction
3592    /* 10-11 instructions */
3593
3594
3595/* ------------------------------ */
3596    .balign 64
3597.L_OP_INT_TO_FLOAT: /* 0x82 */
3598/* File: armv5te/OP_INT_TO_FLOAT.S */
3599/* File: armv5te/unop.S */
3600    /*
3601     * Generic 32-bit unary operation.  Provide an "instr" line that
3602     * specifies an instruction that performs "result = op r0".
3603     * This could be an ARM instruction or a function call.
3604     *
3605     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3606     *      int-to-byte, int-to-char, int-to-short
3607     */
3608    /* unop vA, vB */
3609    mov     r3, rINST, lsr #12          @ r3<- B
3610    mov     r9, rINST, lsr #8           @ r9<- A+
3611    GET_VREG(r0, r3)                    @ r0<- vB
3612    and     r9, r9, #15
3613                               @ optional op; may set condition codes
3614    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3615    bl      __aeabi_i2f                              @ r0<- op, r0-r3 changed
3616    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3617    SET_VREG(r0, r9)                    @ vAA<- r0
3618    GOTO_OPCODE(ip)                     @ jump to next instruction
3619    /* 9-10 instructions */
3620
3621
3622/* ------------------------------ */
3623    .balign 64
3624.L_OP_INT_TO_DOUBLE: /* 0x83 */
3625/* File: armv5te/OP_INT_TO_DOUBLE.S */
3626/* File: armv5te/unopWider.S */
3627    /*
3628     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3629     * that specifies an instruction that performs "result = op r0", where
3630     * "result" is a 64-bit quantity in r0/r1.
3631     *
3632     * For: int-to-long, int-to-double, float-to-long, float-to-double
3633     */
3634    /* unop vA, vB */
3635    mov     r9, rINST, lsr #8           @ r9<- A+
3636    mov     r3, rINST, lsr #12          @ r3<- B
3637    and     r9, r9, #15
3638    GET_VREG(r0, r3)                    @ r0<- vB
3639    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3640                               @ optional op; may set condition codes
3641    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3642    bl      __aeabi_i2d                              @ r0<- op, r0-r3 changed
3643    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3644    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3645    GOTO_OPCODE(ip)                     @ jump to next instruction
3646    /* 10-11 instructions */
3647
3648
3649/* ------------------------------ */
3650    .balign 64
3651.L_OP_LONG_TO_INT: /* 0x84 */
3652/* File: armv5te/OP_LONG_TO_INT.S */
3653/* we ignore the high word, making this equivalent to a 32-bit reg move */
3654/* File: armv5te/OP_MOVE.S */
3655    /* for move, move-object, long-to-int */
3656    /* op vA, vB */
3657    mov     r1, rINST, lsr #12          @ r1<- B from 15:12
3658    mov     r0, rINST, lsr #8           @ r0<- A from 11:8
3659    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3660    GET_VREG(r2, r1)                    @ r2<- fp[B]
3661    and     r0, r0, #15
3662    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
3663    SET_VREG(r2, r0)                    @ fp[A]<- r2
3664    GOTO_OPCODE(ip)                     @ execute next instruction
3665
3666
3667/* ------------------------------ */
3668    .balign 64
3669.L_OP_LONG_TO_FLOAT: /* 0x85 */
3670/* File: armv5te/OP_LONG_TO_FLOAT.S */
3671/* File: armv5te/unopNarrower.S */
3672    /*
3673     * Generic 64bit-to-32bit unary operation.  Provide an "instr" line
3674     * that specifies an instruction that performs "result = op r0/r1", where
3675     * "result" is a 32-bit quantity in r0.
3676     *
3677     * For: long-to-float, double-to-int, double-to-float
3678     *
3679     * (This would work for long-to-int, but that instruction is actually
3680     * an exact match for OP_MOVE.)
3681     */
3682    /* unop vA, vB */
3683    mov     r3, rINST, lsr #12          @ r3<- B
3684    mov     r9, rINST, lsr #8           @ r9<- A+
3685    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3686    and     r9, r9, #15
3687    ldmia   r3, {r0-r1}                 @ r0/r1<- vB/vB+1
3688    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3689                               @ optional op; may set condition codes
3690    bl      __aeabi_l2f                              @ r0<- op, r0-r3 changed
3691    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3692    SET_VREG(r0, r9)                    @ vA<- r0
3693    GOTO_OPCODE(ip)                     @ jump to next instruction
3694    /* 10-11 instructions */
3695
3696
3697/* ------------------------------ */
3698    .balign 64
3699.L_OP_LONG_TO_DOUBLE: /* 0x86 */
3700/* File: armv5te/OP_LONG_TO_DOUBLE.S */
3701/* File: armv5te/unopWide.S */
3702    /*
3703     * Generic 64-bit unary operation.  Provide an "instr" line that
3704     * specifies an instruction that performs "result = op r0/r1".
3705     * This could be an ARM instruction or a function call.
3706     *
3707     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3708     */
3709    /* unop vA, vB */
3710    mov     r9, rINST, lsr #8           @ r9<- A+
3711    mov     r3, rINST, lsr #12          @ r3<- B
3712    and     r9, r9, #15
3713    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3714    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3715    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3716    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3717                               @ optional op; may set condition codes
3718    bl      __aeabi_l2d                              @ r0/r1<- op, r2-r3 changed
3719    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3720    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3721    GOTO_OPCODE(ip)                     @ jump to next instruction
3722    /* 12-13 instructions */
3723
3724
3725/* ------------------------------ */
3726    .balign 64
3727.L_OP_FLOAT_TO_INT: /* 0x87 */
3728/* File: armv5te/OP_FLOAT_TO_INT.S */
3729/* EABI appears to have Java-style conversions of +inf/-inf/NaN */
3730/* File: armv5te/unop.S */
3731    /*
3732     * Generic 32-bit unary operation.  Provide an "instr" line that
3733     * specifies an instruction that performs "result = op r0".
3734     * This could be an ARM instruction or a function call.
3735     *
3736     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3737     *      int-to-byte, int-to-char, int-to-short
3738     */
3739    /* unop vA, vB */
3740    mov     r3, rINST, lsr #12          @ r3<- B
3741    mov     r9, rINST, lsr #8           @ r9<- A+
3742    GET_VREG(r0, r3)                    @ r0<- vB
3743    and     r9, r9, #15
3744                               @ optional op; may set condition codes
3745    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3746    bl      __aeabi_f2iz                              @ r0<- op, r0-r3 changed
3747    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3748    SET_VREG(r0, r9)                    @ vAA<- r0
3749    GOTO_OPCODE(ip)                     @ jump to next instruction
3750    /* 9-10 instructions */
3751
3752
3753#if 0
3754@include "armv5te/unop.S" {"instr":"bl      f2i_doconv"}
3755@break
3756/*
3757 * Convert the float in r0 to an int in r0.
3758 *
3759 * We have to clip values to int min/max per the specification.  The
3760 * expected common case is a "reasonable" value that converts directly
3761 * to modest integer.  The EABI convert function isn't doing this for us.
3762 */
3763f2i_doconv:
3764    stmfd   sp!, {r4, lr}
3765    mov     r1, #0x4f000000             @ (float)maxint
3766    mov     r4, r0
3767    bl      __aeabi_fcmpge              @ is arg >= maxint?
3768    cmp     r0, #0                      @ nonzero == yes
3769    mvnne   r0, #0x80000000             @ return maxint (7fffffff)
3770    ldmnefd sp!, {r4, pc}
3771
3772    mov     r0, r4                      @ recover arg
3773    mov     r1, #0xcf000000             @ (float)minint
3774    bl      __aeabi_fcmple              @ is arg <= minint?
3775    cmp     r0, #0                      @ nonzero == yes
3776    movne   r0, #0x80000000             @ return minint (80000000)
3777    ldmnefd sp!, {r4, pc}
3778
3779    mov     r0, r4                      @ recover arg
3780    mov     r1, r4
3781    bl      __aeabi_fcmpeq              @ is arg == self?
3782    cmp     r0, #0                      @ zero == no
3783    ldmeqfd sp!, {r4, pc}               @ return zero for NaN
3784
3785    mov     r0, r4                      @ recover arg
3786    bl      __aeabi_f2iz                @ convert float to int
3787    ldmfd   sp!, {r4, pc}
3788#endif
3789
3790/* ------------------------------ */
3791    .balign 64
3792.L_OP_FLOAT_TO_LONG: /* 0x88 */
3793/* File: armv5te/OP_FLOAT_TO_LONG.S */
3794@include "armv5te/unopWider.S" {"instr":"bl      __aeabi_f2lz"}
3795/* File: armv5te/unopWider.S */
3796    /*
3797     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3798     * that specifies an instruction that performs "result = op r0", where
3799     * "result" is a 64-bit quantity in r0/r1.
3800     *
3801     * For: int-to-long, int-to-double, float-to-long, float-to-double
3802     */
3803    /* unop vA, vB */
3804    mov     r9, rINST, lsr #8           @ r9<- A+
3805    mov     r3, rINST, lsr #12          @ r3<- B
3806    and     r9, r9, #15
3807    GET_VREG(r0, r3)                    @ r0<- vB
3808    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3809                               @ optional op; may set condition codes
3810    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3811    bl      f2l_doconv                              @ r0<- op, r0-r3 changed
3812    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3813    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3814    GOTO_OPCODE(ip)                     @ jump to next instruction
3815    /* 10-11 instructions */
3816
3817
3818
3819/* ------------------------------ */
3820    .balign 64
3821.L_OP_FLOAT_TO_DOUBLE: /* 0x89 */
3822/* File: armv5te/OP_FLOAT_TO_DOUBLE.S */
3823/* File: armv5te/unopWider.S */
3824    /*
3825     * Generic 32bit-to-64bit unary operation.  Provide an "instr" line
3826     * that specifies an instruction that performs "result = op r0", where
3827     * "result" is a 64-bit quantity in r0/r1.
3828     *
3829     * For: int-to-long, int-to-double, float-to-long, float-to-double
3830     */
3831    /* unop vA, vB */
3832    mov     r9, rINST, lsr #8           @ r9<- A+
3833    mov     r3, rINST, lsr #12          @ r3<- B
3834    and     r9, r9, #15
3835    GET_VREG(r0, r3)                    @ r0<- vB
3836    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3837                               @ optional op; may set condition codes
3838    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3839    bl      __aeabi_f2d                              @ r0<- op, r0-r3 changed
3840    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3841    stmia   r9, {r0-r1}                 @ vA/vA+1<- r0/r1
3842    GOTO_OPCODE(ip)                     @ jump to next instruction
3843    /* 10-11 instructions */
3844
3845
3846/* ------------------------------ */
3847    .balign 64
3848.L_OP_DOUBLE_TO_INT: /* 0x8a */
3849/* File: armv5te/OP_DOUBLE_TO_INT.S */
3850/* EABI appears to have Java-style conversions of +inf/-inf/NaN */
3851/* File: armv5te/unopNarrower.S */
3852    /*
3853     * Generic 64bit-to-32bit unary operation.  Provide an "instr" line
3854     * that specifies an instruction that performs "result = op r0/r1", where
3855     * "result" is a 32-bit quantity in r0.
3856     *
3857     * For: long-to-float, double-to-int, double-to-float
3858     *
3859     * (This would work for long-to-int, but that instruction is actually
3860     * an exact match for OP_MOVE.)
3861     */
3862    /* unop vA, vB */
3863    mov     r3, rINST, lsr #12          @ r3<- B
3864    mov     r9, rINST, lsr #8           @ r9<- A+
3865    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3866    and     r9, r9, #15
3867    ldmia   r3, {r0-r1}                 @ r0/r1<- vB/vB+1
3868    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3869                               @ optional op; may set condition codes
3870    bl      __aeabi_d2iz                              @ r0<- op, r0-r3 changed
3871    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3872    SET_VREG(r0, r9)                    @ vA<- r0
3873    GOTO_OPCODE(ip)                     @ jump to next instruction
3874    /* 10-11 instructions */
3875
3876
3877#if 0
3878@include "armv5te/unopNarrower.S" {"instr":"bl      d2i_doconv"}
3879@break
3880/*
3881 * Convert the double in r0/r1 to an int in r0.
3882 *
3883 * We have to clip values to int min/max per the specification.  The
3884 * expected common case is a "reasonable" value that converts directly
3885 * to modest integer.  The EABI convert function isn't doing this for us.
3886 */
3887d2i_doconv:
3888    stmfd   sp!, {r4, r5, lr}           @ save regs
3889    mov     r2, #0x80000000             @ maxint, as a double (low word)
3890    mov     r2, r2, asr #9              @  0xffc00000
3891    sub     sp, sp, #4                  @ align for EABI
3892    mvn     r3, #0xbe000000             @ maxint, as a double (high word)
3893    sub     r3, r3, #0x00200000         @  0x41dfffff
3894    mov     r4, r0                      @ save a copy of r0
3895    mov     r5, r1                      @  and r1
3896    bl      __aeabi_dcmpge              @ is arg >= maxint?
3897    cmp     r0, #0                      @ nonzero == yes
3898    mvnne   r0, #0x80000000             @ return maxint (0x7fffffff)
3899    bne     1f
3900
3901    mov     r0, r4                      @ recover arg
3902    mov     r1, r5
3903    mov     r3, #0xc1000000             @ minint, as a double (high word)
3904    add     r3, r3, #0x00e00000         @  0xc1e00000
3905    mov     r2, #0                      @ minint, as a double (low word)
3906    bl      __aeabi_dcmple              @ is arg <= minint?
3907    cmp     r0, #0                      @ nonzero == yes
3908    movne   r0, #0x80000000             @ return minint (80000000)
3909    bne     1f
3910
3911    mov     r0, r4                      @ recover arg
3912    mov     r1, r5
3913    mov     r2, r4                      @ compare against self
3914    mov     r3, r5
3915    bl      __aeabi_dcmpeq              @ is arg == self?
3916    cmp     r0, #0                      @ zero == no
3917    beq     1f                          @ return zero for NaN
3918
3919    mov     r0, r4                      @ recover arg
3920    mov     r1, r5
3921    bl      __aeabi_d2iz                @ convert double to int
3922
39231:
3924    add     sp, sp, #4
3925    ldmfd   sp!, {r4, r5, pc}
3926#endif
3927
3928/* ------------------------------ */
3929    .balign 64
3930.L_OP_DOUBLE_TO_LONG: /* 0x8b */
3931/* File: armv5te/OP_DOUBLE_TO_LONG.S */
3932@include "armv5te/unopWide.S" {"instr":"bl      __aeabi_d2lz"}
3933/* File: armv5te/unopWide.S */
3934    /*
3935     * Generic 64-bit unary operation.  Provide an "instr" line that
3936     * specifies an instruction that performs "result = op r0/r1".
3937     * This could be an ARM instruction or a function call.
3938     *
3939     * For: neg-long, not-long, neg-double, long-to-double, double-to-long
3940     */
3941    /* unop vA, vB */
3942    mov     r9, rINST, lsr #8           @ r9<- A+
3943    mov     r3, rINST, lsr #12          @ r3<- B
3944    and     r9, r9, #15
3945    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3946    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
3947    ldmia   r3, {r0-r1}                 @ r0/r1<- vAA
3948    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3949                               @ optional op; may set condition codes
3950    bl      d2l_doconv                              @ r0/r1<- op, r2-r3 changed
3951    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3952    stmia   r9, {r0-r1}                 @ vAA<- r0/r1
3953    GOTO_OPCODE(ip)                     @ jump to next instruction
3954    /* 12-13 instructions */
3955
3956
3957
3958/* ------------------------------ */
3959    .balign 64
3960.L_OP_DOUBLE_TO_FLOAT: /* 0x8c */
3961/* File: armv5te/OP_DOUBLE_TO_FLOAT.S */
3962/* File: armv5te/unopNarrower.S */
3963    /*
3964     * Generic 64bit-to-32bit unary operation.  Provide an "instr" line
3965     * that specifies an instruction that performs "result = op r0/r1", where
3966     * "result" is a 32-bit quantity in r0.
3967     *
3968     * For: long-to-float, double-to-int, double-to-float
3969     *
3970     * (This would work for long-to-int, but that instruction is actually
3971     * an exact match for OP_MOVE.)
3972     */
3973    /* unop vA, vB */
3974    mov     r3, rINST, lsr #12          @ r3<- B
3975    mov     r9, rINST, lsr #8           @ r9<- A+
3976    add     r3, rFP, r3, lsl #2         @ r3<- &fp[B]
3977    and     r9, r9, #15
3978    ldmia   r3, {r0-r1}                 @ r0/r1<- vB/vB+1
3979    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
3980                               @ optional op; may set condition codes
3981    bl      __aeabi_d2f                              @ r0<- op, r0-r3 changed
3982    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
3983    SET_VREG(r0, r9)                    @ vA<- r0
3984    GOTO_OPCODE(ip)                     @ jump to next instruction
3985    /* 10-11 instructions */
3986
3987
3988/* ------------------------------ */
3989    .balign 64
3990.L_OP_INT_TO_BYTE: /* 0x8d */
3991/* File: armv5te/OP_INT_TO_BYTE.S */
3992/* File: armv5te/unop.S */
3993    /*
3994     * Generic 32-bit unary operation.  Provide an "instr" line that
3995     * specifies an instruction that performs "result = op r0".
3996     * This could be an ARM instruction or a function call.
3997     *
3998     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
3999     *      int-to-byte, int-to-char, int-to-short
4000     */
4001    /* unop vA, vB */
4002    mov     r3, rINST, lsr #12          @ r3<- B
4003    mov     r9, rINST, lsr #8           @ r9<- A+
4004    GET_VREG(r0, r3)                    @ r0<- vB
4005    and     r9, r9, #15
4006    mov     r0, r0, asl #24                           @ optional op; may set condition codes
4007    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
4008    mov     r0, r0, asr #24                              @ r0<- op, r0-r3 changed
4009    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4010    SET_VREG(r0, r9)                    @ vAA<- r0
4011    GOTO_OPCODE(ip)                     @ jump to next instruction
4012    /* 9-10 instructions */
4013
4014
4015/* ------------------------------ */
4016    .balign 64
4017.L_OP_INT_TO_CHAR: /* 0x8e */
4018/* File: armv5te/OP_INT_TO_CHAR.S */
4019/* File: armv5te/unop.S */
4020    /*
4021     * Generic 32-bit unary operation.  Provide an "instr" line that
4022     * specifies an instruction that performs "result = op r0".
4023     * This could be an ARM instruction or a function call.
4024     *
4025     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
4026     *      int-to-byte, int-to-char, int-to-short
4027     */
4028    /* unop vA, vB */
4029    mov     r3, rINST, lsr #12          @ r3<- B
4030    mov     r9, rINST, lsr #8           @ r9<- A+
4031    GET_VREG(r0, r3)                    @ r0<- vB
4032    and     r9, r9, #15
4033    mov     r0, r0, asl #16                           @ optional op; may set condition codes
4034    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
4035    mov     r0, r0, lsr #16                              @ r0<- op, r0-r3 changed
4036    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4037    SET_VREG(r0, r9)                    @ vAA<- r0
4038    GOTO_OPCODE(ip)                     @ jump to next instruction
4039    /* 9-10 instructions */
4040
4041
4042/* ------------------------------ */
4043    .balign 64
4044.L_OP_INT_TO_SHORT: /* 0x8f */
4045/* File: armv5te/OP_INT_TO_SHORT.S */
4046/* File: armv5te/unop.S */
4047    /*
4048     * Generic 32-bit unary operation.  Provide an "instr" line that
4049     * specifies an instruction that performs "result = op r0".
4050     * This could be an ARM instruction or a function call.
4051     *
4052     * for: neg-int, not-int, neg-float, int-to-float, float-to-int,
4053     *      int-to-byte, int-to-char, int-to-short
4054     */
4055    /* unop vA, vB */
4056    mov     r3, rINST, lsr #12          @ r3<- B
4057    mov     r9, rINST, lsr #8           @ r9<- A+
4058    GET_VREG(r0, r3)                    @ r0<- vB
4059    and     r9, r9, #15
4060    mov     r0, r0, asl #16                           @ optional op; may set condition codes
4061    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
4062    mov     r0, r0, asr #16                              @ r0<- op, r0-r3 changed
4063    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4064    SET_VREG(r0, r9)                    @ vAA<- r0
4065    GOTO_OPCODE(ip)                     @ jump to next instruction
4066    /* 9-10 instructions */
4067
4068
4069/* ------------------------------ */
4070    .balign 64
4071.L_OP_ADD_INT: /* 0x90 */
4072/* File: armv5te/OP_ADD_INT.S */
4073/* File: armv5te/binop.S */
4074    /*
4075     * Generic 32-bit binary operation.  Provide an "instr" line that
4076     * specifies an instruction that performs "result = r0 op r1".
4077     * This could be an ARM instruction or a function call.  (If the result
4078     * comes back in a register other than r0, you can override "result".)
4079     *
4080     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4081     * vCC (r1).  Useful for integer division and modulus.  Note that we
4082     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4083     * handles it correctly.
4084     *
4085     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4086     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4087     *      mul-float, div-float, rem-float
4088     */
4089    /* binop vAA, vBB, vCC */
4090    FETCH(r0, 1)                        @ r0<- CCBB
4091    mov     r9, rINST, lsr #8           @ r9<- AA
4092    mov     r3, r0, lsr #8              @ r3<- CC
4093    and     r2, r0, #255                @ r2<- BB
4094    GET_VREG(r1, r3)                    @ r1<- vCC
4095    GET_VREG(r0, r2)                    @ r0<- vBB
4096    .if 0
4097    cmp     r1, #0                      @ is second operand zero?
4098    beq     common_errDivideByZero
4099    .endif
4100
4101    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4102                               @ optional op; may set condition codes
4103    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
4104    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4105    SET_VREG(r0, r9)               @ vAA<- r0
4106    GOTO_OPCODE(ip)                     @ jump to next instruction
4107    /* 11-14 instructions */
4108
4109
4110/* ------------------------------ */
4111    .balign 64
4112.L_OP_SUB_INT: /* 0x91 */
4113/* File: armv5te/OP_SUB_INT.S */
4114/* File: armv5te/binop.S */
4115    /*
4116     * Generic 32-bit binary operation.  Provide an "instr" line that
4117     * specifies an instruction that performs "result = r0 op r1".
4118     * This could be an ARM instruction or a function call.  (If the result
4119     * comes back in a register other than r0, you can override "result".)
4120     *
4121     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4122     * vCC (r1).  Useful for integer division and modulus.  Note that we
4123     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4124     * handles it correctly.
4125     *
4126     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4127     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4128     *      mul-float, div-float, rem-float
4129     */
4130    /* binop vAA, vBB, vCC */
4131    FETCH(r0, 1)                        @ r0<- CCBB
4132    mov     r9, rINST, lsr #8           @ r9<- AA
4133    mov     r3, r0, lsr #8              @ r3<- CC
4134    and     r2, r0, #255                @ r2<- BB
4135    GET_VREG(r1, r3)                    @ r1<- vCC
4136    GET_VREG(r0, r2)                    @ r0<- vBB
4137    .if 0
4138    cmp     r1, #0                      @ is second operand zero?
4139    beq     common_errDivideByZero
4140    .endif
4141
4142    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4143                               @ optional op; may set condition codes
4144    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
4145    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4146    SET_VREG(r0, r9)               @ vAA<- r0
4147    GOTO_OPCODE(ip)                     @ jump to next instruction
4148    /* 11-14 instructions */
4149
4150
4151/* ------------------------------ */
4152    .balign 64
4153.L_OP_MUL_INT: /* 0x92 */
4154/* File: armv5te/OP_MUL_INT.S */
4155/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
4156/* File: armv5te/binop.S */
4157    /*
4158     * Generic 32-bit binary operation.  Provide an "instr" line that
4159     * specifies an instruction that performs "result = r0 op r1".
4160     * This could be an ARM instruction or a function call.  (If the result
4161     * comes back in a register other than r0, you can override "result".)
4162     *
4163     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4164     * vCC (r1).  Useful for integer division and modulus.  Note that we
4165     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4166     * handles it correctly.
4167     *
4168     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4169     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4170     *      mul-float, div-float, rem-float
4171     */
4172    /* binop vAA, vBB, vCC */
4173    FETCH(r0, 1)                        @ r0<- CCBB
4174    mov     r9, rINST, lsr #8           @ r9<- AA
4175    mov     r3, r0, lsr #8              @ r3<- CC
4176    and     r2, r0, #255                @ r2<- BB
4177    GET_VREG(r1, r3)                    @ r1<- vCC
4178    GET_VREG(r0, r2)                    @ r0<- vBB
4179    .if 0
4180    cmp     r1, #0                      @ is second operand zero?
4181    beq     common_errDivideByZero
4182    .endif
4183
4184    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4185                               @ optional op; may set condition codes
4186    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
4187    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4188    SET_VREG(r0, r9)               @ vAA<- r0
4189    GOTO_OPCODE(ip)                     @ jump to next instruction
4190    /* 11-14 instructions */
4191
4192
4193/* ------------------------------ */
4194    .balign 64
4195.L_OP_DIV_INT: /* 0x93 */
4196/* File: armv5te/OP_DIV_INT.S */
4197/* File: armv5te/binop.S */
4198    /*
4199     * Generic 32-bit binary operation.  Provide an "instr" line that
4200     * specifies an instruction that performs "result = r0 op r1".
4201     * This could be an ARM instruction or a function call.  (If the result
4202     * comes back in a register other than r0, you can override "result".)
4203     *
4204     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4205     * vCC (r1).  Useful for integer division and modulus.  Note that we
4206     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4207     * handles it correctly.
4208     *
4209     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4210     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4211     *      mul-float, div-float, rem-float
4212     */
4213    /* binop vAA, vBB, vCC */
4214    FETCH(r0, 1)                        @ r0<- CCBB
4215    mov     r9, rINST, lsr #8           @ r9<- AA
4216    mov     r3, r0, lsr #8              @ r3<- CC
4217    and     r2, r0, #255                @ r2<- BB
4218    GET_VREG(r1, r3)                    @ r1<- vCC
4219    GET_VREG(r0, r2)                    @ r0<- vBB
4220    .if 1
4221    cmp     r1, #0                      @ is second operand zero?
4222    beq     common_errDivideByZero
4223    .endif
4224
4225    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4226                               @ optional op; may set condition codes
4227    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
4228    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4229    SET_VREG(r0, r9)               @ vAA<- r0
4230    GOTO_OPCODE(ip)                     @ jump to next instruction
4231    /* 11-14 instructions */
4232
4233
4234/* ------------------------------ */
4235    .balign 64
4236.L_OP_REM_INT: /* 0x94 */
4237/* File: armv5te/OP_REM_INT.S */
4238/* idivmod returns quotient in r0 and remainder in r1 */
4239/* File: armv5te/binop.S */
4240    /*
4241     * Generic 32-bit binary operation.  Provide an "instr" line that
4242     * specifies an instruction that performs "result = r0 op r1".
4243     * This could be an ARM instruction or a function call.  (If the result
4244     * comes back in a register other than r0, you can override "result".)
4245     *
4246     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4247     * vCC (r1).  Useful for integer division and modulus.  Note that we
4248     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4249     * handles it correctly.
4250     *
4251     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4252     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4253     *      mul-float, div-float, rem-float
4254     */
4255    /* binop vAA, vBB, vCC */
4256    FETCH(r0, 1)                        @ r0<- CCBB
4257    mov     r9, rINST, lsr #8           @ r9<- AA
4258    mov     r3, r0, lsr #8              @ r3<- CC
4259    and     r2, r0, #255                @ r2<- BB
4260    GET_VREG(r1, r3)                    @ r1<- vCC
4261    GET_VREG(r0, r2)                    @ r0<- vBB
4262    .if 1
4263    cmp     r1, #0                      @ is second operand zero?
4264    beq     common_errDivideByZero
4265    .endif
4266
4267    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4268                               @ optional op; may set condition codes
4269    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
4270    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4271    SET_VREG(r1, r9)               @ vAA<- r1
4272    GOTO_OPCODE(ip)                     @ jump to next instruction
4273    /* 11-14 instructions */
4274
4275
4276/* ------------------------------ */
4277    .balign 64
4278.L_OP_AND_INT: /* 0x95 */
4279/* File: armv5te/OP_AND_INT.S */
4280/* File: armv5te/binop.S */
4281    /*
4282     * Generic 32-bit binary operation.  Provide an "instr" line that
4283     * specifies an instruction that performs "result = r0 op r1".
4284     * This could be an ARM instruction or a function call.  (If the result
4285     * comes back in a register other than r0, you can override "result".)
4286     *
4287     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4288     * vCC (r1).  Useful for integer division and modulus.  Note that we
4289     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4290     * handles it correctly.
4291     *
4292     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4293     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4294     *      mul-float, div-float, rem-float
4295     */
4296    /* binop vAA, vBB, vCC */
4297    FETCH(r0, 1)                        @ r0<- CCBB
4298    mov     r9, rINST, lsr #8           @ r9<- AA
4299    mov     r3, r0, lsr #8              @ r3<- CC
4300    and     r2, r0, #255                @ r2<- BB
4301    GET_VREG(r1, r3)                    @ r1<- vCC
4302    GET_VREG(r0, r2)                    @ r0<- vBB
4303    .if 0
4304    cmp     r1, #0                      @ is second operand zero?
4305    beq     common_errDivideByZero
4306    .endif
4307
4308    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4309                               @ optional op; may set condition codes
4310    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
4311    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4312    SET_VREG(r0, r9)               @ vAA<- r0
4313    GOTO_OPCODE(ip)                     @ jump to next instruction
4314    /* 11-14 instructions */
4315
4316
4317/* ------------------------------ */
4318    .balign 64
4319.L_OP_OR_INT: /* 0x96 */
4320/* File: armv5te/OP_OR_INT.S */
4321/* File: armv5te/binop.S */
4322    /*
4323     * Generic 32-bit binary operation.  Provide an "instr" line that
4324     * specifies an instruction that performs "result = r0 op r1".
4325     * This could be an ARM instruction or a function call.  (If the result
4326     * comes back in a register other than r0, you can override "result".)
4327     *
4328     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4329     * vCC (r1).  Useful for integer division and modulus.  Note that we
4330     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4331     * handles it correctly.
4332     *
4333     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4334     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4335     *      mul-float, div-float, rem-float
4336     */
4337    /* binop vAA, vBB, vCC */
4338    FETCH(r0, 1)                        @ r0<- CCBB
4339    mov     r9, rINST, lsr #8           @ r9<- AA
4340    mov     r3, r0, lsr #8              @ r3<- CC
4341    and     r2, r0, #255                @ r2<- BB
4342    GET_VREG(r1, r3)                    @ r1<- vCC
4343    GET_VREG(r0, r2)                    @ r0<- vBB
4344    .if 0
4345    cmp     r1, #0                      @ is second operand zero?
4346    beq     common_errDivideByZero
4347    .endif
4348
4349    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4350                               @ optional op; may set condition codes
4351    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
4352    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4353    SET_VREG(r0, r9)               @ vAA<- r0
4354    GOTO_OPCODE(ip)                     @ jump to next instruction
4355    /* 11-14 instructions */
4356
4357
4358/* ------------------------------ */
4359    .balign 64
4360.L_OP_XOR_INT: /* 0x97 */
4361/* File: armv5te/OP_XOR_INT.S */
4362/* File: armv5te/binop.S */
4363    /*
4364     * Generic 32-bit binary operation.  Provide an "instr" line that
4365     * specifies an instruction that performs "result = r0 op r1".
4366     * This could be an ARM instruction or a function call.  (If the result
4367     * comes back in a register other than r0, you can override "result".)
4368     *
4369     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4370     * vCC (r1).  Useful for integer division and modulus.  Note that we
4371     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4372     * handles it correctly.
4373     *
4374     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4375     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4376     *      mul-float, div-float, rem-float
4377     */
4378    /* binop vAA, vBB, vCC */
4379    FETCH(r0, 1)                        @ r0<- CCBB
4380    mov     r9, rINST, lsr #8           @ r9<- AA
4381    mov     r3, r0, lsr #8              @ r3<- CC
4382    and     r2, r0, #255                @ r2<- BB
4383    GET_VREG(r1, r3)                    @ r1<- vCC
4384    GET_VREG(r0, r2)                    @ r0<- vBB
4385    .if 0
4386    cmp     r1, #0                      @ is second operand zero?
4387    beq     common_errDivideByZero
4388    .endif
4389
4390    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4391                               @ optional op; may set condition codes
4392    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
4393    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4394    SET_VREG(r0, r9)               @ vAA<- r0
4395    GOTO_OPCODE(ip)                     @ jump to next instruction
4396    /* 11-14 instructions */
4397
4398
4399/* ------------------------------ */
4400    .balign 64
4401.L_OP_SHL_INT: /* 0x98 */
4402/* File: armv5te/OP_SHL_INT.S */
4403/* File: armv5te/binop.S */
4404    /*
4405     * Generic 32-bit binary operation.  Provide an "instr" line that
4406     * specifies an instruction that performs "result = r0 op r1".
4407     * This could be an ARM instruction or a function call.  (If the result
4408     * comes back in a register other than r0, you can override "result".)
4409     *
4410     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4411     * vCC (r1).  Useful for integer division and modulus.  Note that we
4412     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4413     * handles it correctly.
4414     *
4415     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4416     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4417     *      mul-float, div-float, rem-float
4418     */
4419    /* binop vAA, vBB, vCC */
4420    FETCH(r0, 1)                        @ r0<- CCBB
4421    mov     r9, rINST, lsr #8           @ r9<- AA
4422    mov     r3, r0, lsr #8              @ r3<- CC
4423    and     r2, r0, #255                @ r2<- BB
4424    GET_VREG(r1, r3)                    @ r1<- vCC
4425    GET_VREG(r0, r2)                    @ r0<- vBB
4426    .if 0
4427    cmp     r1, #0                      @ is second operand zero?
4428    beq     common_errDivideByZero
4429    .endif
4430
4431    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4432    and     r1, r1, #31                           @ optional op; may set condition codes
4433    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
4434    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4435    SET_VREG(r0, r9)               @ vAA<- r0
4436    GOTO_OPCODE(ip)                     @ jump to next instruction
4437    /* 11-14 instructions */
4438
4439
4440/* ------------------------------ */
4441    .balign 64
4442.L_OP_SHR_INT: /* 0x99 */
4443/* File: armv5te/OP_SHR_INT.S */
4444/* File: armv5te/binop.S */
4445    /*
4446     * Generic 32-bit binary operation.  Provide an "instr" line that
4447     * specifies an instruction that performs "result = r0 op r1".
4448     * This could be an ARM instruction or a function call.  (If the result
4449     * comes back in a register other than r0, you can override "result".)
4450     *
4451     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4452     * vCC (r1).  Useful for integer division and modulus.  Note that we
4453     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4454     * handles it correctly.
4455     *
4456     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4457     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4458     *      mul-float, div-float, rem-float
4459     */
4460    /* binop vAA, vBB, vCC */
4461    FETCH(r0, 1)                        @ r0<- CCBB
4462    mov     r9, rINST, lsr #8           @ r9<- AA
4463    mov     r3, r0, lsr #8              @ r3<- CC
4464    and     r2, r0, #255                @ r2<- BB
4465    GET_VREG(r1, r3)                    @ r1<- vCC
4466    GET_VREG(r0, r2)                    @ r0<- vBB
4467    .if 0
4468    cmp     r1, #0                      @ is second operand zero?
4469    beq     common_errDivideByZero
4470    .endif
4471
4472    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4473    and     r1, r1, #31                           @ optional op; may set condition codes
4474    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
4475    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4476    SET_VREG(r0, r9)               @ vAA<- r0
4477    GOTO_OPCODE(ip)                     @ jump to next instruction
4478    /* 11-14 instructions */
4479
4480
4481/* ------------------------------ */
4482    .balign 64
4483.L_OP_USHR_INT: /* 0x9a */
4484/* File: armv5te/OP_USHR_INT.S */
4485/* File: armv5te/binop.S */
4486    /*
4487     * Generic 32-bit binary operation.  Provide an "instr" line that
4488     * specifies an instruction that performs "result = r0 op r1".
4489     * This could be an ARM instruction or a function call.  (If the result
4490     * comes back in a register other than r0, you can override "result".)
4491     *
4492     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4493     * vCC (r1).  Useful for integer division and modulus.  Note that we
4494     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4495     * handles it correctly.
4496     *
4497     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4498     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4499     *      mul-float, div-float, rem-float
4500     */
4501    /* binop vAA, vBB, vCC */
4502    FETCH(r0, 1)                        @ r0<- CCBB
4503    mov     r9, rINST, lsr #8           @ r9<- AA
4504    mov     r3, r0, lsr #8              @ r3<- CC
4505    and     r2, r0, #255                @ r2<- BB
4506    GET_VREG(r1, r3)                    @ r1<- vCC
4507    GET_VREG(r0, r2)                    @ r0<- vBB
4508    .if 0
4509    cmp     r1, #0                      @ is second operand zero?
4510    beq     common_errDivideByZero
4511    .endif
4512
4513    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4514    and     r1, r1, #31                           @ optional op; may set condition codes
4515    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
4516    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4517    SET_VREG(r0, r9)               @ vAA<- r0
4518    GOTO_OPCODE(ip)                     @ jump to next instruction
4519    /* 11-14 instructions */
4520
4521
4522/* ------------------------------ */
4523    .balign 64
4524.L_OP_ADD_LONG: /* 0x9b */
4525/* File: armv5te/OP_ADD_LONG.S */
4526/* File: armv5te/binopWide.S */
4527    /*
4528     * Generic 64-bit binary operation.  Provide an "instr" line that
4529     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4530     * This could be an ARM instruction or a function call.  (If the result
4531     * comes back in a register other than r0, you can override "result".)
4532     *
4533     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4534     * vCC (r1).  Useful for integer division and modulus.
4535     *
4536     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4537     *      xor-long, add-double, sub-double, mul-double, div-double,
4538     *      rem-double
4539     *
4540     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4541     */
4542    /* binop vAA, vBB, vCC */
4543    FETCH(r0, 1)                        @ r0<- CCBB
4544    mov     r9, rINST, lsr #8           @ r9<- AA
4545    and     r2, r0, #255                @ r2<- BB
4546    mov     r3, r0, lsr #8              @ r3<- CC
4547    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4548    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4549    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4550    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4551    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4552    .if 0
4553    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4554    beq     common_errDivideByZero
4555    .endif
4556    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4557
4558    adds    r0, r0, r2                           @ optional op; may set condition codes
4559    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
4560    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4561    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4562    GOTO_OPCODE(ip)                     @ jump to next instruction
4563    /* 14-17 instructions */
4564
4565
4566/* ------------------------------ */
4567    .balign 64
4568.L_OP_SUB_LONG: /* 0x9c */
4569/* File: armv5te/OP_SUB_LONG.S */
4570/* File: armv5te/binopWide.S */
4571    /*
4572     * Generic 64-bit binary operation.  Provide an "instr" line that
4573     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4574     * This could be an ARM instruction or a function call.  (If the result
4575     * comes back in a register other than r0, you can override "result".)
4576     *
4577     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4578     * vCC (r1).  Useful for integer division and modulus.
4579     *
4580     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4581     *      xor-long, add-double, sub-double, mul-double, div-double,
4582     *      rem-double
4583     *
4584     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4585     */
4586    /* binop vAA, vBB, vCC */
4587    FETCH(r0, 1)                        @ r0<- CCBB
4588    mov     r9, rINST, lsr #8           @ r9<- AA
4589    and     r2, r0, #255                @ r2<- BB
4590    mov     r3, r0, lsr #8              @ r3<- CC
4591    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4592    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4593    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4594    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4595    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4596    .if 0
4597    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4598    beq     common_errDivideByZero
4599    .endif
4600    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4601
4602    subs    r0, r0, r2                           @ optional op; may set condition codes
4603    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
4604    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4605    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4606    GOTO_OPCODE(ip)                     @ jump to next instruction
4607    /* 14-17 instructions */
4608
4609
4610/* ------------------------------ */
4611    .balign 64
4612.L_OP_MUL_LONG: /* 0x9d */
4613/* File: armv5te/OP_MUL_LONG.S */
4614    /*
4615     * Signed 64-bit integer multiply.
4616     *
4617     * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
4618     *        WX
4619     *      x YZ
4620     *  --------
4621     *     ZW ZX
4622     *  YW YX
4623     *
4624     * The low word of the result holds ZX, the high word holds
4625     * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
4626     * it doesn't fit in the low 64 bits.
4627     *
4628     * Unlike most ARM math operations, multiply instructions have
4629     * restrictions on using the same register more than once (Rd and Rm
4630     * cannot be the same).
4631     */
4632    /* mul-long vAA, vBB, vCC */
4633    FETCH(r0, 1)                        @ r0<- CCBB
4634    and     r2, r0, #255                @ r2<- BB
4635    mov     r3, r0, lsr #8              @ r3<- CC
4636    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4637    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4638    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4639    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4640    mul     ip, r2, r1                  @  ip<- ZxW
4641    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
4642    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
4643    mov     r0, rINST, lsr #8           @ r0<- AA
4644    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
4645    add     r0, rFP, r0, lsl #2         @ r0<- &fp[AA]
4646    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4647    b       .LOP_MUL_LONG_finish
4648
4649/* ------------------------------ */
4650    .balign 64
4651.L_OP_DIV_LONG: /* 0x9e */
4652/* File: armv5te/OP_DIV_LONG.S */
4653/* File: armv5te/binopWide.S */
4654    /*
4655     * Generic 64-bit binary operation.  Provide an "instr" line that
4656     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4657     * This could be an ARM instruction or a function call.  (If the result
4658     * comes back in a register other than r0, you can override "result".)
4659     *
4660     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4661     * vCC (r1).  Useful for integer division and modulus.
4662     *
4663     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4664     *      xor-long, add-double, sub-double, mul-double, div-double,
4665     *      rem-double
4666     *
4667     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4668     */
4669    /* binop vAA, vBB, vCC */
4670    FETCH(r0, 1)                        @ r0<- CCBB
4671    mov     r9, rINST, lsr #8           @ r9<- AA
4672    and     r2, r0, #255                @ r2<- BB
4673    mov     r3, r0, lsr #8              @ r3<- CC
4674    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4675    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4676    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4677    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4678    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4679    .if 1
4680    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4681    beq     common_errDivideByZero
4682    .endif
4683    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4684
4685                               @ optional op; may set condition codes
4686    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4687    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4688    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4689    GOTO_OPCODE(ip)                     @ jump to next instruction
4690    /* 14-17 instructions */
4691
4692
4693/* ------------------------------ */
4694    .balign 64
4695.L_OP_REM_LONG: /* 0x9f */
4696/* File: armv5te/OP_REM_LONG.S */
4697/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
4698/* File: armv5te/binopWide.S */
4699    /*
4700     * Generic 64-bit binary operation.  Provide an "instr" line that
4701     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4702     * This could be an ARM instruction or a function call.  (If the result
4703     * comes back in a register other than r0, you can override "result".)
4704     *
4705     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4706     * vCC (r1).  Useful for integer division and modulus.
4707     *
4708     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4709     *      xor-long, add-double, sub-double, mul-double, div-double,
4710     *      rem-double
4711     *
4712     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4713     */
4714    /* binop vAA, vBB, vCC */
4715    FETCH(r0, 1)                        @ r0<- CCBB
4716    mov     r9, rINST, lsr #8           @ r9<- AA
4717    and     r2, r0, #255                @ r2<- BB
4718    mov     r3, r0, lsr #8              @ r3<- CC
4719    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4720    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4721    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4722    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4723    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4724    .if 1
4725    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4726    beq     common_errDivideByZero
4727    .endif
4728    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4729
4730                               @ optional op; may set condition codes
4731    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
4732    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4733    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
4734    GOTO_OPCODE(ip)                     @ jump to next instruction
4735    /* 14-17 instructions */
4736
4737
4738/* ------------------------------ */
4739    .balign 64
4740.L_OP_AND_LONG: /* 0xa0 */
4741/* File: armv5te/OP_AND_LONG.S */
4742/* File: armv5te/binopWide.S */
4743    /*
4744     * Generic 64-bit binary operation.  Provide an "instr" line that
4745     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4746     * This could be an ARM instruction or a function call.  (If the result
4747     * comes back in a register other than r0, you can override "result".)
4748     *
4749     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4750     * vCC (r1).  Useful for integer division and modulus.
4751     *
4752     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4753     *      xor-long, add-double, sub-double, mul-double, div-double,
4754     *      rem-double
4755     *
4756     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4757     */
4758    /* binop vAA, vBB, vCC */
4759    FETCH(r0, 1)                        @ r0<- CCBB
4760    mov     r9, rINST, lsr #8           @ r9<- AA
4761    and     r2, r0, #255                @ r2<- BB
4762    mov     r3, r0, lsr #8              @ r3<- CC
4763    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4764    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4765    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4766    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4767    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4768    .if 0
4769    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4770    beq     common_errDivideByZero
4771    .endif
4772    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4773
4774    and     r0, r0, r2                           @ optional op; may set condition codes
4775    and     r1, r1, r3                              @ result<- op, r0-r3 changed
4776    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4777    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4778    GOTO_OPCODE(ip)                     @ jump to next instruction
4779    /* 14-17 instructions */
4780
4781
4782/* ------------------------------ */
4783    .balign 64
4784.L_OP_OR_LONG: /* 0xa1 */
4785/* File: armv5te/OP_OR_LONG.S */
4786/* File: armv5te/binopWide.S */
4787    /*
4788     * Generic 64-bit binary operation.  Provide an "instr" line that
4789     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4790     * This could be an ARM instruction or a function call.  (If the result
4791     * comes back in a register other than r0, you can override "result".)
4792     *
4793     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4794     * vCC (r1).  Useful for integer division and modulus.
4795     *
4796     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4797     *      xor-long, add-double, sub-double, mul-double, div-double,
4798     *      rem-double
4799     *
4800     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4801     */
4802    /* binop vAA, vBB, vCC */
4803    FETCH(r0, 1)                        @ r0<- CCBB
4804    mov     r9, rINST, lsr #8           @ r9<- AA
4805    and     r2, r0, #255                @ r2<- BB
4806    mov     r3, r0, lsr #8              @ r3<- CC
4807    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4808    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4809    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4810    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4811    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4812    .if 0
4813    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4814    beq     common_errDivideByZero
4815    .endif
4816    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4817
4818    orr     r0, r0, r2                           @ optional op; may set condition codes
4819    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
4820    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4821    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4822    GOTO_OPCODE(ip)                     @ jump to next instruction
4823    /* 14-17 instructions */
4824
4825
4826/* ------------------------------ */
4827    .balign 64
4828.L_OP_XOR_LONG: /* 0xa2 */
4829/* File: armv5te/OP_XOR_LONG.S */
4830/* File: armv5te/binopWide.S */
4831    /*
4832     * Generic 64-bit binary operation.  Provide an "instr" line that
4833     * specifies an instruction that performs "result = r0-r1 op r2-r3".
4834     * This could be an ARM instruction or a function call.  (If the result
4835     * comes back in a register other than r0, you can override "result".)
4836     *
4837     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4838     * vCC (r1).  Useful for integer division and modulus.
4839     *
4840     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
4841     *      xor-long, add-double, sub-double, mul-double, div-double,
4842     *      rem-double
4843     *
4844     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
4845     */
4846    /* binop vAA, vBB, vCC */
4847    FETCH(r0, 1)                        @ r0<- CCBB
4848    mov     r9, rINST, lsr #8           @ r9<- AA
4849    and     r2, r0, #255                @ r2<- BB
4850    mov     r3, r0, lsr #8              @ r3<- CC
4851    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4852    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
4853    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
4854    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4855    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
4856    .if 0
4857    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
4858    beq     common_errDivideByZero
4859    .endif
4860    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4861
4862    eor     r0, r0, r2                           @ optional op; may set condition codes
4863    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
4864    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4865    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
4866    GOTO_OPCODE(ip)                     @ jump to next instruction
4867    /* 14-17 instructions */
4868
4869
4870/* ------------------------------ */
4871    .balign 64
4872.L_OP_SHL_LONG: /* 0xa3 */
4873/* File: armv5te/OP_SHL_LONG.S */
4874    /*
4875     * Long integer shift.  This is different from the generic 32/64-bit
4876     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4877     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4878     * 6 bits of the shift distance.
4879     */
4880    /* shl-long vAA, vBB, vCC */
4881    FETCH(r0, 1)                        @ r0<- CCBB
4882    mov     r9, rINST, lsr #8           @ r9<- AA
4883    and     r3, r0, #255                @ r3<- BB
4884    mov     r0, r0, lsr #8              @ r0<- CC
4885    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4886    GET_VREG(r2, r0)                    @ r2<- vCC
4887    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4888    and     r2, r2, #63                 @ r2<- r2 & 0x3f
4889    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4890
4891    mov     r1, r1, asl r2              @  r1<- r1 << r2
4892    rsb     r3, r2, #32                 @  r3<- 32 - r2
4893    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
4894    subs    ip, r2, #32                 @  ip<- r2 - 32
4895    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
4896    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4897    b       .LOP_SHL_LONG_finish
4898
4899/* ------------------------------ */
4900    .balign 64
4901.L_OP_SHR_LONG: /* 0xa4 */
4902/* File: armv5te/OP_SHR_LONG.S */
4903    /*
4904     * Long integer shift.  This is different from the generic 32/64-bit
4905     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4906     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4907     * 6 bits of the shift distance.
4908     */
4909    /* shr-long vAA, vBB, vCC */
4910    FETCH(r0, 1)                        @ r0<- CCBB
4911    mov     r9, rINST, lsr #8           @ r9<- AA
4912    and     r3, r0, #255                @ r3<- BB
4913    mov     r0, r0, lsr #8              @ r0<- CC
4914    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4915    GET_VREG(r2, r0)                    @ r2<- vCC
4916    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4917    and     r2, r2, #63                 @ r0<- r0 & 0x3f
4918    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4919
4920    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
4921    rsb     r3, r2, #32                 @  r3<- 32 - r2
4922    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
4923    subs    ip, r2, #32                 @  ip<- r2 - 32
4924    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
4925    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4926    b       .LOP_SHR_LONG_finish
4927
4928/* ------------------------------ */
4929    .balign 64
4930.L_OP_USHR_LONG: /* 0xa5 */
4931/* File: armv5te/OP_USHR_LONG.S */
4932    /*
4933     * Long integer shift.  This is different from the generic 32/64-bit
4934     * binary operations because vAA/vBB are 64-bit but vCC (the shift
4935     * distance) is 32-bit.  Also, Dalvik requires us to mask off the low
4936     * 6 bits of the shift distance.
4937     */
4938    /* ushr-long vAA, vBB, vCC */
4939    FETCH(r0, 1)                        @ r0<- CCBB
4940    mov     r9, rINST, lsr #8           @ r9<- AA
4941    and     r3, r0, #255                @ r3<- BB
4942    mov     r0, r0, lsr #8              @ r0<- CC
4943    add     r3, rFP, r3, lsl #2         @ r3<- &fp[BB]
4944    GET_VREG(r2, r0)                    @ r2<- vCC
4945    ldmia   r3, {r0-r1}                 @ r0/r1<- vBB/vBB+1
4946    and     r2, r2, #63                 @ r0<- r0 & 0x3f
4947    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
4948
4949    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
4950    rsb     r3, r2, #32                 @  r3<- 32 - r2
4951    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
4952    subs    ip, r2, #32                 @  ip<- r2 - 32
4953    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
4954    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4955    b       .LOP_USHR_LONG_finish
4956
4957/* ------------------------------ */
4958    .balign 64
4959.L_OP_ADD_FLOAT: /* 0xa6 */
4960/* File: armv5te/OP_ADD_FLOAT.S */
4961/* File: armv5te/binop.S */
4962    /*
4963     * Generic 32-bit binary operation.  Provide an "instr" line that
4964     * specifies an instruction that performs "result = r0 op r1".
4965     * This could be an ARM instruction or a function call.  (If the result
4966     * comes back in a register other than r0, you can override "result".)
4967     *
4968     * If "chkzero" is set to 1, we perform a divide-by-zero check on
4969     * vCC (r1).  Useful for integer division and modulus.  Note that we
4970     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
4971     * handles it correctly.
4972     *
4973     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
4974     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
4975     *      mul-float, div-float, rem-float
4976     */
4977    /* binop vAA, vBB, vCC */
4978    FETCH(r0, 1)                        @ r0<- CCBB
4979    mov     r9, rINST, lsr #8           @ r9<- AA
4980    mov     r3, r0, lsr #8              @ r3<- CC
4981    and     r2, r0, #255                @ r2<- BB
4982    GET_VREG(r1, r3)                    @ r1<- vCC
4983    GET_VREG(r0, r2)                    @ r0<- vBB
4984    .if 0
4985    cmp     r1, #0                      @ is second operand zero?
4986    beq     common_errDivideByZero
4987    .endif
4988
4989    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
4990                               @ optional op; may set condition codes
4991    bl      __aeabi_fadd                              @ r0<- op, r0-r3 changed
4992    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
4993    SET_VREG(r0, r9)               @ vAA<- r0
4994    GOTO_OPCODE(ip)                     @ jump to next instruction
4995    /* 11-14 instructions */
4996
4997
4998/* ------------------------------ */
4999    .balign 64
5000.L_OP_SUB_FLOAT: /* 0xa7 */
5001/* File: armv5te/OP_SUB_FLOAT.S */
5002/* File: armv5te/binop.S */
5003    /*
5004     * Generic 32-bit binary operation.  Provide an "instr" line that
5005     * specifies an instruction that performs "result = r0 op r1".
5006     * This could be an ARM instruction or a function call.  (If the result
5007     * comes back in a register other than r0, you can override "result".)
5008     *
5009     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5010     * vCC (r1).  Useful for integer division and modulus.  Note that we
5011     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
5012     * handles it correctly.
5013     *
5014     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
5015     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
5016     *      mul-float, div-float, rem-float
5017     */
5018    /* binop vAA, vBB, vCC */
5019    FETCH(r0, 1)                        @ r0<- CCBB
5020    mov     r9, rINST, lsr #8           @ r9<- AA
5021    mov     r3, r0, lsr #8              @ r3<- CC
5022    and     r2, r0, #255                @ r2<- BB
5023    GET_VREG(r1, r3)                    @ r1<- vCC
5024    GET_VREG(r0, r2)                    @ r0<- vBB
5025    .if 0
5026    cmp     r1, #0                      @ is second operand zero?
5027    beq     common_errDivideByZero
5028    .endif
5029
5030    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5031                               @ optional op; may set condition codes
5032    bl      __aeabi_fsub                              @ r0<- op, r0-r3 changed
5033    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5034    SET_VREG(r0, r9)               @ vAA<- r0
5035    GOTO_OPCODE(ip)                     @ jump to next instruction
5036    /* 11-14 instructions */
5037
5038
5039/* ------------------------------ */
5040    .balign 64
5041.L_OP_MUL_FLOAT: /* 0xa8 */
5042/* File: armv5te/OP_MUL_FLOAT.S */
5043/* File: armv5te/binop.S */
5044    /*
5045     * Generic 32-bit binary operation.  Provide an "instr" line that
5046     * specifies an instruction that performs "result = r0 op r1".
5047     * This could be an ARM instruction or a function call.  (If the result
5048     * comes back in a register other than r0, you can override "result".)
5049     *
5050     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5051     * vCC (r1).  Useful for integer division and modulus.  Note that we
5052     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
5053     * handles it correctly.
5054     *
5055     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
5056     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
5057     *      mul-float, div-float, rem-float
5058     */
5059    /* binop vAA, vBB, vCC */
5060    FETCH(r0, 1)                        @ r0<- CCBB
5061    mov     r9, rINST, lsr #8           @ r9<- AA
5062    mov     r3, r0, lsr #8              @ r3<- CC
5063    and     r2, r0, #255                @ r2<- BB
5064    GET_VREG(r1, r3)                    @ r1<- vCC
5065    GET_VREG(r0, r2)                    @ r0<- vBB
5066    .if 0
5067    cmp     r1, #0                      @ is second operand zero?
5068    beq     common_errDivideByZero
5069    .endif
5070
5071    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5072                               @ optional op; may set condition codes
5073    bl      __aeabi_fmul                              @ r0<- op, r0-r3 changed
5074    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5075    SET_VREG(r0, r9)               @ vAA<- r0
5076    GOTO_OPCODE(ip)                     @ jump to next instruction
5077    /* 11-14 instructions */
5078
5079
5080/* ------------------------------ */
5081    .balign 64
5082.L_OP_DIV_FLOAT: /* 0xa9 */
5083/* File: armv5te/OP_DIV_FLOAT.S */
5084/* File: armv5te/binop.S */
5085    /*
5086     * Generic 32-bit binary operation.  Provide an "instr" line that
5087     * specifies an instruction that performs "result = r0 op r1".
5088     * This could be an ARM instruction or a function call.  (If the result
5089     * comes back in a register other than r0, you can override "result".)
5090     *
5091     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5092     * vCC (r1).  Useful for integer division and modulus.  Note that we
5093     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
5094     * handles it correctly.
5095     *
5096     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
5097     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
5098     *      mul-float, div-float, rem-float
5099     */
5100    /* binop vAA, vBB, vCC */
5101    FETCH(r0, 1)                        @ r0<- CCBB
5102    mov     r9, rINST, lsr #8           @ r9<- AA
5103    mov     r3, r0, lsr #8              @ r3<- CC
5104    and     r2, r0, #255                @ r2<- BB
5105    GET_VREG(r1, r3)                    @ r1<- vCC
5106    GET_VREG(r0, r2)                    @ r0<- vBB
5107    .if 0
5108    cmp     r1, #0                      @ is second operand zero?
5109    beq     common_errDivideByZero
5110    .endif
5111
5112    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5113                               @ optional op; may set condition codes
5114    bl      __aeabi_fdiv                              @ r0<- op, r0-r3 changed
5115    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5116    SET_VREG(r0, r9)               @ vAA<- r0
5117    GOTO_OPCODE(ip)                     @ jump to next instruction
5118    /* 11-14 instructions */
5119
5120
5121/* ------------------------------ */
5122    .balign 64
5123.L_OP_REM_FLOAT: /* 0xaa */
5124/* File: armv5te/OP_REM_FLOAT.S */
5125/* EABI doesn't define a float remainder function, but libm does */
5126/* File: armv5te/binop.S */
5127    /*
5128     * Generic 32-bit binary operation.  Provide an "instr" line that
5129     * specifies an instruction that performs "result = r0 op r1".
5130     * This could be an ARM instruction or a function call.  (If the result
5131     * comes back in a register other than r0, you can override "result".)
5132     *
5133     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5134     * vCC (r1).  Useful for integer division and modulus.  Note that we
5135     * *don't* check for (INT_MIN / -1) here, because the ARM math lib
5136     * handles it correctly.
5137     *
5138     * For: add-int, sub-int, mul-int, div-int, rem-int, and-int, or-int,
5139     *      xor-int, shl-int, shr-int, ushr-int, add-float, sub-float,
5140     *      mul-float, div-float, rem-float
5141     */
5142    /* binop vAA, vBB, vCC */
5143    FETCH(r0, 1)                        @ r0<- CCBB
5144    mov     r9, rINST, lsr #8           @ r9<- AA
5145    mov     r3, r0, lsr #8              @ r3<- CC
5146    and     r2, r0, #255                @ r2<- BB
5147    GET_VREG(r1, r3)                    @ r1<- vCC
5148    GET_VREG(r0, r2)                    @ r0<- vBB
5149    .if 0
5150    cmp     r1, #0                      @ is second operand zero?
5151    beq     common_errDivideByZero
5152    .endif
5153
5154    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5155                               @ optional op; may set condition codes
5156    bl      fmodf                              @ r0<- op, r0-r3 changed
5157    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5158    SET_VREG(r0, r9)               @ vAA<- r0
5159    GOTO_OPCODE(ip)                     @ jump to next instruction
5160    /* 11-14 instructions */
5161
5162
5163/* ------------------------------ */
5164    .balign 64
5165.L_OP_ADD_DOUBLE: /* 0xab */
5166/* File: armv5te/OP_ADD_DOUBLE.S */
5167/* File: armv5te/binopWide.S */
5168    /*
5169     * Generic 64-bit binary operation.  Provide an "instr" line that
5170     * specifies an instruction that performs "result = r0-r1 op r2-r3".
5171     * This could be an ARM instruction or a function call.  (If the result
5172     * comes back in a register other than r0, you can override "result".)
5173     *
5174     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5175     * vCC (r1).  Useful for integer division and modulus.
5176     *
5177     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
5178     *      xor-long, add-double, sub-double, mul-double, div-double,
5179     *      rem-double
5180     *
5181     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
5182     */
5183    /* binop vAA, vBB, vCC */
5184    FETCH(r0, 1)                        @ r0<- CCBB
5185    mov     r9, rINST, lsr #8           @ r9<- AA
5186    and     r2, r0, #255                @ r2<- BB
5187    mov     r3, r0, lsr #8              @ r3<- CC
5188    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5189    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
5190    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
5191    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5192    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
5193    .if 0
5194    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5195    beq     common_errDivideByZero
5196    .endif
5197    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5198
5199                               @ optional op; may set condition codes
5200    bl      __aeabi_dadd                              @ result<- op, r0-r3 changed
5201    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5202    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5203    GOTO_OPCODE(ip)                     @ jump to next instruction
5204    /* 14-17 instructions */
5205
5206
5207/* ------------------------------ */
5208    .balign 64
5209.L_OP_SUB_DOUBLE: /* 0xac */
5210/* File: armv5te/OP_SUB_DOUBLE.S */
5211/* File: armv5te/binopWide.S */
5212    /*
5213     * Generic 64-bit binary operation.  Provide an "instr" line that
5214     * specifies an instruction that performs "result = r0-r1 op r2-r3".
5215     * This could be an ARM instruction or a function call.  (If the result
5216     * comes back in a register other than r0, you can override "result".)
5217     *
5218     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5219     * vCC (r1).  Useful for integer division and modulus.
5220     *
5221     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
5222     *      xor-long, add-double, sub-double, mul-double, div-double,
5223     *      rem-double
5224     *
5225     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
5226     */
5227    /* binop vAA, vBB, vCC */
5228    FETCH(r0, 1)                        @ r0<- CCBB
5229    mov     r9, rINST, lsr #8           @ r9<- AA
5230    and     r2, r0, #255                @ r2<- BB
5231    mov     r3, r0, lsr #8              @ r3<- CC
5232    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5233    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
5234    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
5235    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5236    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
5237    .if 0
5238    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5239    beq     common_errDivideByZero
5240    .endif
5241    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5242
5243                               @ optional op; may set condition codes
5244    bl      __aeabi_dsub                              @ result<- op, r0-r3 changed
5245    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5246    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5247    GOTO_OPCODE(ip)                     @ jump to next instruction
5248    /* 14-17 instructions */
5249
5250
5251/* ------------------------------ */
5252    .balign 64
5253.L_OP_MUL_DOUBLE: /* 0xad */
5254/* File: armv5te/OP_MUL_DOUBLE.S */
5255/* File: armv5te/binopWide.S */
5256    /*
5257     * Generic 64-bit binary operation.  Provide an "instr" line that
5258     * specifies an instruction that performs "result = r0-r1 op r2-r3".
5259     * This could be an ARM instruction or a function call.  (If the result
5260     * comes back in a register other than r0, you can override "result".)
5261     *
5262     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5263     * vCC (r1).  Useful for integer division and modulus.
5264     *
5265     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
5266     *      xor-long, add-double, sub-double, mul-double, div-double,
5267     *      rem-double
5268     *
5269     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
5270     */
5271    /* binop vAA, vBB, vCC */
5272    FETCH(r0, 1)                        @ r0<- CCBB
5273    mov     r9, rINST, lsr #8           @ r9<- AA
5274    and     r2, r0, #255                @ r2<- BB
5275    mov     r3, r0, lsr #8              @ r3<- CC
5276    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5277    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
5278    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
5279    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5280    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
5281    .if 0
5282    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5283    beq     common_errDivideByZero
5284    .endif
5285    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5286
5287                               @ optional op; may set condition codes
5288    bl      __aeabi_dmul                              @ result<- op, r0-r3 changed
5289    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5290    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5291    GOTO_OPCODE(ip)                     @ jump to next instruction
5292    /* 14-17 instructions */
5293
5294
5295/* ------------------------------ */
5296    .balign 64
5297.L_OP_DIV_DOUBLE: /* 0xae */
5298/* File: armv5te/OP_DIV_DOUBLE.S */
5299/* File: armv5te/binopWide.S */
5300    /*
5301     * Generic 64-bit binary operation.  Provide an "instr" line that
5302     * specifies an instruction that performs "result = r0-r1 op r2-r3".
5303     * This could be an ARM instruction or a function call.  (If the result
5304     * comes back in a register other than r0, you can override "result".)
5305     *
5306     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5307     * vCC (r1).  Useful for integer division and modulus.
5308     *
5309     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
5310     *      xor-long, add-double, sub-double, mul-double, div-double,
5311     *      rem-double
5312     *
5313     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
5314     */
5315    /* binop vAA, vBB, vCC */
5316    FETCH(r0, 1)                        @ r0<- CCBB
5317    mov     r9, rINST, lsr #8           @ r9<- AA
5318    and     r2, r0, #255                @ r2<- BB
5319    mov     r3, r0, lsr #8              @ r3<- CC
5320    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5321    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
5322    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
5323    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5324    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
5325    .if 0
5326    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5327    beq     common_errDivideByZero
5328    .endif
5329    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5330
5331                               @ optional op; may set condition codes
5332    bl      __aeabi_ddiv                              @ result<- op, r0-r3 changed
5333    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5334    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5335    GOTO_OPCODE(ip)                     @ jump to next instruction
5336    /* 14-17 instructions */
5337
5338
5339/* ------------------------------ */
5340    .balign 64
5341.L_OP_REM_DOUBLE: /* 0xaf */
5342/* File: armv5te/OP_REM_DOUBLE.S */
5343/* EABI doesn't define a double remainder function, but libm does */
5344/* File: armv5te/binopWide.S */
5345    /*
5346     * Generic 64-bit binary operation.  Provide an "instr" line that
5347     * specifies an instruction that performs "result = r0-r1 op r2-r3".
5348     * This could be an ARM instruction or a function call.  (If the result
5349     * comes back in a register other than r0, you can override "result".)
5350     *
5351     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5352     * vCC (r1).  Useful for integer division and modulus.
5353     *
5354     * for: add-long, sub-long, div-long, rem-long, and-long, or-long,
5355     *      xor-long, add-double, sub-double, mul-double, div-double,
5356     *      rem-double
5357     *
5358     * IMPORTANT: you may specify "chkzero" or "preinstr" but not both.
5359     */
5360    /* binop vAA, vBB, vCC */
5361    FETCH(r0, 1)                        @ r0<- CCBB
5362    mov     r9, rINST, lsr #8           @ r9<- AA
5363    and     r2, r0, #255                @ r2<- BB
5364    mov     r3, r0, lsr #8              @ r3<- CC
5365    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
5366    add     r2, rFP, r2, lsl #2         @ r2<- &fp[BB]
5367    add     r3, rFP, r3, lsl #2         @ r3<- &fp[CC]
5368    ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
5369    ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
5370    .if 0
5371    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5372    beq     common_errDivideByZero
5373    .endif
5374    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
5375
5376                               @ optional op; may set condition codes
5377    bl      fmod                              @ result<- op, r0-r3 changed
5378    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5379    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5380    GOTO_OPCODE(ip)                     @ jump to next instruction
5381    /* 14-17 instructions */
5382
5383
5384/* ------------------------------ */
5385    .balign 64
5386.L_OP_ADD_INT_2ADDR: /* 0xb0 */
5387/* File: armv5te/OP_ADD_INT_2ADDR.S */
5388/* File: armv5te/binop2addr.S */
5389    /*
5390     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5391     * that specifies an instruction that performs "result = r0 op r1".
5392     * This could be an ARM instruction or a function call.  (If the result
5393     * comes back in a register other than r0, you can override "result".)
5394     *
5395     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5396     * vCC (r1).  Useful for integer division and modulus.
5397     *
5398     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5399     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5400     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5401     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5402     */
5403    /* binop/2addr vA, vB */
5404    mov     r9, rINST, lsr #8           @ r9<- A+
5405    mov     r3, rINST, lsr #12          @ r3<- B
5406    and     r9, r9, #15
5407    GET_VREG(r1, r3)                    @ r1<- vB
5408    GET_VREG(r0, r9)                    @ r0<- vA
5409    .if 0
5410    cmp     r1, #0                      @ is second operand zero?
5411    beq     common_errDivideByZero
5412    .endif
5413    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5414
5415                               @ optional op; may set condition codes
5416    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
5417    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5418    SET_VREG(r0, r9)               @ vAA<- r0
5419    GOTO_OPCODE(ip)                     @ jump to next instruction
5420    /* 10-13 instructions */
5421
5422
5423/* ------------------------------ */
5424    .balign 64
5425.L_OP_SUB_INT_2ADDR: /* 0xb1 */
5426/* File: armv5te/OP_SUB_INT_2ADDR.S */
5427/* File: armv5te/binop2addr.S */
5428    /*
5429     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5430     * that specifies an instruction that performs "result = r0 op r1".
5431     * This could be an ARM instruction or a function call.  (If the result
5432     * comes back in a register other than r0, you can override "result".)
5433     *
5434     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5435     * vCC (r1).  Useful for integer division and modulus.
5436     *
5437     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5438     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5439     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5440     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5441     */
5442    /* binop/2addr vA, vB */
5443    mov     r9, rINST, lsr #8           @ r9<- A+
5444    mov     r3, rINST, lsr #12          @ r3<- B
5445    and     r9, r9, #15
5446    GET_VREG(r1, r3)                    @ r1<- vB
5447    GET_VREG(r0, r9)                    @ r0<- vA
5448    .if 0
5449    cmp     r1, #0                      @ is second operand zero?
5450    beq     common_errDivideByZero
5451    .endif
5452    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5453
5454                               @ optional op; may set condition codes
5455    sub     r0, r0, r1                              @ r0<- op, r0-r3 changed
5456    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5457    SET_VREG(r0, r9)               @ vAA<- r0
5458    GOTO_OPCODE(ip)                     @ jump to next instruction
5459    /* 10-13 instructions */
5460
5461
5462/* ------------------------------ */
5463    .balign 64
5464.L_OP_MUL_INT_2ADDR: /* 0xb2 */
5465/* File: armv5te/OP_MUL_INT_2ADDR.S */
5466/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
5467/* File: armv5te/binop2addr.S */
5468    /*
5469     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5470     * that specifies an instruction that performs "result = r0 op r1".
5471     * This could be an ARM instruction or a function call.  (If the result
5472     * comes back in a register other than r0, you can override "result".)
5473     *
5474     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5475     * vCC (r1).  Useful for integer division and modulus.
5476     *
5477     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5478     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5479     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5480     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5481     */
5482    /* binop/2addr vA, vB */
5483    mov     r9, rINST, lsr #8           @ r9<- A+
5484    mov     r3, rINST, lsr #12          @ r3<- B
5485    and     r9, r9, #15
5486    GET_VREG(r1, r3)                    @ r1<- vB
5487    GET_VREG(r0, r9)                    @ r0<- vA
5488    .if 0
5489    cmp     r1, #0                      @ is second operand zero?
5490    beq     common_errDivideByZero
5491    .endif
5492    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5493
5494                               @ optional op; may set condition codes
5495    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
5496    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5497    SET_VREG(r0, r9)               @ vAA<- r0
5498    GOTO_OPCODE(ip)                     @ jump to next instruction
5499    /* 10-13 instructions */
5500
5501
5502/* ------------------------------ */
5503    .balign 64
5504.L_OP_DIV_INT_2ADDR: /* 0xb3 */
5505/* File: armv5te/OP_DIV_INT_2ADDR.S */
5506/* File: armv5te/binop2addr.S */
5507    /*
5508     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5509     * that specifies an instruction that performs "result = r0 op r1".
5510     * This could be an ARM instruction or a function call.  (If the result
5511     * comes back in a register other than r0, you can override "result".)
5512     *
5513     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5514     * vCC (r1).  Useful for integer division and modulus.
5515     *
5516     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5517     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5518     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5519     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5520     */
5521    /* binop/2addr vA, vB */
5522    mov     r9, rINST, lsr #8           @ r9<- A+
5523    mov     r3, rINST, lsr #12          @ r3<- B
5524    and     r9, r9, #15
5525    GET_VREG(r1, r3)                    @ r1<- vB
5526    GET_VREG(r0, r9)                    @ r0<- vA
5527    .if 1
5528    cmp     r1, #0                      @ is second operand zero?
5529    beq     common_errDivideByZero
5530    .endif
5531    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5532
5533                               @ optional op; may set condition codes
5534    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
5535    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5536    SET_VREG(r0, r9)               @ vAA<- r0
5537    GOTO_OPCODE(ip)                     @ jump to next instruction
5538    /* 10-13 instructions */
5539
5540
5541/* ------------------------------ */
5542    .balign 64
5543.L_OP_REM_INT_2ADDR: /* 0xb4 */
5544/* File: armv5te/OP_REM_INT_2ADDR.S */
5545/* idivmod returns quotient in r0 and remainder in r1 */
5546/* File: armv5te/binop2addr.S */
5547    /*
5548     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5549     * that specifies an instruction that performs "result = r0 op r1".
5550     * This could be an ARM instruction or a function call.  (If the result
5551     * comes back in a register other than r0, you can override "result".)
5552     *
5553     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5554     * vCC (r1).  Useful for integer division and modulus.
5555     *
5556     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5557     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5558     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5559     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5560     */
5561    /* binop/2addr vA, vB */
5562    mov     r9, rINST, lsr #8           @ r9<- A+
5563    mov     r3, rINST, lsr #12          @ r3<- B
5564    and     r9, r9, #15
5565    GET_VREG(r1, r3)                    @ r1<- vB
5566    GET_VREG(r0, r9)                    @ r0<- vA
5567    .if 1
5568    cmp     r1, #0                      @ is second operand zero?
5569    beq     common_errDivideByZero
5570    .endif
5571    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5572
5573                               @ optional op; may set condition codes
5574    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
5575    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5576    SET_VREG(r1, r9)               @ vAA<- r1
5577    GOTO_OPCODE(ip)                     @ jump to next instruction
5578    /* 10-13 instructions */
5579
5580
5581/* ------------------------------ */
5582    .balign 64
5583.L_OP_AND_INT_2ADDR: /* 0xb5 */
5584/* File: armv5te/OP_AND_INT_2ADDR.S */
5585/* File: armv5te/binop2addr.S */
5586    /*
5587     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5588     * that specifies an instruction that performs "result = r0 op r1".
5589     * This could be an ARM instruction or a function call.  (If the result
5590     * comes back in a register other than r0, you can override "result".)
5591     *
5592     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5593     * vCC (r1).  Useful for integer division and modulus.
5594     *
5595     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5596     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5597     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5598     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5599     */
5600    /* binop/2addr vA, vB */
5601    mov     r9, rINST, lsr #8           @ r9<- A+
5602    mov     r3, rINST, lsr #12          @ r3<- B
5603    and     r9, r9, #15
5604    GET_VREG(r1, r3)                    @ r1<- vB
5605    GET_VREG(r0, r9)                    @ r0<- vA
5606    .if 0
5607    cmp     r1, #0                      @ is second operand zero?
5608    beq     common_errDivideByZero
5609    .endif
5610    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5611
5612                               @ optional op; may set condition codes
5613    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
5614    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5615    SET_VREG(r0, r9)               @ vAA<- r0
5616    GOTO_OPCODE(ip)                     @ jump to next instruction
5617    /* 10-13 instructions */
5618
5619
5620/* ------------------------------ */
5621    .balign 64
5622.L_OP_OR_INT_2ADDR: /* 0xb6 */
5623/* File: armv5te/OP_OR_INT_2ADDR.S */
5624/* File: armv5te/binop2addr.S */
5625    /*
5626     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5627     * that specifies an instruction that performs "result = r0 op r1".
5628     * This could be an ARM instruction or a function call.  (If the result
5629     * comes back in a register other than r0, you can override "result".)
5630     *
5631     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5632     * vCC (r1).  Useful for integer division and modulus.
5633     *
5634     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5635     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5636     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5637     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5638     */
5639    /* binop/2addr vA, vB */
5640    mov     r9, rINST, lsr #8           @ r9<- A+
5641    mov     r3, rINST, lsr #12          @ r3<- B
5642    and     r9, r9, #15
5643    GET_VREG(r1, r3)                    @ r1<- vB
5644    GET_VREG(r0, r9)                    @ r0<- vA
5645    .if 0
5646    cmp     r1, #0                      @ is second operand zero?
5647    beq     common_errDivideByZero
5648    .endif
5649    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5650
5651                               @ optional op; may set condition codes
5652    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
5653    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5654    SET_VREG(r0, r9)               @ vAA<- r0
5655    GOTO_OPCODE(ip)                     @ jump to next instruction
5656    /* 10-13 instructions */
5657
5658
5659/* ------------------------------ */
5660    .balign 64
5661.L_OP_XOR_INT_2ADDR: /* 0xb7 */
5662/* File: armv5te/OP_XOR_INT_2ADDR.S */
5663/* File: armv5te/binop2addr.S */
5664    /*
5665     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5666     * that specifies an instruction that performs "result = r0 op r1".
5667     * This could be an ARM instruction or a function call.  (If the result
5668     * comes back in a register other than r0, you can override "result".)
5669     *
5670     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5671     * vCC (r1).  Useful for integer division and modulus.
5672     *
5673     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5674     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5675     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5676     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5677     */
5678    /* binop/2addr vA, vB */
5679    mov     r9, rINST, lsr #8           @ r9<- A+
5680    mov     r3, rINST, lsr #12          @ r3<- B
5681    and     r9, r9, #15
5682    GET_VREG(r1, r3)                    @ r1<- vB
5683    GET_VREG(r0, r9)                    @ r0<- vA
5684    .if 0
5685    cmp     r1, #0                      @ is second operand zero?
5686    beq     common_errDivideByZero
5687    .endif
5688    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5689
5690                               @ optional op; may set condition codes
5691    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
5692    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5693    SET_VREG(r0, r9)               @ vAA<- r0
5694    GOTO_OPCODE(ip)                     @ jump to next instruction
5695    /* 10-13 instructions */
5696
5697
5698/* ------------------------------ */
5699    .balign 64
5700.L_OP_SHL_INT_2ADDR: /* 0xb8 */
5701/* File: armv5te/OP_SHL_INT_2ADDR.S */
5702/* File: armv5te/binop2addr.S */
5703    /*
5704     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5705     * that specifies an instruction that performs "result = r0 op r1".
5706     * This could be an ARM instruction or a function call.  (If the result
5707     * comes back in a register other than r0, you can override "result".)
5708     *
5709     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5710     * vCC (r1).  Useful for integer division and modulus.
5711     *
5712     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5713     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5714     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5715     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5716     */
5717    /* binop/2addr vA, vB */
5718    mov     r9, rINST, lsr #8           @ r9<- A+
5719    mov     r3, rINST, lsr #12          @ r3<- B
5720    and     r9, r9, #15
5721    GET_VREG(r1, r3)                    @ r1<- vB
5722    GET_VREG(r0, r9)                    @ r0<- vA
5723    .if 0
5724    cmp     r1, #0                      @ is second operand zero?
5725    beq     common_errDivideByZero
5726    .endif
5727    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5728
5729    and     r1, r1, #31                           @ optional op; may set condition codes
5730    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
5731    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5732    SET_VREG(r0, r9)               @ vAA<- r0
5733    GOTO_OPCODE(ip)                     @ jump to next instruction
5734    /* 10-13 instructions */
5735
5736
5737/* ------------------------------ */
5738    .balign 64
5739.L_OP_SHR_INT_2ADDR: /* 0xb9 */
5740/* File: armv5te/OP_SHR_INT_2ADDR.S */
5741/* File: armv5te/binop2addr.S */
5742    /*
5743     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5744     * that specifies an instruction that performs "result = r0 op r1".
5745     * This could be an ARM instruction or a function call.  (If the result
5746     * comes back in a register other than r0, you can override "result".)
5747     *
5748     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5749     * vCC (r1).  Useful for integer division and modulus.
5750     *
5751     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5752     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5753     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5754     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5755     */
5756    /* binop/2addr vA, vB */
5757    mov     r9, rINST, lsr #8           @ r9<- A+
5758    mov     r3, rINST, lsr #12          @ r3<- B
5759    and     r9, r9, #15
5760    GET_VREG(r1, r3)                    @ r1<- vB
5761    GET_VREG(r0, r9)                    @ r0<- vA
5762    .if 0
5763    cmp     r1, #0                      @ is second operand zero?
5764    beq     common_errDivideByZero
5765    .endif
5766    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5767
5768    and     r1, r1, #31                           @ optional op; may set condition codes
5769    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
5770    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5771    SET_VREG(r0, r9)               @ vAA<- r0
5772    GOTO_OPCODE(ip)                     @ jump to next instruction
5773    /* 10-13 instructions */
5774
5775
5776/* ------------------------------ */
5777    .balign 64
5778.L_OP_USHR_INT_2ADDR: /* 0xba */
5779/* File: armv5te/OP_USHR_INT_2ADDR.S */
5780/* File: armv5te/binop2addr.S */
5781    /*
5782     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
5783     * that specifies an instruction that performs "result = r0 op r1".
5784     * This could be an ARM instruction or a function call.  (If the result
5785     * comes back in a register other than r0, you can override "result".)
5786     *
5787     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5788     * vCC (r1).  Useful for integer division and modulus.
5789     *
5790     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
5791     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
5792     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
5793     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
5794     */
5795    /* binop/2addr vA, vB */
5796    mov     r9, rINST, lsr #8           @ r9<- A+
5797    mov     r3, rINST, lsr #12          @ r3<- B
5798    and     r9, r9, #15
5799    GET_VREG(r1, r3)                    @ r1<- vB
5800    GET_VREG(r0, r9)                    @ r0<- vA
5801    .if 0
5802    cmp     r1, #0                      @ is second operand zero?
5803    beq     common_errDivideByZero
5804    .endif
5805    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5806
5807    and     r1, r1, #31                           @ optional op; may set condition codes
5808    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
5809    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5810    SET_VREG(r0, r9)               @ vAA<- r0
5811    GOTO_OPCODE(ip)                     @ jump to next instruction
5812    /* 10-13 instructions */
5813
5814
5815/* ------------------------------ */
5816    .balign 64
5817.L_OP_ADD_LONG_2ADDR: /* 0xbb */
5818/* File: armv5te/OP_ADD_LONG_2ADDR.S */
5819/* File: armv5te/binopWide2addr.S */
5820    /*
5821     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5822     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5823     * This could be an ARM instruction or a function call.  (If the result
5824     * comes back in a register other than r0, you can override "result".)
5825     *
5826     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5827     * vCC (r1).  Useful for integer division and modulus.
5828     *
5829     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5830     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5831     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5832     *      rem-double/2addr
5833     */
5834    /* binop/2addr vA, vB */
5835    mov     r9, rINST, lsr #8           @ r9<- A+
5836    mov     r1, rINST, lsr #12          @ r1<- B
5837    and     r9, r9, #15
5838    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5839    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5840    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5841    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5842    .if 0
5843    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5844    beq     common_errDivideByZero
5845    .endif
5846    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5847
5848    adds    r0, r0, r2                           @ optional op; may set condition codes
5849    adc     r1, r1, r3                              @ result<- op, r0-r3 changed
5850    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5851    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5852    GOTO_OPCODE(ip)                     @ jump to next instruction
5853    /* 12-15 instructions */
5854
5855
5856/* ------------------------------ */
5857    .balign 64
5858.L_OP_SUB_LONG_2ADDR: /* 0xbc */
5859/* File: armv5te/OP_SUB_LONG_2ADDR.S */
5860/* File: armv5te/binopWide2addr.S */
5861    /*
5862     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5863     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5864     * This could be an ARM instruction or a function call.  (If the result
5865     * comes back in a register other than r0, you can override "result".)
5866     *
5867     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5868     * vCC (r1).  Useful for integer division and modulus.
5869     *
5870     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5871     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5872     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5873     *      rem-double/2addr
5874     */
5875    /* binop/2addr vA, vB */
5876    mov     r9, rINST, lsr #8           @ r9<- A+
5877    mov     r1, rINST, lsr #12          @ r1<- B
5878    and     r9, r9, #15
5879    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5880    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5881    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5882    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5883    .if 0
5884    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5885    beq     common_errDivideByZero
5886    .endif
5887    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5888
5889    subs    r0, r0, r2                           @ optional op; may set condition codes
5890    sbc     r1, r1, r3                              @ result<- op, r0-r3 changed
5891    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5892    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5893    GOTO_OPCODE(ip)                     @ jump to next instruction
5894    /* 12-15 instructions */
5895
5896
5897/* ------------------------------ */
5898    .balign 64
5899.L_OP_MUL_LONG_2ADDR: /* 0xbd */
5900/* File: armv5te/OP_MUL_LONG_2ADDR.S */
5901    /*
5902     * Signed 64-bit integer multiply, "/2addr" version.
5903     *
5904     * See OP_MUL_LONG for an explanation.
5905     *
5906     * We get a little tight on registers, so to avoid looking up &fp[A]
5907     * again we stuff it into rINST.
5908     */
5909    /* mul-long/2addr vA, vB */
5910    mov     r9, rINST, lsr #8           @ r9<- A+
5911    mov     r1, rINST, lsr #12          @ r1<- B
5912    and     r9, r9, #15
5913    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5914    add     rINST, rFP, r9, lsl #2      @ rINST<- &fp[A]
5915    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5916    ldmia   rINST, {r0-r1}              @ r0/r1<- vAA/vAA+1
5917    mul     ip, r2, r1                  @  ip<- ZxW
5918    umull   r9, r10, r2, r0             @  r9/r10 <- ZxX
5919    mla     r2, r0, r3, ip              @  r2<- YxX + (ZxW)
5920    mov     r0, rINST                   @ r0<- &fp[A] (free up rINST)
5921    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5922    add     r10, r2, r10                @  r10<- r10 + low(ZxW + (YxX))
5923    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5924    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
5925    GOTO_OPCODE(ip)                     @ jump to next instruction
5926
5927/* ------------------------------ */
5928    .balign 64
5929.L_OP_DIV_LONG_2ADDR: /* 0xbe */
5930/* File: armv5te/OP_DIV_LONG_2ADDR.S */
5931/* File: armv5te/binopWide2addr.S */
5932    /*
5933     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5934     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5935     * This could be an ARM instruction or a function call.  (If the result
5936     * comes back in a register other than r0, you can override "result".)
5937     *
5938     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5939     * vCC (r1).  Useful for integer division and modulus.
5940     *
5941     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5942     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5943     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5944     *      rem-double/2addr
5945     */
5946    /* binop/2addr vA, vB */
5947    mov     r9, rINST, lsr #8           @ r9<- A+
5948    mov     r1, rINST, lsr #12          @ r1<- B
5949    and     r9, r9, #15
5950    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5951    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5952    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5953    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5954    .if 1
5955    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5956    beq     common_errDivideByZero
5957    .endif
5958    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
5959
5960                               @ optional op; may set condition codes
5961    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
5962    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
5963    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
5964    GOTO_OPCODE(ip)                     @ jump to next instruction
5965    /* 12-15 instructions */
5966
5967
5968/* ------------------------------ */
5969    .balign 64
5970.L_OP_REM_LONG_2ADDR: /* 0xbf */
5971/* File: armv5te/OP_REM_LONG_2ADDR.S */
5972/* ldivmod returns quotient in r0/r1 and remainder in r2/r3 */
5973/* File: armv5te/binopWide2addr.S */
5974    /*
5975     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
5976     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
5977     * This could be an ARM instruction or a function call.  (If the result
5978     * comes back in a register other than r0, you can override "result".)
5979     *
5980     * If "chkzero" is set to 1, we perform a divide-by-zero check on
5981     * vCC (r1).  Useful for integer division and modulus.
5982     *
5983     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
5984     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
5985     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
5986     *      rem-double/2addr
5987     */
5988    /* binop/2addr vA, vB */
5989    mov     r9, rINST, lsr #8           @ r9<- A+
5990    mov     r1, rINST, lsr #12          @ r1<- B
5991    and     r9, r9, #15
5992    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
5993    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
5994    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
5995    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
5996    .if 1
5997    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
5998    beq     common_errDivideByZero
5999    .endif
6000    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6001
6002                               @ optional op; may set condition codes
6003    bl      __aeabi_ldivmod                              @ result<- op, r0-r3 changed
6004    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6005    stmia   r9, {r2,r3}     @ vAA/vAA+1<- r2/r3
6006    GOTO_OPCODE(ip)                     @ jump to next instruction
6007    /* 12-15 instructions */
6008
6009
6010/* ------------------------------ */
6011    .balign 64
6012.L_OP_AND_LONG_2ADDR: /* 0xc0 */
6013/* File: armv5te/OP_AND_LONG_2ADDR.S */
6014/* File: armv5te/binopWide2addr.S */
6015    /*
6016     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6017     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6018     * This could be an ARM instruction or a function call.  (If the result
6019     * comes back in a register other than r0, you can override "result".)
6020     *
6021     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6022     * vCC (r1).  Useful for integer division and modulus.
6023     *
6024     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6025     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6026     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6027     *      rem-double/2addr
6028     */
6029    /* binop/2addr vA, vB */
6030    mov     r9, rINST, lsr #8           @ r9<- A+
6031    mov     r1, rINST, lsr #12          @ r1<- B
6032    and     r9, r9, #15
6033    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6034    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6035    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6036    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6037    .if 0
6038    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6039    beq     common_errDivideByZero
6040    .endif
6041    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6042
6043    and     r0, r0, r2                           @ optional op; may set condition codes
6044    and     r1, r1, r3                              @ result<- op, r0-r3 changed
6045    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6046    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6047    GOTO_OPCODE(ip)                     @ jump to next instruction
6048    /* 12-15 instructions */
6049
6050
6051/* ------------------------------ */
6052    .balign 64
6053.L_OP_OR_LONG_2ADDR: /* 0xc1 */
6054/* File: armv5te/OP_OR_LONG_2ADDR.S */
6055/* File: armv5te/binopWide2addr.S */
6056    /*
6057     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6058     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6059     * This could be an ARM instruction or a function call.  (If the result
6060     * comes back in a register other than r0, you can override "result".)
6061     *
6062     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6063     * vCC (r1).  Useful for integer division and modulus.
6064     *
6065     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6066     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6067     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6068     *      rem-double/2addr
6069     */
6070    /* binop/2addr vA, vB */
6071    mov     r9, rINST, lsr #8           @ r9<- A+
6072    mov     r1, rINST, lsr #12          @ r1<- B
6073    and     r9, r9, #15
6074    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6075    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6076    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6077    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6078    .if 0
6079    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6080    beq     common_errDivideByZero
6081    .endif
6082    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6083
6084    orr     r0, r0, r2                           @ optional op; may set condition codes
6085    orr     r1, r1, r3                              @ result<- op, r0-r3 changed
6086    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6087    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6088    GOTO_OPCODE(ip)                     @ jump to next instruction
6089    /* 12-15 instructions */
6090
6091
6092/* ------------------------------ */
6093    .balign 64
6094.L_OP_XOR_LONG_2ADDR: /* 0xc2 */
6095/* File: armv5te/OP_XOR_LONG_2ADDR.S */
6096/* File: armv5te/binopWide2addr.S */
6097    /*
6098     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6099     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6100     * This could be an ARM instruction or a function call.  (If the result
6101     * comes back in a register other than r0, you can override "result".)
6102     *
6103     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6104     * vCC (r1).  Useful for integer division and modulus.
6105     *
6106     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6107     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6108     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6109     *      rem-double/2addr
6110     */
6111    /* binop/2addr vA, vB */
6112    mov     r9, rINST, lsr #8           @ r9<- A+
6113    mov     r1, rINST, lsr #12          @ r1<- B
6114    and     r9, r9, #15
6115    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6116    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6117    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6118    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6119    .if 0
6120    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6121    beq     common_errDivideByZero
6122    .endif
6123    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6124
6125    eor     r0, r0, r2                           @ optional op; may set condition codes
6126    eor     r1, r1, r3                              @ result<- op, r0-r3 changed
6127    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6128    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6129    GOTO_OPCODE(ip)                     @ jump to next instruction
6130    /* 12-15 instructions */
6131
6132
6133/* ------------------------------ */
6134    .balign 64
6135.L_OP_SHL_LONG_2ADDR: /* 0xc3 */
6136/* File: armv5te/OP_SHL_LONG_2ADDR.S */
6137    /*
6138     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6139     * 32-bit shift distance.
6140     */
6141    /* shl-long/2addr vA, vB */
6142    mov     r9, rINST, lsr #8           @ r9<- A+
6143    mov     r3, rINST, lsr #12          @ r3<- B
6144    and     r9, r9, #15
6145    GET_VREG(r2, r3)                    @ r2<- vB
6146    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6147    and     r2, r2, #63                 @ r2<- r2 & 0x3f
6148    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6149
6150    mov     r1, r1, asl r2              @  r1<- r1 << r2
6151    rsb     r3, r2, #32                 @  r3<- 32 - r2
6152    orr     r1, r1, r0, lsr r3          @  r1<- r1 | (r0 << (32-r2))
6153    subs    ip, r2, #32                 @  ip<- r2 - 32
6154    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6155    movpl   r1, r0, asl ip              @  if r2 >= 32, r1<- r0 << (r2-32)
6156    mov     r0, r0, asl r2              @  r0<- r0 << r2
6157    b       .LOP_SHL_LONG_2ADDR_finish
6158
6159/* ------------------------------ */
6160    .balign 64
6161.L_OP_SHR_LONG_2ADDR: /* 0xc4 */
6162/* File: armv5te/OP_SHR_LONG_2ADDR.S */
6163    /*
6164     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6165     * 32-bit shift distance.
6166     */
6167    /* shr-long/2addr vA, vB */
6168    mov     r9, rINST, lsr #8           @ r9<- A+
6169    mov     r3, rINST, lsr #12          @ r3<- B
6170    and     r9, r9, #15
6171    GET_VREG(r2, r3)                    @ r2<- vB
6172    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6173    and     r2, r2, #63                 @ r2<- r2 & 0x3f
6174    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6175
6176    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
6177    rsb     r3, r2, #32                 @  r3<- 32 - r2
6178    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
6179    subs    ip, r2, #32                 @  ip<- r2 - 32
6180    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6181    movpl   r0, r1, asr ip              @  if r2 >= 32, r0<-r1 >> (r2-32)
6182    mov     r1, r1, asr r2              @  r1<- r1 >> r2
6183    b       .LOP_SHR_LONG_2ADDR_finish
6184
6185/* ------------------------------ */
6186    .balign 64
6187.L_OP_USHR_LONG_2ADDR: /* 0xc5 */
6188/* File: armv5te/OP_USHR_LONG_2ADDR.S */
6189    /*
6190     * Long integer shift, 2addr version.  vA is 64-bit value/result, vB is
6191     * 32-bit shift distance.
6192     */
6193    /* ushr-long/2addr vA, vB */
6194    mov     r9, rINST, lsr #8           @ r9<- A+
6195    mov     r3, rINST, lsr #12          @ r3<- B
6196    and     r9, r9, #15
6197    GET_VREG(r2, r3)                    @ r2<- vB
6198    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6199    and     r2, r2, #63                 @ r2<- r2 & 0x3f
6200    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6201
6202    mov     r0, r0, lsr r2              @  r0<- r2 >> r2
6203    rsb     r3, r2, #32                 @  r3<- 32 - r2
6204    orr     r0, r0, r1, asl r3          @  r0<- r0 | (r1 << (32-r2))
6205    subs    ip, r2, #32                 @  ip<- r2 - 32
6206    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6207    movpl   r0, r1, lsr ip              @  if r2 >= 32, r0<-r1 >>> (r2-32)
6208    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
6209    b       .LOP_USHR_LONG_2ADDR_finish
6210
6211/* ------------------------------ */
6212    .balign 64
6213.L_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
6214/* File: armv5te/OP_ADD_FLOAT_2ADDR.S */
6215/* File: armv5te/binop2addr.S */
6216    /*
6217     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6218     * that specifies an instruction that performs "result = r0 op r1".
6219     * This could be an ARM instruction or a function call.  (If the result
6220     * comes back in a register other than r0, you can override "result".)
6221     *
6222     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6223     * vCC (r1).  Useful for integer division and modulus.
6224     *
6225     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6226     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6227     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6228     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6229     */
6230    /* binop/2addr vA, vB */
6231    mov     r9, rINST, lsr #8           @ r9<- A+
6232    mov     r3, rINST, lsr #12          @ r3<- B
6233    and     r9, r9, #15
6234    GET_VREG(r1, r3)                    @ r1<- vB
6235    GET_VREG(r0, r9)                    @ r0<- vA
6236    .if 0
6237    cmp     r1, #0                      @ is second operand zero?
6238    beq     common_errDivideByZero
6239    .endif
6240    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6241
6242                               @ optional op; may set condition codes
6243    bl      __aeabi_fadd                              @ r0<- op, r0-r3 changed
6244    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6245    SET_VREG(r0, r9)               @ vAA<- r0
6246    GOTO_OPCODE(ip)                     @ jump to next instruction
6247    /* 10-13 instructions */
6248
6249
6250/* ------------------------------ */
6251    .balign 64
6252.L_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
6253/* File: armv5te/OP_SUB_FLOAT_2ADDR.S */
6254/* File: armv5te/binop2addr.S */
6255    /*
6256     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6257     * that specifies an instruction that performs "result = r0 op r1".
6258     * This could be an ARM instruction or a function call.  (If the result
6259     * comes back in a register other than r0, you can override "result".)
6260     *
6261     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6262     * vCC (r1).  Useful for integer division and modulus.
6263     *
6264     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6265     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6266     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6267     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6268     */
6269    /* binop/2addr vA, vB */
6270    mov     r9, rINST, lsr #8           @ r9<- A+
6271    mov     r3, rINST, lsr #12          @ r3<- B
6272    and     r9, r9, #15
6273    GET_VREG(r1, r3)                    @ r1<- vB
6274    GET_VREG(r0, r9)                    @ r0<- vA
6275    .if 0
6276    cmp     r1, #0                      @ is second operand zero?
6277    beq     common_errDivideByZero
6278    .endif
6279    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6280
6281                               @ optional op; may set condition codes
6282    bl      __aeabi_fsub                              @ r0<- op, r0-r3 changed
6283    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6284    SET_VREG(r0, r9)               @ vAA<- r0
6285    GOTO_OPCODE(ip)                     @ jump to next instruction
6286    /* 10-13 instructions */
6287
6288
6289/* ------------------------------ */
6290    .balign 64
6291.L_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
6292/* File: armv5te/OP_MUL_FLOAT_2ADDR.S */
6293/* File: armv5te/binop2addr.S */
6294    /*
6295     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6296     * that specifies an instruction that performs "result = r0 op r1".
6297     * This could be an ARM instruction or a function call.  (If the result
6298     * comes back in a register other than r0, you can override "result".)
6299     *
6300     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6301     * vCC (r1).  Useful for integer division and modulus.
6302     *
6303     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6304     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6305     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6306     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6307     */
6308    /* binop/2addr vA, vB */
6309    mov     r9, rINST, lsr #8           @ r9<- A+
6310    mov     r3, rINST, lsr #12          @ r3<- B
6311    and     r9, r9, #15
6312    GET_VREG(r1, r3)                    @ r1<- vB
6313    GET_VREG(r0, r9)                    @ r0<- vA
6314    .if 0
6315    cmp     r1, #0                      @ is second operand zero?
6316    beq     common_errDivideByZero
6317    .endif
6318    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6319
6320                               @ optional op; may set condition codes
6321    bl      __aeabi_fmul                              @ r0<- op, r0-r3 changed
6322    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6323    SET_VREG(r0, r9)               @ vAA<- r0
6324    GOTO_OPCODE(ip)                     @ jump to next instruction
6325    /* 10-13 instructions */
6326
6327
6328/* ------------------------------ */
6329    .balign 64
6330.L_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
6331/* File: armv5te/OP_DIV_FLOAT_2ADDR.S */
6332/* File: armv5te/binop2addr.S */
6333    /*
6334     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6335     * that specifies an instruction that performs "result = r0 op r1".
6336     * This could be an ARM instruction or a function call.  (If the result
6337     * comes back in a register other than r0, you can override "result".)
6338     *
6339     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6340     * vCC (r1).  Useful for integer division and modulus.
6341     *
6342     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6343     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6344     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6345     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6346     */
6347    /* binop/2addr vA, vB */
6348    mov     r9, rINST, lsr #8           @ r9<- A+
6349    mov     r3, rINST, lsr #12          @ r3<- B
6350    and     r9, r9, #15
6351    GET_VREG(r1, r3)                    @ r1<- vB
6352    GET_VREG(r0, r9)                    @ r0<- vA
6353    .if 0
6354    cmp     r1, #0                      @ is second operand zero?
6355    beq     common_errDivideByZero
6356    .endif
6357    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6358
6359                               @ optional op; may set condition codes
6360    bl      __aeabi_fdiv                              @ 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_REM_FLOAT_2ADDR: /* 0xca */
6370/* File: armv5te/OP_REM_FLOAT_2ADDR.S */
6371/* EABI doesn't define a float remainder function, but libm does */
6372/* File: armv5te/binop2addr.S */
6373    /*
6374     * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
6375     * that specifies an instruction that performs "result = r0 op r1".
6376     * This could be an ARM instruction or a function call.  (If the result
6377     * comes back in a register other than r0, you can override "result".)
6378     *
6379     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6380     * vCC (r1).  Useful for integer division and modulus.
6381     *
6382     * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
6383     *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
6384     *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
6385     *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
6386     */
6387    /* binop/2addr vA, vB */
6388    mov     r9, rINST, lsr #8           @ r9<- A+
6389    mov     r3, rINST, lsr #12          @ r3<- B
6390    and     r9, r9, #15
6391    GET_VREG(r1, r3)                    @ r1<- vB
6392    GET_VREG(r0, r9)                    @ r0<- vA
6393    .if 0
6394    cmp     r1, #0                      @ is second operand zero?
6395    beq     common_errDivideByZero
6396    .endif
6397    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6398
6399                               @ optional op; may set condition codes
6400    bl      fmodf                              @ r0<- op, r0-r3 changed
6401    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6402    SET_VREG(r0, r9)               @ vAA<- r0
6403    GOTO_OPCODE(ip)                     @ jump to next instruction
6404    /* 10-13 instructions */
6405
6406
6407/* ------------------------------ */
6408    .balign 64
6409.L_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
6410/* File: armv5te/OP_ADD_DOUBLE_2ADDR.S */
6411/* File: armv5te/binopWide2addr.S */
6412    /*
6413     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6414     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6415     * This could be an ARM instruction or a function call.  (If the result
6416     * comes back in a register other than r0, you can override "result".)
6417     *
6418     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6419     * vCC (r1).  Useful for integer division and modulus.
6420     *
6421     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6422     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6423     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6424     *      rem-double/2addr
6425     */
6426    /* binop/2addr vA, vB */
6427    mov     r9, rINST, lsr #8           @ r9<- A+
6428    mov     r1, rINST, lsr #12          @ r1<- B
6429    and     r9, r9, #15
6430    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6431    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6432    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6433    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6434    .if 0
6435    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6436    beq     common_errDivideByZero
6437    .endif
6438    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6439
6440                               @ optional op; may set condition codes
6441    bl      __aeabi_dadd                              @ result<- op, r0-r3 changed
6442    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6443    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6444    GOTO_OPCODE(ip)                     @ jump to next instruction
6445    /* 12-15 instructions */
6446
6447
6448/* ------------------------------ */
6449    .balign 64
6450.L_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
6451/* File: armv5te/OP_SUB_DOUBLE_2ADDR.S */
6452/* File: armv5te/binopWide2addr.S */
6453    /*
6454     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6455     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6456     * This could be an ARM instruction or a function call.  (If the result
6457     * comes back in a register other than r0, you can override "result".)
6458     *
6459     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6460     * vCC (r1).  Useful for integer division and modulus.
6461     *
6462     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6463     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6464     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6465     *      rem-double/2addr
6466     */
6467    /* binop/2addr vA, vB */
6468    mov     r9, rINST, lsr #8           @ r9<- A+
6469    mov     r1, rINST, lsr #12          @ r1<- B
6470    and     r9, r9, #15
6471    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6472    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6473    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6474    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6475    .if 0
6476    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6477    beq     common_errDivideByZero
6478    .endif
6479    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6480
6481                               @ optional op; may set condition codes
6482    bl      __aeabi_dsub                              @ result<- op, r0-r3 changed
6483    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6484    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6485    GOTO_OPCODE(ip)                     @ jump to next instruction
6486    /* 12-15 instructions */
6487
6488
6489/* ------------------------------ */
6490    .balign 64
6491.L_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
6492/* File: armv5te/OP_MUL_DOUBLE_2ADDR.S */
6493/* File: armv5te/binopWide2addr.S */
6494    /*
6495     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6496     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6497     * This could be an ARM instruction or a function call.  (If the result
6498     * comes back in a register other than r0, you can override "result".)
6499     *
6500     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6501     * vCC (r1).  Useful for integer division and modulus.
6502     *
6503     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6504     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6505     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6506     *      rem-double/2addr
6507     */
6508    /* binop/2addr vA, vB */
6509    mov     r9, rINST, lsr #8           @ r9<- A+
6510    mov     r1, rINST, lsr #12          @ r1<- B
6511    and     r9, r9, #15
6512    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6513    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6514    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6515    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6516    .if 0
6517    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6518    beq     common_errDivideByZero
6519    .endif
6520    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6521
6522                               @ optional op; may set condition codes
6523    bl      __aeabi_dmul                              @ result<- op, r0-r3 changed
6524    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6525    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6526    GOTO_OPCODE(ip)                     @ jump to next instruction
6527    /* 12-15 instructions */
6528
6529
6530/* ------------------------------ */
6531    .balign 64
6532.L_OP_DIV_DOUBLE_2ADDR: /* 0xce */
6533/* File: armv5te/OP_DIV_DOUBLE_2ADDR.S */
6534/* File: armv5te/binopWide2addr.S */
6535    /*
6536     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6537     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6538     * This could be an ARM instruction or a function call.  (If the result
6539     * comes back in a register other than r0, you can override "result".)
6540     *
6541     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6542     * vCC (r1).  Useful for integer division and modulus.
6543     *
6544     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6545     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6546     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6547     *      rem-double/2addr
6548     */
6549    /* binop/2addr vA, vB */
6550    mov     r9, rINST, lsr #8           @ r9<- A+
6551    mov     r1, rINST, lsr #12          @ r1<- B
6552    and     r9, r9, #15
6553    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6554    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6555    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6556    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6557    .if 0
6558    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6559    beq     common_errDivideByZero
6560    .endif
6561    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6562
6563                               @ optional op; may set condition codes
6564    bl      __aeabi_ddiv                              @ result<- op, r0-r3 changed
6565    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6566    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6567    GOTO_OPCODE(ip)                     @ jump to next instruction
6568    /* 12-15 instructions */
6569
6570
6571/* ------------------------------ */
6572    .balign 64
6573.L_OP_REM_DOUBLE_2ADDR: /* 0xcf */
6574/* File: armv5te/OP_REM_DOUBLE_2ADDR.S */
6575/* EABI doesn't define a double remainder function, but libm does */
6576/* File: armv5te/binopWide2addr.S */
6577    /*
6578     * Generic 64-bit "/2addr" binary operation.  Provide an "instr" line
6579     * that specifies an instruction that performs "result = r0-r1 op r2-r3".
6580     * This could be an ARM instruction or a function call.  (If the result
6581     * comes back in a register other than r0, you can override "result".)
6582     *
6583     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6584     * vCC (r1).  Useful for integer division and modulus.
6585     *
6586     * For: add-long/2addr, sub-long/2addr, div-long/2addr, rem-long/2addr,
6587     *      and-long/2addr, or-long/2addr, xor-long/2addr, add-double/2addr,
6588     *      sub-double/2addr, mul-double/2addr, div-double/2addr,
6589     *      rem-double/2addr
6590     */
6591    /* binop/2addr vA, vB */
6592    mov     r9, rINST, lsr #8           @ r9<- A+
6593    mov     r1, rINST, lsr #12          @ r1<- B
6594    and     r9, r9, #15
6595    add     r1, rFP, r1, lsl #2         @ r1<- &fp[B]
6596    add     r9, rFP, r9, lsl #2         @ r9<- &fp[A]
6597    ldmia   r1, {r2-r3}                 @ r2/r3<- vBB/vBB+1
6598    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
6599    .if 0
6600    orrs    ip, r2, r3                  @ second arg (r2-r3) is zero?
6601    beq     common_errDivideByZero
6602    .endif
6603    FETCH_ADVANCE_INST(1)               @ advance rPC, load rINST
6604
6605                               @ optional op; may set condition codes
6606    bl      fmod                              @ result<- op, r0-r3 changed
6607    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6608    stmia   r9, {r0,r1}     @ vAA/vAA+1<- r0/r1
6609    GOTO_OPCODE(ip)                     @ jump to next instruction
6610    /* 12-15 instructions */
6611
6612
6613/* ------------------------------ */
6614    .balign 64
6615.L_OP_ADD_INT_LIT16: /* 0xd0 */
6616/* File: armv5te/OP_ADD_INT_LIT16.S */
6617/* File: armv5te/binopLit16.S */
6618    /*
6619     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6620     * that specifies an instruction that performs "result = r0 op r1".
6621     * This could be an ARM instruction or a function call.  (If the result
6622     * comes back in a register other than r0, you can override "result".)
6623     *
6624     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6625     * vCC (r1).  Useful for integer division and modulus.
6626     *
6627     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6628     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6629     */
6630    /* binop/lit16 vA, vB, #+CCCC */
6631    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6632    mov     r2, rINST, lsr #12          @ r2<- B
6633    mov     r9, rINST, lsr #8           @ r9<- A+
6634    GET_VREG(r0, r2)                    @ r0<- vB
6635    and     r9, r9, #15
6636    .if 0
6637    cmp     r1, #0                      @ is second operand zero?
6638    beq     common_errDivideByZero
6639    .endif
6640    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6641
6642    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
6643    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6644    SET_VREG(r0, r9)               @ vAA<- r0
6645    GOTO_OPCODE(ip)                     @ jump to next instruction
6646    /* 10-13 instructions */
6647
6648
6649/* ------------------------------ */
6650    .balign 64
6651.L_OP_RSUB_INT: /* 0xd1 */
6652/* File: armv5te/OP_RSUB_INT.S */
6653/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
6654/* File: armv5te/binopLit16.S */
6655    /*
6656     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6657     * that specifies an instruction that performs "result = r0 op r1".
6658     * This could be an ARM instruction or a function call.  (If the result
6659     * comes back in a register other than r0, you can override "result".)
6660     *
6661     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6662     * vCC (r1).  Useful for integer division and modulus.
6663     *
6664     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6665     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6666     */
6667    /* binop/lit16 vA, vB, #+CCCC */
6668    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6669    mov     r2, rINST, lsr #12          @ r2<- B
6670    mov     r9, rINST, lsr #8           @ r9<- A+
6671    GET_VREG(r0, r2)                    @ r0<- vB
6672    and     r9, r9, #15
6673    .if 0
6674    cmp     r1, #0                      @ is second operand zero?
6675    beq     common_errDivideByZero
6676    .endif
6677    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6678
6679    rsb     r0, r0, r1                              @ r0<- op, r0-r3 changed
6680    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6681    SET_VREG(r0, r9)               @ vAA<- r0
6682    GOTO_OPCODE(ip)                     @ jump to next instruction
6683    /* 10-13 instructions */
6684
6685
6686/* ------------------------------ */
6687    .balign 64
6688.L_OP_MUL_INT_LIT16: /* 0xd2 */
6689/* File: armv5te/OP_MUL_INT_LIT16.S */
6690/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
6691/* File: armv5te/binopLit16.S */
6692    /*
6693     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6694     * that specifies an instruction that performs "result = r0 op r1".
6695     * This could be an ARM instruction or a function call.  (If the result
6696     * comes back in a register other than r0, you can override "result".)
6697     *
6698     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6699     * vCC (r1).  Useful for integer division and modulus.
6700     *
6701     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6702     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6703     */
6704    /* binop/lit16 vA, vB, #+CCCC */
6705    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6706    mov     r2, rINST, lsr #12          @ r2<- B
6707    mov     r9, rINST, lsr #8           @ r9<- A+
6708    GET_VREG(r0, r2)                    @ r0<- vB
6709    and     r9, r9, #15
6710    .if 0
6711    cmp     r1, #0                      @ is second operand zero?
6712    beq     common_errDivideByZero
6713    .endif
6714    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6715
6716    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
6717    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6718    SET_VREG(r0, r9)               @ vAA<- r0
6719    GOTO_OPCODE(ip)                     @ jump to next instruction
6720    /* 10-13 instructions */
6721
6722
6723/* ------------------------------ */
6724    .balign 64
6725.L_OP_DIV_INT_LIT16: /* 0xd3 */
6726/* File: armv5te/OP_DIV_INT_LIT16.S */
6727/* File: armv5te/binopLit16.S */
6728    /*
6729     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6730     * that specifies an instruction that performs "result = r0 op r1".
6731     * This could be an ARM instruction or a function call.  (If the result
6732     * comes back in a register other than r0, you can override "result".)
6733     *
6734     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6735     * vCC (r1).  Useful for integer division and modulus.
6736     *
6737     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6738     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6739     */
6740    /* binop/lit16 vA, vB, #+CCCC */
6741    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6742    mov     r2, rINST, lsr #12          @ r2<- B
6743    mov     r9, rINST, lsr #8           @ r9<- A+
6744    GET_VREG(r0, r2)                    @ r0<- vB
6745    and     r9, r9, #15
6746    .if 1
6747    cmp     r1, #0                      @ is second operand zero?
6748    beq     common_errDivideByZero
6749    .endif
6750    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6751
6752    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
6753    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6754    SET_VREG(r0, r9)               @ vAA<- r0
6755    GOTO_OPCODE(ip)                     @ jump to next instruction
6756    /* 10-13 instructions */
6757
6758
6759/* ------------------------------ */
6760    .balign 64
6761.L_OP_REM_INT_LIT16: /* 0xd4 */
6762/* File: armv5te/OP_REM_INT_LIT16.S */
6763/* idivmod returns quotient in r0 and remainder in r1 */
6764/* File: armv5te/binopLit16.S */
6765    /*
6766     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6767     * that specifies an instruction that performs "result = r0 op r1".
6768     * This could be an ARM instruction or a function call.  (If the result
6769     * comes back in a register other than r0, you can override "result".)
6770     *
6771     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6772     * vCC (r1).  Useful for integer division and modulus.
6773     *
6774     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6775     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6776     */
6777    /* binop/lit16 vA, vB, #+CCCC */
6778    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6779    mov     r2, rINST, lsr #12          @ r2<- B
6780    mov     r9, rINST, lsr #8           @ r9<- A+
6781    GET_VREG(r0, r2)                    @ r0<- vB
6782    and     r9, r9, #15
6783    .if 1
6784    cmp     r1, #0                      @ is second operand zero?
6785    beq     common_errDivideByZero
6786    .endif
6787    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6788
6789    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
6790    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6791    SET_VREG(r1, r9)               @ vAA<- r1
6792    GOTO_OPCODE(ip)                     @ jump to next instruction
6793    /* 10-13 instructions */
6794
6795
6796/* ------------------------------ */
6797    .balign 64
6798.L_OP_AND_INT_LIT16: /* 0xd5 */
6799/* File: armv5te/OP_AND_INT_LIT16.S */
6800/* File: armv5te/binopLit16.S */
6801    /*
6802     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6803     * that specifies an instruction that performs "result = r0 op r1".
6804     * This could be an ARM instruction or a function call.  (If the result
6805     * comes back in a register other than r0, you can override "result".)
6806     *
6807     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6808     * vCC (r1).  Useful for integer division and modulus.
6809     *
6810     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6811     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6812     */
6813    /* binop/lit16 vA, vB, #+CCCC */
6814    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6815    mov     r2, rINST, lsr #12          @ r2<- B
6816    mov     r9, rINST, lsr #8           @ r9<- A+
6817    GET_VREG(r0, r2)                    @ r0<- vB
6818    and     r9, r9, #15
6819    .if 0
6820    cmp     r1, #0                      @ is second operand zero?
6821    beq     common_errDivideByZero
6822    .endif
6823    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6824
6825    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
6826    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6827    SET_VREG(r0, r9)               @ vAA<- r0
6828    GOTO_OPCODE(ip)                     @ jump to next instruction
6829    /* 10-13 instructions */
6830
6831
6832/* ------------------------------ */
6833    .balign 64
6834.L_OP_OR_INT_LIT16: /* 0xd6 */
6835/* File: armv5te/OP_OR_INT_LIT16.S */
6836/* File: armv5te/binopLit16.S */
6837    /*
6838     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6839     * that specifies an instruction that performs "result = r0 op r1".
6840     * This could be an ARM instruction or a function call.  (If the result
6841     * comes back in a register other than r0, you can override "result".)
6842     *
6843     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6844     * vCC (r1).  Useful for integer division and modulus.
6845     *
6846     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6847     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6848     */
6849    /* binop/lit16 vA, vB, #+CCCC */
6850    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6851    mov     r2, rINST, lsr #12          @ r2<- B
6852    mov     r9, rINST, lsr #8           @ r9<- A+
6853    GET_VREG(r0, r2)                    @ r0<- vB
6854    and     r9, r9, #15
6855    .if 0
6856    cmp     r1, #0                      @ is second operand zero?
6857    beq     common_errDivideByZero
6858    .endif
6859    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6860
6861    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
6862    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6863    SET_VREG(r0, r9)               @ vAA<- r0
6864    GOTO_OPCODE(ip)                     @ jump to next instruction
6865    /* 10-13 instructions */
6866
6867
6868/* ------------------------------ */
6869    .balign 64
6870.L_OP_XOR_INT_LIT16: /* 0xd7 */
6871/* File: armv5te/OP_XOR_INT_LIT16.S */
6872/* File: armv5te/binopLit16.S */
6873    /*
6874     * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
6875     * that specifies an instruction that performs "result = r0 op r1".
6876     * This could be an ARM instruction or a function call.  (If the result
6877     * comes back in a register other than r0, you can override "result".)
6878     *
6879     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6880     * vCC (r1).  Useful for integer division and modulus.
6881     *
6882     * For: add-int/lit16, rsub-int, mul-int/lit16, div-int/lit16,
6883     *      rem-int/lit16, and-int/lit16, or-int/lit16, xor-int/lit16
6884     */
6885    /* binop/lit16 vA, vB, #+CCCC */
6886    FETCH_S(r1, 1)                      @ r1<- ssssCCCC (sign-extended)
6887    mov     r2, rINST, lsr #12          @ r2<- B
6888    mov     r9, rINST, lsr #8           @ r9<- A+
6889    GET_VREG(r0, r2)                    @ r0<- vB
6890    and     r9, r9, #15
6891    .if 0
6892    cmp     r1, #0                      @ is second operand zero?
6893    beq     common_errDivideByZero
6894    .endif
6895    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6896
6897    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
6898    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6899    SET_VREG(r0, r9)               @ vAA<- r0
6900    GOTO_OPCODE(ip)                     @ jump to next instruction
6901    /* 10-13 instructions */
6902
6903
6904/* ------------------------------ */
6905    .balign 64
6906.L_OP_ADD_INT_LIT8: /* 0xd8 */
6907/* File: armv5te/OP_ADD_INT_LIT8.S */
6908/* File: armv5te/binopLit8.S */
6909    /*
6910     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6911     * that specifies an instruction that performs "result = r0 op r1".
6912     * This could be an ARM instruction or a function call.  (If the result
6913     * comes back in a register other than r0, you can override "result".)
6914     *
6915     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6916     * vCC (r1).  Useful for integer division and modulus.
6917     *
6918     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6919     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6920     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6921     */
6922    /* binop/lit8 vAA, vBB, #+CC */
6923    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6924    mov     r9, rINST, lsr #8           @ r9<- AA
6925    and     r2, r3, #255                @ r2<- BB
6926    GET_VREG(r0, r2)                    @ r0<- vBB
6927    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6928    .if 0
6929    @cmp     r1, #0                      @ is second operand zero?
6930    beq     common_errDivideByZero
6931    .endif
6932    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6933
6934                               @ optional op; may set condition codes
6935    add     r0, r0, r1                              @ r0<- op, r0-r3 changed
6936    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6937    SET_VREG(r0, r9)               @ vAA<- r0
6938    GOTO_OPCODE(ip)                     @ jump to next instruction
6939    /* 10-12 instructions */
6940
6941
6942/* ------------------------------ */
6943    .balign 64
6944.L_OP_RSUB_INT_LIT8: /* 0xd9 */
6945/* File: armv5te/OP_RSUB_INT_LIT8.S */
6946/* File: armv5te/binopLit8.S */
6947    /*
6948     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6949     * that specifies an instruction that performs "result = r0 op r1".
6950     * This could be an ARM instruction or a function call.  (If the result
6951     * comes back in a register other than r0, you can override "result".)
6952     *
6953     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6954     * vCC (r1).  Useful for integer division and modulus.
6955     *
6956     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6957     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6958     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6959     */
6960    /* binop/lit8 vAA, vBB, #+CC */
6961    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
6962    mov     r9, rINST, lsr #8           @ r9<- AA
6963    and     r2, r3, #255                @ r2<- BB
6964    GET_VREG(r0, r2)                    @ r0<- vBB
6965    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
6966    .if 0
6967    @cmp     r1, #0                      @ is second operand zero?
6968    beq     common_errDivideByZero
6969    .endif
6970    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
6971
6972                               @ optional op; may set condition codes
6973    rsb     r0, r0, r1                              @ r0<- op, r0-r3 changed
6974    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
6975    SET_VREG(r0, r9)               @ vAA<- r0
6976    GOTO_OPCODE(ip)                     @ jump to next instruction
6977    /* 10-12 instructions */
6978
6979
6980/* ------------------------------ */
6981    .balign 64
6982.L_OP_MUL_INT_LIT8: /* 0xda */
6983/* File: armv5te/OP_MUL_INT_LIT8.S */
6984/* must be "mul r0, r1, r0" -- "r0, r0, r1" is illegal */
6985/* File: armv5te/binopLit8.S */
6986    /*
6987     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
6988     * that specifies an instruction that performs "result = r0 op r1".
6989     * This could be an ARM instruction or a function call.  (If the result
6990     * comes back in a register other than r0, you can override "result".)
6991     *
6992     * If "chkzero" is set to 1, we perform a divide-by-zero check on
6993     * vCC (r1).  Useful for integer division and modulus.
6994     *
6995     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
6996     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
6997     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
6998     */
6999    /* binop/lit8 vAA, vBB, #+CC */
7000    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7001    mov     r9, rINST, lsr #8           @ r9<- AA
7002    and     r2, r3, #255                @ r2<- BB
7003    GET_VREG(r0, r2)                    @ r0<- vBB
7004    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7005    .if 0
7006    @cmp     r1, #0                      @ is second operand zero?
7007    beq     common_errDivideByZero
7008    .endif
7009    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7010
7011                               @ optional op; may set condition codes
7012    mul     r0, r1, r0                              @ r0<- op, r0-r3 changed
7013    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7014    SET_VREG(r0, r9)               @ vAA<- r0
7015    GOTO_OPCODE(ip)                     @ jump to next instruction
7016    /* 10-12 instructions */
7017
7018
7019/* ------------------------------ */
7020    .balign 64
7021.L_OP_DIV_INT_LIT8: /* 0xdb */
7022/* File: armv5te/OP_DIV_INT_LIT8.S */
7023/* File: armv5te/binopLit8.S */
7024    /*
7025     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7026     * that specifies an instruction that performs "result = r0 op r1".
7027     * This could be an ARM instruction or a function call.  (If the result
7028     * comes back in a register other than r0, you can override "result".)
7029     *
7030     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7031     * vCC (r1).  Useful for integer division and modulus.
7032     *
7033     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7034     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7035     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7036     */
7037    /* binop/lit8 vAA, vBB, #+CC */
7038    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7039    mov     r9, rINST, lsr #8           @ r9<- AA
7040    and     r2, r3, #255                @ r2<- BB
7041    GET_VREG(r0, r2)                    @ r0<- vBB
7042    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7043    .if 1
7044    @cmp     r1, #0                      @ is second operand zero?
7045    beq     common_errDivideByZero
7046    .endif
7047    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7048
7049                               @ optional op; may set condition codes
7050    bl     __aeabi_idiv                              @ r0<- op, r0-r3 changed
7051    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7052    SET_VREG(r0, r9)               @ vAA<- r0
7053    GOTO_OPCODE(ip)                     @ jump to next instruction
7054    /* 10-12 instructions */
7055
7056
7057/* ------------------------------ */
7058    .balign 64
7059.L_OP_REM_INT_LIT8: /* 0xdc */
7060/* File: armv5te/OP_REM_INT_LIT8.S */
7061/* idivmod returns quotient in r0 and remainder in r1 */
7062/* File: armv5te/binopLit8.S */
7063    /*
7064     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7065     * that specifies an instruction that performs "result = r0 op r1".
7066     * This could be an ARM instruction or a function call.  (If the result
7067     * comes back in a register other than r0, you can override "result".)
7068     *
7069     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7070     * vCC (r1).  Useful for integer division and modulus.
7071     *
7072     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7073     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7074     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7075     */
7076    /* binop/lit8 vAA, vBB, #+CC */
7077    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7078    mov     r9, rINST, lsr #8           @ r9<- AA
7079    and     r2, r3, #255                @ r2<- BB
7080    GET_VREG(r0, r2)                    @ r0<- vBB
7081    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7082    .if 1
7083    @cmp     r1, #0                      @ is second operand zero?
7084    beq     common_errDivideByZero
7085    .endif
7086    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7087
7088                               @ optional op; may set condition codes
7089    bl      __aeabi_idivmod                              @ r1<- op, r0-r3 changed
7090    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7091    SET_VREG(r1, r9)               @ vAA<- r1
7092    GOTO_OPCODE(ip)                     @ jump to next instruction
7093    /* 10-12 instructions */
7094
7095
7096/* ------------------------------ */
7097    .balign 64
7098.L_OP_AND_INT_LIT8: /* 0xdd */
7099/* File: armv5te/OP_AND_INT_LIT8.S */
7100/* File: armv5te/binopLit8.S */
7101    /*
7102     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7103     * that specifies an instruction that performs "result = r0 op r1".
7104     * This could be an ARM instruction or a function call.  (If the result
7105     * comes back in a register other than r0, you can override "result".)
7106     *
7107     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7108     * vCC (r1).  Useful for integer division and modulus.
7109     *
7110     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7111     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7112     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7113     */
7114    /* binop/lit8 vAA, vBB, #+CC */
7115    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7116    mov     r9, rINST, lsr #8           @ r9<- AA
7117    and     r2, r3, #255                @ r2<- BB
7118    GET_VREG(r0, r2)                    @ r0<- vBB
7119    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7120    .if 0
7121    @cmp     r1, #0                      @ is second operand zero?
7122    beq     common_errDivideByZero
7123    .endif
7124    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7125
7126                               @ optional op; may set condition codes
7127    and     r0, r0, r1                              @ r0<- op, r0-r3 changed
7128    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7129    SET_VREG(r0, r9)               @ vAA<- r0
7130    GOTO_OPCODE(ip)                     @ jump to next instruction
7131    /* 10-12 instructions */
7132
7133
7134/* ------------------------------ */
7135    .balign 64
7136.L_OP_OR_INT_LIT8: /* 0xde */
7137/* File: armv5te/OP_OR_INT_LIT8.S */
7138/* File: armv5te/binopLit8.S */
7139    /*
7140     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7141     * that specifies an instruction that performs "result = r0 op r1".
7142     * This could be an ARM instruction or a function call.  (If the result
7143     * comes back in a register other than r0, you can override "result".)
7144     *
7145     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7146     * vCC (r1).  Useful for integer division and modulus.
7147     *
7148     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7149     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7150     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7151     */
7152    /* binop/lit8 vAA, vBB, #+CC */
7153    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7154    mov     r9, rINST, lsr #8           @ r9<- AA
7155    and     r2, r3, #255                @ r2<- BB
7156    GET_VREG(r0, r2)                    @ r0<- vBB
7157    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7158    .if 0
7159    @cmp     r1, #0                      @ is second operand zero?
7160    beq     common_errDivideByZero
7161    .endif
7162    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7163
7164                               @ optional op; may set condition codes
7165    orr     r0, r0, r1                              @ r0<- op, r0-r3 changed
7166    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7167    SET_VREG(r0, r9)               @ vAA<- r0
7168    GOTO_OPCODE(ip)                     @ jump to next instruction
7169    /* 10-12 instructions */
7170
7171
7172/* ------------------------------ */
7173    .balign 64
7174.L_OP_XOR_INT_LIT8: /* 0xdf */
7175/* File: armv5te/OP_XOR_INT_LIT8.S */
7176/* File: armv5te/binopLit8.S */
7177    /*
7178     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7179     * that specifies an instruction that performs "result = r0 op r1".
7180     * This could be an ARM instruction or a function call.  (If the result
7181     * comes back in a register other than r0, you can override "result".)
7182     *
7183     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7184     * vCC (r1).  Useful for integer division and modulus.
7185     *
7186     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7187     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7188     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7189     */
7190    /* binop/lit8 vAA, vBB, #+CC */
7191    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7192    mov     r9, rINST, lsr #8           @ r9<- AA
7193    and     r2, r3, #255                @ r2<- BB
7194    GET_VREG(r0, r2)                    @ r0<- vBB
7195    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7196    .if 0
7197    @cmp     r1, #0                      @ is second operand zero?
7198    beq     common_errDivideByZero
7199    .endif
7200    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7201
7202                               @ optional op; may set condition codes
7203    eor     r0, r0, r1                              @ r0<- op, r0-r3 changed
7204    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7205    SET_VREG(r0, r9)               @ vAA<- r0
7206    GOTO_OPCODE(ip)                     @ jump to next instruction
7207    /* 10-12 instructions */
7208
7209
7210/* ------------------------------ */
7211    .balign 64
7212.L_OP_SHL_INT_LIT8: /* 0xe0 */
7213/* File: armv5te/OP_SHL_INT_LIT8.S */
7214/* File: armv5te/binopLit8.S */
7215    /*
7216     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7217     * that specifies an instruction that performs "result = r0 op r1".
7218     * This could be an ARM instruction or a function call.  (If the result
7219     * comes back in a register other than r0, you can override "result".)
7220     *
7221     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7222     * vCC (r1).  Useful for integer division and modulus.
7223     *
7224     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7225     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7226     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7227     */
7228    /* binop/lit8 vAA, vBB, #+CC */
7229    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7230    mov     r9, rINST, lsr #8           @ r9<- AA
7231    and     r2, r3, #255                @ r2<- BB
7232    GET_VREG(r0, r2)                    @ r0<- vBB
7233    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7234    .if 0
7235    @cmp     r1, #0                      @ is second operand zero?
7236    beq     common_errDivideByZero
7237    .endif
7238    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7239
7240    and     r1, r1, #31                           @ optional op; may set condition codes
7241    mov     r0, r0, asl r1                              @ r0<- op, r0-r3 changed
7242    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7243    SET_VREG(r0, r9)               @ vAA<- r0
7244    GOTO_OPCODE(ip)                     @ jump to next instruction
7245    /* 10-12 instructions */
7246
7247
7248/* ------------------------------ */
7249    .balign 64
7250.L_OP_SHR_INT_LIT8: /* 0xe1 */
7251/* File: armv5te/OP_SHR_INT_LIT8.S */
7252/* File: armv5te/binopLit8.S */
7253    /*
7254     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7255     * that specifies an instruction that performs "result = r0 op r1".
7256     * This could be an ARM instruction or a function call.  (If the result
7257     * comes back in a register other than r0, you can override "result".)
7258     *
7259     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7260     * vCC (r1).  Useful for integer division and modulus.
7261     *
7262     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7263     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7264     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7265     */
7266    /* binop/lit8 vAA, vBB, #+CC */
7267    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7268    mov     r9, rINST, lsr #8           @ r9<- AA
7269    and     r2, r3, #255                @ r2<- BB
7270    GET_VREG(r0, r2)                    @ r0<- vBB
7271    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7272    .if 0
7273    @cmp     r1, #0                      @ is second operand zero?
7274    beq     common_errDivideByZero
7275    .endif
7276    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7277
7278    and     r1, r1, #31                           @ optional op; may set condition codes
7279    mov     r0, r0, asr r1                              @ r0<- op, r0-r3 changed
7280    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7281    SET_VREG(r0, r9)               @ vAA<- r0
7282    GOTO_OPCODE(ip)                     @ jump to next instruction
7283    /* 10-12 instructions */
7284
7285
7286/* ------------------------------ */
7287    .balign 64
7288.L_OP_USHR_INT_LIT8: /* 0xe2 */
7289/* File: armv5te/OP_USHR_INT_LIT8.S */
7290/* File: armv5te/binopLit8.S */
7291    /*
7292     * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
7293     * that specifies an instruction that performs "result = r0 op r1".
7294     * This could be an ARM instruction or a function call.  (If the result
7295     * comes back in a register other than r0, you can override "result".)
7296     *
7297     * If "chkzero" is set to 1, we perform a divide-by-zero check on
7298     * vCC (r1).  Useful for integer division and modulus.
7299     *
7300     * For: add-int/lit8, rsub-int/lit8, mul-int/lit8, div-int/lit8,
7301     *      rem-int/lit8, and-int/lit8, or-int/lit8, xor-int/lit8,
7302     *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
7303     */
7304    /* binop/lit8 vAA, vBB, #+CC */
7305    FETCH_S(r3, 1)                      @ r3<- ssssCCBB (sign-extended for CC)
7306    mov     r9, rINST, lsr #8           @ r9<- AA
7307    and     r2, r3, #255                @ r2<- BB
7308    GET_VREG(r0, r2)                    @ r0<- vBB
7309    movs    r1, r3, asr #8              @ r1<- ssssssCC (sign extended)
7310    .if 0
7311    @cmp     r1, #0                      @ is second operand zero?
7312    beq     common_errDivideByZero
7313    .endif
7314    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7315
7316    and     r1, r1, #31                           @ optional op; may set condition codes
7317    mov     r0, r0, lsr r1                              @ r0<- op, r0-r3 changed
7318    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7319    SET_VREG(r0, r9)               @ vAA<- r0
7320    GOTO_OPCODE(ip)                     @ jump to next instruction
7321    /* 10-12 instructions */
7322
7323
7324/* ------------------------------ */
7325    .balign 64
7326.L_OP_IGET_VOLATILE: /* 0xe3 */
7327/* File: armv5te/OP_IGET_VOLATILE.S */
7328/* File: armv5te/OP_IGET.S */
7329    /*
7330     * General 32-bit instance field get.
7331     *
7332     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7333     */
7334    /* op vA, vB, field@CCCC */
7335    mov     r0, rINST, lsr #12          @ r0<- B
7336    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7337    FETCH(r1, 1)                        @ r1<- field ref CCCC
7338    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7339    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7340    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7341    cmp     r0, #0                      @ is resolved entry null?
7342    bne     .LOP_IGET_VOLATILE_finish          @ no, already resolved
73438:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7344    EXPORT_PC()                         @ resolve() could throw
7345    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7346    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7347    cmp     r0, #0
7348    bne     .LOP_IGET_VOLATILE_finish
7349    b       common_exceptionThrown
7350
7351
7352/* ------------------------------ */
7353    .balign 64
7354.L_OP_IPUT_VOLATILE: /* 0xe4 */
7355/* File: armv5te/OP_IPUT_VOLATILE.S */
7356/* File: armv5te/OP_IPUT.S */
7357    /*
7358     * General 32-bit instance field put.
7359     *
7360     * for: iput, iput-boolean, iput-byte, iput-char, iput-short
7361     */
7362    /* op vA, vB, field@CCCC */
7363    mov     r0, rINST, lsr #12          @ r0<- B
7364    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7365    FETCH(r1, 1)                        @ r1<- field ref CCCC
7366    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7367    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7368    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7369    cmp     r0, #0                      @ is resolved entry null?
7370    bne     .LOP_IPUT_VOLATILE_finish          @ no, already resolved
73718:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7372    EXPORT_PC()                         @ resolve() could throw
7373    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7374    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7375    cmp     r0, #0                      @ success?
7376    bne     .LOP_IPUT_VOLATILE_finish          @ yes, finish up
7377    b       common_exceptionThrown
7378
7379
7380/* ------------------------------ */
7381    .balign 64
7382.L_OP_SGET_VOLATILE: /* 0xe5 */
7383/* File: armv5te/OP_SGET_VOLATILE.S */
7384/* File: armv5te/OP_SGET.S */
7385    /*
7386     * General 32-bit SGET handler.
7387     *
7388     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7389     */
7390    /* op vAA, field@BBBB */
7391    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7392    FETCH(r1, 1)                        @ r1<- field ref BBBB
7393    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
7394    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
7395    cmp     r0, #0                      @ is resolved entry null?
7396    beq     .LOP_SGET_VOLATILE_resolve         @ yes, do resolve
7397.LOP_SGET_VOLATILE_finish: @ field ptr in r0
7398    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7399    SMP_DMB                            @ acquiring load
7400    mov     r2, rINST, lsr #8           @ r2<- AA
7401    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7402    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7403    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7404    GOTO_OPCODE(ip)                     @ jump to next instruction
7405
7406
7407/* ------------------------------ */
7408    .balign 64
7409.L_OP_SPUT_VOLATILE: /* 0xe6 */
7410/* File: armv5te/OP_SPUT_VOLATILE.S */
7411/* File: armv5te/OP_SPUT.S */
7412    /*
7413     * General 32-bit SPUT handler.
7414     *
7415     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
7416     */
7417    /* op vAA, field@BBBB */
7418    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7419    FETCH(r1, 1)                        @ r1<- field ref BBBB
7420    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
7421    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
7422    cmp     r0, #0                      @ is resolved entry null?
7423    beq     .LOP_SPUT_VOLATILE_resolve         @ yes, do resolve
7424.LOP_SPUT_VOLATILE_finish:   @ field ptr in r0
7425    mov     r2, rINST, lsr #8           @ r2<- AA
7426    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7427    GET_VREG(r1, r2)                    @ r1<- fp[AA]
7428    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7429    SMP_DMB_ST                        @ releasing store
7430    str     r1, [r0, #offStaticField_value] @ field<- vAA
7431    SMP_DMB
7432    GOTO_OPCODE(ip)                     @ jump to next instruction
7433
7434
7435/* ------------------------------ */
7436    .balign 64
7437.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
7438/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */
7439/* File: armv5te/OP_IGET.S */
7440    /*
7441     * General 32-bit instance field get.
7442     *
7443     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
7444     */
7445    /* op vA, vB, field@CCCC */
7446    mov     r0, rINST, lsr #12          @ r0<- B
7447    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7448    FETCH(r1, 1)                        @ r1<- field ref CCCC
7449    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7450    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7451    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7452    cmp     r0, #0                      @ is resolved entry null?
7453    bne     .LOP_IGET_OBJECT_VOLATILE_finish          @ no, already resolved
74548:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7455    EXPORT_PC()                         @ resolve() could throw
7456    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7457    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7458    cmp     r0, #0
7459    bne     .LOP_IGET_OBJECT_VOLATILE_finish
7460    b       common_exceptionThrown
7461
7462
7463/* ------------------------------ */
7464    .balign 64
7465.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
7466/* File: armv5te/OP_IGET_WIDE_VOLATILE.S */
7467/* File: armv5te/OP_IGET_WIDE.S */
7468    /*
7469     * Wide 32-bit instance field get.
7470     */
7471    /* iget-wide vA, vB, field@CCCC */
7472    mov     r0, rINST, lsr #12          @ r0<- B
7473    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7474    FETCH(r1, 1)                        @ r1<- field ref CCCC
7475    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7476    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7477    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7478    cmp     r0, #0                      @ is resolved entry null?
7479    bne     .LOP_IGET_WIDE_VOLATILE_finish          @ no, already resolved
74808:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
7481    EXPORT_PC()                         @ resolve() could throw
7482    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7483    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7484    cmp     r0, #0
7485    bne     .LOP_IGET_WIDE_VOLATILE_finish
7486    b       common_exceptionThrown
7487
7488
7489/* ------------------------------ */
7490    .balign 64
7491.L_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
7492/* File: armv5te/OP_IPUT_WIDE_VOLATILE.S */
7493/* File: armv5te/OP_IPUT_WIDE.S */
7494    /* iput-wide vA, vB, field@CCCC */
7495    mov     r0, rINST, lsr #12          @ r0<- B
7496    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7497    FETCH(r1, 1)                        @ r1<- field ref CCCC
7498    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pResFields
7499    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7500    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7501    cmp     r0, #0                      @ is resolved entry null?
7502    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ no, already resolved
75038:  ldr     r2, [rSELF, #offThread_method] @ r2<- current method
7504    EXPORT_PC()                         @ resolve() could throw
7505    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7506    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7507    cmp     r0, #0                      @ success?
7508    bne     .LOP_IPUT_WIDE_VOLATILE_finish          @ yes, finish up
7509    b       common_exceptionThrown
7510
7511
7512/* ------------------------------ */
7513    .balign 64
7514.L_OP_SGET_WIDE_VOLATILE: /* 0xea */
7515/* File: armv5te/OP_SGET_WIDE_VOLATILE.S */
7516/* File: armv5te/OP_SGET_WIDE.S */
7517    /*
7518     * 64-bit SGET handler.
7519     */
7520    /* sget-wide vAA, field@BBBB */
7521    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7522    FETCH(r1, 1)                        @ r1<- field ref BBBB
7523    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
7524    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
7525    cmp     r0, #0                      @ is resolved entry null?
7526    beq     .LOP_SGET_WIDE_VOLATILE_resolve         @ yes, do resolve
7527.LOP_SGET_WIDE_VOLATILE_finish:
7528    mov     r9, rINST, lsr #8           @ r9<- AA
7529    .if 1
7530    add     r0, r0, #offStaticField_value @ r0<- pointer to data
7531    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
7532    .else
7533    ldrd    r0, [r0, #offStaticField_value] @ r0/r1<- field value (aligned)
7534    .endif
7535    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7536    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7537    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
7538    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7539    GOTO_OPCODE(ip)                     @ jump to next instruction
7540
7541
7542/* ------------------------------ */
7543    .balign 64
7544.L_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
7545/* File: armv5te/OP_SPUT_WIDE_VOLATILE.S */
7546/* File: armv5te/OP_SPUT_WIDE.S */
7547    /*
7548     * 64-bit SPUT handler.
7549     */
7550    /* sput-wide vAA, field@BBBB */
7551    ldr     r0, [rSELF, #offThread_methodClassDex]  @ r0<- DvmDex
7552    FETCH(r1, 1)                        @ r1<- field ref BBBB
7553    ldr     r10, [r0, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
7554    mov     r9, rINST, lsr #8           @ r9<- AA
7555    ldr     r2, [r10, r1, lsl #2]        @ r2<- resolved StaticField ptr
7556    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
7557    cmp     r2, #0                      @ is resolved entry null?
7558    beq     .LOP_SPUT_WIDE_VOLATILE_resolve         @ yes, do resolve
7559.LOP_SPUT_WIDE_VOLATILE_finish: @ field ptr in r2, AA in r9
7560    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7561    ldmia   r9, {r0-r1}                 @ r0/r1<- vAA/vAA+1
7562    GET_INST_OPCODE(r10)                @ extract opcode from rINST
7563    .if 1
7564    add     r2, r2, #offStaticField_value @ r2<- pointer to data
7565    bl      dvmQuasiAtomicSwap64Sync    @ stores r0/r1 into addr r2
7566    .else
7567    strd    r0, [r2, #offStaticField_value] @ field<- vAA/vAA+1
7568    .endif
7569    GOTO_OPCODE(r10)                    @ jump to next instruction
7570
7571
7572/* ------------------------------ */
7573    .balign 64
7574.L_OP_BREAKPOINT: /* 0xec */
7575/* File: armv5te/OP_BREAKPOINT.S */
7576    /*
7577     * Breakpoint handler.
7578     *
7579     * Restart this instruction with the original opcode.  By
7580     * the time we get here, the breakpoint will have already been
7581     * handled.
7582     */
7583    mov     r0, rPC
7584    bl      dvmGetOriginalOpcode        @ (rPC)
7585    FETCH(rINST, 0)                     @ reload OP_BREAKPOINT + rest of inst
7586    ldr     r1, [rSELF, #offThread_mainHandlerTable]
7587    and     rINST, #0xff00
7588    orr     rINST, rINST, r0
7589    GOTO_OPCODE_BASE(r1, r0)
7590
7591/* ------------------------------ */
7592    .balign 64
7593.L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
7594/* File: armv5te/OP_THROW_VERIFICATION_ERROR.S */
7595    /*
7596     * Handle a throw-verification-error instruction.  This throws an
7597     * exception for an error discovered during verification.  The
7598     * exception is indicated by AA, with some detail provided by BBBB.
7599     */
7600    /* op AA, ref@BBBB */
7601    ldr     r0, [rSELF, #offThread_method]    @ r0<- self->method
7602    FETCH(r2, 1)                        @ r2<- BBBB
7603    EXPORT_PC()                         @ export the PC
7604    mov     r1, rINST, lsr #8           @ r1<- AA
7605    bl      dvmThrowVerificationError   @ always throws
7606    b       common_exceptionThrown      @ handle exception
7607
7608/* ------------------------------ */
7609    .balign 64
7610.L_OP_EXECUTE_INLINE: /* 0xee */
7611/* File: armv5te/OP_EXECUTE_INLINE.S */
7612    /*
7613     * Execute a "native inline" instruction.
7614     *
7615     * We need to call an InlineOp4Func:
7616     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7617     *
7618     * The first four args are in r0-r3, pointer to return value storage
7619     * is on the stack.  The function's return value is a flag that tells
7620     * us if an exception was thrown.
7621     *
7622     * TUNING: could maintain two tables, pointer in Thread and
7623     * swap if profiler/debuggger active.
7624     */
7625    /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
7626    ldrh    r2, [rSELF, #offThread_subMode]
7627    FETCH(r10, 1)                       @ r10<- BBBB
7628    EXPORT_PC()                         @ can throw
7629    ands    r2, #kSubModeDebugProfile   @ Any going on?
7630    bne     .LOP_EXECUTE_INLINE_debugmode       @ yes - take slow path
7631.LOP_EXECUTE_INLINE_resume:
7632    add     r1, rSELF, #offThread_retval  @ r1<- &self->retval
7633    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7634    mov     r0, rINST, lsr #12          @ r0<- B
7635    str     r1, [sp]                    @ push &self->retval
7636    bl      .LOP_EXECUTE_INLINE_continue        @ make call; will return after
7637    add     sp, sp, #8                  @ pop stack
7638    cmp     r0, #0                      @ test boolean result of inline
7639    beq     common_exceptionThrown      @ returned false, handle exception
7640    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7641    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7642    GOTO_OPCODE(ip)                     @ jump to next instruction
7643
7644/* ------------------------------ */
7645    .balign 64
7646.L_OP_EXECUTE_INLINE_RANGE: /* 0xef */
7647/* File: armv5te/OP_EXECUTE_INLINE_RANGE.S */
7648    /*
7649     * Execute a "native inline" instruction, using "/range" semantics.
7650     * Same idea as execute-inline, but we get the args differently.
7651     *
7652     * We need to call an InlineOp4Func:
7653     *  bool (func)(u4 arg0, u4 arg1, u4 arg2, u4 arg3, JValue* pResult)
7654     *
7655     * The first four args are in r0-r3, pointer to return value storage
7656     * is on the stack.  The function's return value is a flag that tells
7657     * us if an exception was thrown.
7658     */
7659    /* [opt] execute-inline/range {vCCCC..v(CCCC+AA-1)}, inline@BBBB */
7660    ldrh    r2, [rSELF, #offThread_subMode]
7661    FETCH(r10, 1)                       @ r10<- BBBB
7662    EXPORT_PC()                         @ can throw
7663    ands    r2, #kSubModeDebugProfile   @ Any going on?
7664    bne     .LOP_EXECUTE_INLINE_RANGE_debugmode       @ yes - take slow path
7665.LOP_EXECUTE_INLINE_RANGE_resume:
7666    add     r1, rSELF, #offThread_retval  @ r1<- &self->retval
7667    sub     sp, sp, #8                  @ make room for arg, +64 bit align
7668    mov     r0, rINST, lsr #8           @ r0<- AA
7669    str     r1, [sp]                    @ push &self->retval
7670    bl      .LOP_EXECUTE_INLINE_RANGE_continue        @ make call; will return after
7671    add     sp, sp, #8                  @ pop stack
7672    cmp     r0, #0                      @ test boolean result of inline
7673    beq     common_exceptionThrown      @ returned false, handle exception
7674    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
7675    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7676    GOTO_OPCODE(ip)                     @ jump to next instruction
7677
7678/* ------------------------------ */
7679    .balign 64
7680.L_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */
7681/* File: armv5te/OP_INVOKE_OBJECT_INIT_RANGE.S */
7682    /*
7683     * Invoke Object.<init> on an object.  In practice we know that
7684     * Object's nullary constructor doesn't do anything, so we just
7685     * skip it unless a debugger is active.
7686     */
7687    FETCH(r1, 2)                  @ r1<- CCCC
7688    GET_VREG(r0, r1)                    @ r0<- "this" ptr
7689    cmp     r0, #0                      @ check for NULL
7690    beq     common_errNullObject        @ export PC and throw NPE
7691    ldr     r1, [r0, #offObject_clazz]  @ r1<- obj->clazz
7692    ldr     r2, [r1, #offClassObject_accessFlags] @ r2<- clazz->accessFlags
7693    tst     r2, #CLASS_ISFINALIZABLE    @ is this class finalizable?
7694    bne     .LOP_INVOKE_OBJECT_INIT_RANGE_setFinal        @ yes, go
7695.LOP_INVOKE_OBJECT_INIT_RANGE_finish:
7696    ldrh    r1, [rSELF, #offThread_subMode]
7697    ands    r1, #kSubModeDebuggerActive @ debugger active?
7698    bne     .LOP_INVOKE_OBJECT_INIT_RANGE_debugger        @ Yes - skip optimization
7699    FETCH_ADVANCE_INST(2+1)       @ advance to next instr, load rINST
7700    GET_INST_OPCODE(ip)                 @ ip<- opcode from rINST
7701    GOTO_OPCODE(ip)                     @ execute it
7702
7703/* ------------------------------ */
7704    .balign 64
7705.L_OP_RETURN_VOID_BARRIER: /* 0xf1 */
7706/* File: armv5te/OP_RETURN_VOID_BARRIER.S */
7707    SMP_DMB_ST
7708    b       common_returnFromMethod
7709
7710/* ------------------------------ */
7711    .balign 64
7712.L_OP_IGET_QUICK: /* 0xf2 */
7713/* File: armv5te/OP_IGET_QUICK.S */
7714    /* For: iget-quick, iget-object-quick */
7715    /* op vA, vB, offset@CCCC */
7716    mov     r2, rINST, lsr #12          @ r2<- B
7717    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7718    FETCH(r1, 1)                        @ r1<- field byte offset
7719    cmp     r3, #0                      @ check object for null
7720    mov     r2, rINST, lsr #8           @ r2<- A(+)
7721    beq     common_errNullObject        @ object was null
7722    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7723    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7724    and     r2, r2, #15
7725    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7726    SET_VREG(r0, r2)                    @ fp[A]<- r0
7727    GOTO_OPCODE(ip)                     @ jump to next instruction
7728
7729/* ------------------------------ */
7730    .balign 64
7731.L_OP_IGET_WIDE_QUICK: /* 0xf3 */
7732/* File: armv5te/OP_IGET_WIDE_QUICK.S */
7733    /* iget-wide-quick vA, vB, offset@CCCC */
7734    mov     r2, rINST, lsr #12          @ r2<- B
7735    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7736    FETCH(ip, 1)                        @ ip<- field byte offset
7737    cmp     r3, #0                      @ check object for null
7738    mov     r2, rINST, lsr #8           @ r2<- A(+)
7739    beq     common_errNullObject        @ object was null
7740    ldrd    r0, [r3, ip]                @ r0<- obj.field (64 bits, aligned)
7741    and     r2, r2, #15
7742    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7743    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
7744    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7745    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
7746    GOTO_OPCODE(ip)                     @ jump to next instruction
7747
7748/* ------------------------------ */
7749    .balign 64
7750.L_OP_IGET_OBJECT_QUICK: /* 0xf4 */
7751/* File: armv5te/OP_IGET_OBJECT_QUICK.S */
7752/* File: armv5te/OP_IGET_QUICK.S */
7753    /* For: iget-quick, iget-object-quick */
7754    /* op vA, vB, offset@CCCC */
7755    mov     r2, rINST, lsr #12          @ r2<- B
7756    GET_VREG(r3, r2)                    @ r3<- object we're operating on
7757    FETCH(r1, 1)                        @ r1<- field byte offset
7758    cmp     r3, #0                      @ check object for null
7759    mov     r2, rINST, lsr #8           @ r2<- A(+)
7760    beq     common_errNullObject        @ object was null
7761    ldr     r0, [r3, r1]                @ r0<- obj.field (always 32 bits)
7762    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7763    and     r2, r2, #15
7764    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7765    SET_VREG(r0, r2)                    @ fp[A]<- r0
7766    GOTO_OPCODE(ip)                     @ jump to next instruction
7767
7768
7769/* ------------------------------ */
7770    .balign 64
7771.L_OP_IPUT_QUICK: /* 0xf5 */
7772/* File: armv5te/OP_IPUT_QUICK.S */
7773    /* For: iput-quick */
7774    /* op vA, vB, offset@CCCC */
7775    mov     r2, rINST, lsr #12          @ r2<- B
7776    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7777    FETCH(r1, 1)                        @ r1<- field byte offset
7778    cmp     r3, #0                      @ check object for null
7779    mov     r2, rINST, lsr #8           @ r2<- A(+)
7780    beq     common_errNullObject        @ object was null
7781    and     r2, r2, #15
7782    GET_VREG(r0, r2)                    @ r0<- fp[A]
7783    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7784    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7785    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7786    GOTO_OPCODE(ip)                     @ jump to next instruction
7787
7788/* ------------------------------ */
7789    .balign 64
7790.L_OP_IPUT_WIDE_QUICK: /* 0xf6 */
7791/* File: armv5te/OP_IPUT_WIDE_QUICK.S */
7792    /* iput-wide-quick vA, vB, offset@CCCC */
7793    mov     r0, rINST, lsr #8           @ r0<- A(+)
7794    mov     r1, rINST, lsr #12          @ r1<- B
7795    and     r0, r0, #15
7796    GET_VREG(r2, r1)                    @ r2<- fp[B], the object pointer
7797    add     r3, rFP, r0, lsl #2         @ r3<- &fp[A]
7798    cmp     r2, #0                      @ check object for null
7799    ldmia   r3, {r0-r1}                 @ r0/r1<- fp[A]
7800    beq     common_errNullObject        @ object was null
7801    FETCH(r3, 1)                        @ r3<- field byte offset
7802    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7803    strd    r0, [r2, r3]                @ obj.field (64 bits, aligned)<- r0/r1
7804    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7805    GOTO_OPCODE(ip)                     @ jump to next instruction
7806
7807/* ------------------------------ */
7808    .balign 64
7809.L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
7810/* File: armv5te/OP_IPUT_OBJECT_QUICK.S */
7811    /* For: iput-object-quick */
7812    /* op vA, vB, offset@CCCC */
7813    mov     r2, rINST, lsr #12          @ r2<- B
7814    GET_VREG(r3, r2)                    @ r3<- fp[B], the object pointer
7815    FETCH(r1, 1)                        @ r1<- field byte offset
7816    cmp     r3, #0                      @ check object for null
7817    mov     r2, rINST, lsr #8           @ r2<- A(+)
7818    beq     common_errNullObject        @ object was null
7819    and     r2, r2, #15
7820    GET_VREG(r0, r2)                    @ r0<- fp[A]
7821    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
7822    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7823    str     r0, [r3, r1]                @ obj.field (always 32 bits)<- r0
7824    cmp     r0, #0
7825    strneb  r2, [r2, r3, lsr #GC_CARD_SHIFT] @ mark card based on obj head
7826    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7827    GOTO_OPCODE(ip)                     @ jump to next instruction
7828
7829/* ------------------------------ */
7830    .balign 64
7831.L_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
7832/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7833    /*
7834     * Handle an optimized virtual method call.
7835     *
7836     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7837     */
7838    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7839    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7840    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7841    FETCH(r1, 1)                        @ r1<- BBBB
7842    .if     (!0)
7843    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7844    .endif
7845    GET_VREG(r9, r3)                    @ r9<- vC ("this" ptr)
7846    cmp     r9, #0                      @ is "this" null?
7847    beq     common_errNullObject        @ null "this", throw exception
7848    ldr     r2, [r9, #offObject_clazz]  @ r2<- thisPtr->clazz
7849    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7850    EXPORT_PC()                         @ invoke must export
7851    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7852    bl      common_invokeMethodNoRange @ (r0=method, r9="this")
7853
7854/* ------------------------------ */
7855    .balign 64
7856.L_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
7857/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK_RANGE.S */
7858/* File: armv5te/OP_INVOKE_VIRTUAL_QUICK.S */
7859    /*
7860     * Handle an optimized virtual method call.
7861     *
7862     * for: [opt] invoke-virtual-quick, invoke-virtual-quick/range
7863     */
7864    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7865    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7866    FETCH(r3, 2)                        @ r3<- FEDC or CCCC
7867    FETCH(r1, 1)                        @ r1<- BBBB
7868    .if     (!1)
7869    and     r3, r3, #15                 @ r3<- C (or stays CCCC)
7870    .endif
7871    GET_VREG(r9, r3)                    @ r9<- vC ("this" ptr)
7872    cmp     r9, #0                      @ is "this" null?
7873    beq     common_errNullObject        @ null "this", throw exception
7874    ldr     r2, [r9, #offObject_clazz]  @ r2<- thisPtr->clazz
7875    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- thisPtr->clazz->vtable
7876    EXPORT_PC()                         @ invoke must export
7877    ldr     r0, [r2, r1, lsl #2]        @ r3<- vtable[BBBB]
7878    bl      common_invokeMethodRange @ (r0=method, r9="this")
7879
7880
7881/* ------------------------------ */
7882    .balign 64
7883.L_OP_INVOKE_SUPER_QUICK: /* 0xfa */
7884/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7885    /*
7886     * Handle an optimized "super" method call.
7887     *
7888     * for: [opt] invoke-super-quick, invoke-super-quick/range
7889     */
7890    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7891    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7892    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7893    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7894    .if     (!0)
7895    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7896    .endif
7897    FETCH(r1, 1)                        @ r1<- BBBB
7898    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7899    EXPORT_PC()                         @ must export for invoke
7900    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7901    GET_VREG(r9, r10)                   @ r9<- "this"
7902    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7903    cmp     r9, #0                      @ null "this" ref?
7904    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7905    beq     common_errNullObject        @ "this" is null, throw exception
7906    bl      common_invokeMethodNoRange @ (r0=method, r9="this")
7907
7908/* ------------------------------ */
7909    .balign 64
7910.L_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
7911/* File: armv5te/OP_INVOKE_SUPER_QUICK_RANGE.S */
7912/* File: armv5te/OP_INVOKE_SUPER_QUICK.S */
7913    /*
7914     * Handle an optimized "super" method call.
7915     *
7916     * for: [opt] invoke-super-quick, invoke-super-quick/range
7917     */
7918    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
7919    /* op vAA, {vCCCC..v(CCCC+AA-1)}, meth@BBBB */
7920    FETCH(r10, 2)                       @ r10<- GFED or CCCC
7921    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7922    .if     (!1)
7923    and     r10, r10, #15               @ r10<- D (or stays CCCC)
7924    .endif
7925    FETCH(r1, 1)                        @ r1<- BBBB
7926    ldr     r2, [r2, #offMethod_clazz]  @ r2<- method->clazz
7927    EXPORT_PC()                         @ must export for invoke
7928    ldr     r2, [r2, #offClassObject_super]     @ r2<- method->clazz->super
7929    GET_VREG(r9, r10)                   @ r9<- "this"
7930    ldr     r2, [r2, #offClassObject_vtable]    @ r2<- ...clazz->super->vtable
7931    cmp     r9, #0                      @ null "this" ref?
7932    ldr     r0, [r2, r1, lsl #2]        @ r0<- super->vtable[BBBB]
7933    beq     common_errNullObject        @ "this" is null, throw exception
7934    bl      common_invokeMethodRange @ (r0=method, r9="this")
7935
7936
7937/* ------------------------------ */
7938    .balign 64
7939.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
7940/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */
7941/* File: armv5te/OP_IPUT_OBJECT.S */
7942    /*
7943     * 32-bit instance field put.
7944     *
7945     * for: iput-object, iput-object-volatile
7946     */
7947    /* op vA, vB, field@CCCC */
7948    mov     r0, rINST, lsr #12          @ r0<- B
7949    ldr     r3, [rSELF, #offThread_methodClassDex]    @ r3<- DvmDex
7950    FETCH(r1, 1)                        @ r1<- field ref CCCC
7951    ldr     r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
7952    GET_VREG(r9, r0)                    @ r9<- fp[B], the object pointer
7953    ldr     r0, [r2, r1, lsl #2]        @ r0<- resolved InstField ptr
7954    cmp     r0, #0                      @ is resolved entry null?
7955    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ no, already resolved
79568:  ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
7957    EXPORT_PC()                         @ resolve() could throw
7958    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
7959    bl      dvmResolveInstField         @ r0<- resolved InstField ptr
7960    cmp     r0, #0                      @ success?
7961    bne     .LOP_IPUT_OBJECT_VOLATILE_finish          @ yes, finish up
7962    b       common_exceptionThrown
7963
7964
7965/* ------------------------------ */
7966    .balign 64
7967.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
7968/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */
7969/* File: armv5te/OP_SGET.S */
7970    /*
7971     * General 32-bit SGET handler.
7972     *
7973     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
7974     */
7975    /* op vAA, field@BBBB */
7976    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
7977    FETCH(r1, 1)                        @ r1<- field ref BBBB
7978    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
7979    ldr     r0, [r10, r1, lsl #2]       @ r0<- resolved StaticField ptr
7980    cmp     r0, #0                      @ is resolved entry null?
7981    beq     .LOP_SGET_OBJECT_VOLATILE_resolve         @ yes, do resolve
7982.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0
7983    ldr     r1, [r0, #offStaticField_value] @ r1<- field value
7984    SMP_DMB                            @ acquiring load
7985    mov     r2, rINST, lsr #8           @ r2<- AA
7986    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
7987    SET_VREG(r1, r2)                    @ fp[AA]<- r1
7988    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
7989    GOTO_OPCODE(ip)                     @ jump to next instruction
7990
7991
7992/* ------------------------------ */
7993    .balign 64
7994.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
7995/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */
7996/* File: armv5te/OP_SPUT_OBJECT.S */
7997    /*
7998     * 32-bit SPUT handler for objects
7999     *
8000     * for: sput-object, sput-object-volatile
8001     */
8002    /* op vAA, field@BBBB */
8003    ldr     r2, [rSELF, #offThread_methodClassDex]    @ r2<- DvmDex
8004    FETCH(r1, 1)                        @ r1<- field ref BBBB
8005    ldr     r10, [r2, #offDvmDex_pResFields] @ r10<- dvmDex->pResFields
8006    ldr     r0, [r10, r1, lsl #2]        @ r0<- resolved StaticField ptr
8007    cmp     r0, #0                      @ is resolved entry null?
8008    beq     .LOP_SPUT_OBJECT_VOLATILE_resolve         @ yes, do resolve
8009.LOP_SPUT_OBJECT_VOLATILE_finish:   @ field ptr in r0
8010    mov     r2, rINST, lsr #8           @ r2<- AA
8011    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8012    GET_VREG(r1, r2)                    @ r1<- fp[AA]
8013    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
8014    ldr     r9, [r0, #offField_clazz]   @ r9<- field->clazz
8015    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8016    SMP_DMB_ST                        @ releasing store
8017    b       .LOP_SPUT_OBJECT_VOLATILE_end
8018
8019
8020/* ------------------------------ */
8021    .balign 64
8022.L_OP_UNUSED_FF: /* 0xff */
8023/* File: armv5te/OP_UNUSED_FF.S */
8024/* File: armv5te/unused.S */
8025    bl      common_abort
8026
8027
8028    .balign 64
8029    .size   dvmAsmInstructionStart, .-dvmAsmInstructionStart
8030    .global dvmAsmInstructionEnd
8031dvmAsmInstructionEnd:
8032
8033/*
8034 * ===========================================================================
8035 *  Sister implementations
8036 * ===========================================================================
8037 */
8038    .global dvmAsmSisterStart
8039    .type   dvmAsmSisterStart, %function
8040    .text
8041    .balign 4
8042dvmAsmSisterStart:
8043
8044/* continuation for OP_CONST_STRING */
8045
8046    /*
8047     * Continuation if the String has not yet been resolved.
8048     *  r1: BBBB (String ref)
8049     *  r9: target register
8050     */
8051.LOP_CONST_STRING_resolve:
8052    EXPORT_PC()
8053    ldr     r0, [rSELF, #offThread_method] @ r0<- self->method
8054    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
8055    bl      dvmResolveString            @ r0<- String reference
8056    cmp     r0, #0                      @ failed?
8057    beq     common_exceptionThrown      @ yup, handle the exception
8058    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8059    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8060    SET_VREG(r0, r9)                    @ vAA<- r0
8061    GOTO_OPCODE(ip)                     @ jump to next instruction
8062
8063/* continuation for OP_CONST_STRING_JUMBO */
8064
8065    /*
8066     * Continuation if the String has not yet been resolved.
8067     *  r1: BBBBBBBB (String ref)
8068     *  r9: target register
8069     */
8070.LOP_CONST_STRING_JUMBO_resolve:
8071    EXPORT_PC()
8072    ldr     r0, [rSELF, #offThread_method] @ r0<- self->method
8073    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
8074    bl      dvmResolveString            @ r0<- String reference
8075    cmp     r0, #0                      @ failed?
8076    beq     common_exceptionThrown      @ yup, handle the exception
8077    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
8078    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8079    SET_VREG(r0, r9)                    @ vAA<- r0
8080    GOTO_OPCODE(ip)                     @ jump to next instruction
8081
8082/* continuation for OP_CONST_CLASS */
8083
8084    /*
8085     * Continuation if the Class has not yet been resolved.
8086     *  r1: BBBB (Class ref)
8087     *  r9: target register
8088     */
8089.LOP_CONST_CLASS_resolve:
8090    EXPORT_PC()
8091    ldr     r0, [rSELF, #offThread_method] @ r0<- self->method
8092    mov     r2, #1                      @ r2<- true
8093    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
8094    bl      dvmResolveClass             @ r0<- Class reference
8095    cmp     r0, #0                      @ failed?
8096    beq     common_exceptionThrown      @ yup, handle the exception
8097    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8098    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8099    SET_VREG(r0, r9)                    @ vAA<- r0
8100    GOTO_OPCODE(ip)                     @ jump to next instruction
8101
8102/* continuation for OP_CHECK_CAST */
8103
8104    /*
8105     * Trivial test failed, need to perform full check.  This is common.
8106     *  r0 holds obj->clazz
8107     *  r1 holds desired class resolved from BBBB
8108     *  r9 holds object
8109     */
8110.LOP_CHECK_CAST_fullcheck:
8111    mov     r10, r1                     @ avoid ClassObject getting clobbered
8112    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
8113    cmp     r0, #0                      @ failed?
8114    bne     .LOP_CHECK_CAST_okay            @ no, success
8115
8116    @ A cast has failed.  We need to throw a ClassCastException.
8117    EXPORT_PC()                         @ about to throw
8118    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
8119    mov     r1, r10                     @ r1<- desired class
8120    bl      dvmThrowClassCastException
8121    b       common_exceptionThrown
8122
8123    /*
8124     * Resolution required.  This is the least-likely path.
8125     *
8126     *  r2 holds BBBB
8127     *  r9 holds object
8128     */
8129.LOP_CHECK_CAST_resolve:
8130    EXPORT_PC()                         @ resolve() could throw
8131    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
8132    mov     r1, r2                      @ r1<- BBBB
8133    mov     r2, #0                      @ r2<- false
8134    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8135    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
8136    cmp     r0, #0                      @ got null?
8137    beq     common_exceptionThrown      @ yes, handle exception
8138    mov     r1, r0                      @ r1<- class resolved from BBB
8139    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
8140    b       .LOP_CHECK_CAST_resolved        @ pick up where we left off
8141
8142/* continuation for OP_INSTANCE_OF */
8143
8144    /*
8145     * Trivial test failed, need to perform full check.  This is common.
8146     *  r0 holds obj->clazz
8147     *  r1 holds class resolved from BBBB
8148     *  r9 holds A
8149     */
8150.LOP_INSTANCE_OF_fullcheck:
8151    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
8152    @ fall through to OP_INSTANCE_OF_store
8153
8154    /*
8155     * r0 holds boolean result
8156     * r9 holds A
8157     */
8158.LOP_INSTANCE_OF_store:
8159    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8160    SET_VREG(r0, r9)                    @ vA<- r0
8161    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8162    GOTO_OPCODE(ip)                     @ jump to next instruction
8163
8164    /*
8165     * Trivial test succeeded, save and bail.
8166     *  r9 holds A
8167     */
8168.LOP_INSTANCE_OF_trivial:
8169    mov     r0, #1                      @ indicate success
8170    @ could b OP_INSTANCE_OF_store, but copying is faster and cheaper
8171    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8172    SET_VREG(r0, r9)                    @ vA<- r0
8173    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8174    GOTO_OPCODE(ip)                     @ jump to next instruction
8175
8176    /*
8177     * Resolution required.  This is the least-likely path.
8178     *
8179     *  r3 holds BBBB
8180     *  r9 holds A
8181     */
8182.LOP_INSTANCE_OF_resolve:
8183    EXPORT_PC()                         @ resolve() could throw
8184    ldr     r0, [rSELF, #offThread_method]    @ r0<- self->method
8185    mov     r1, r3                      @ r1<- BBBB
8186    mov     r2, #1                      @ r2<- true
8187    ldr     r0, [r0, #offMethod_clazz]  @ r0<- method->clazz
8188    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
8189    cmp     r0, #0                      @ got null?
8190    beq     common_exceptionThrown      @ yes, handle exception
8191    mov     r1, r0                      @ r1<- class resolved from BBB
8192    mov     r3, rINST, lsr #12          @ r3<- B
8193    GET_VREG(r0, r3)                    @ r0<- vB (object)
8194    ldr     r0, [r0, #offObject_clazz]  @ r0<- obj->clazz
8195    b       .LOP_INSTANCE_OF_resolved        @ pick up where we left off
8196
8197/* continuation for OP_NEW_INSTANCE */
8198
8199    .balign 32                          @ minimize cache lines
8200.LOP_NEW_INSTANCE_finish: @ r0=new object
8201    mov     r3, rINST, lsr #8           @ r3<- AA
8202    cmp     r0, #0                      @ failed?
8203#if defined(WITH_JIT)
8204    /*
8205     * The JIT needs the class to be fully resolved before it can
8206     * include this instruction in a trace.
8207     */
8208    ldrh    r1, [rSELF, #offThread_subMode]
8209    beq     common_exceptionThrown      @ yes, handle the exception
8210    ands    r1, #kSubModeJitTraceBuild  @ under construction?
8211    bne     .LOP_NEW_INSTANCE_jitCheck
8212#else
8213    beq     common_exceptionThrown      @ yes, handle the exception
8214#endif
8215.LOP_NEW_INSTANCE_end:
8216    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8217    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8218    SET_VREG(r0, r3)                    @ vAA<- r0
8219    GOTO_OPCODE(ip)                     @ jump to next instruction
8220
8221#if defined(WITH_JIT)
8222    /*
8223     * Check to see if we need to stop the trace building early.
8224     * r0: new object
8225     * r3: vAA
8226     */
8227.LOP_NEW_INSTANCE_jitCheck:
8228    ldr     r1, [r10]                   @ reload resolved class
8229    cmp     r1, #0                      @ okay?
8230    bne     .LOP_NEW_INSTANCE_end             @ yes, finish
8231    mov     r9, r0                      @ preserve new object
8232    mov     r10, r3                     @ preserve vAA
8233    mov     r0, rSELF
8234    mov     r1, rPC
8235    bl      dvmJitEndTraceSelect        @ (self, pc)
8236    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8237    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8238    SET_VREG(r9, r10)                   @ vAA<- new object
8239    GOTO_OPCODE(ip)                     @ jump to next instruction
8240#endif
8241
8242    /*
8243     * Class initialization required.
8244     *
8245     *  r0 holds class object
8246     */
8247.LOP_NEW_INSTANCE_needinit:
8248    mov     r9, r0                      @ save r0
8249    bl      dvmInitClass                @ initialize class
8250    cmp     r0, #0                      @ check boolean result
8251    mov     r0, r9                      @ restore r0
8252    bne     .LOP_NEW_INSTANCE_initialized     @ success, continue
8253    b       common_exceptionThrown      @ failed, deal with init exception
8254
8255    /*
8256     * Resolution required.  This is the least-likely path.
8257     *
8258     *  r1 holds BBBB
8259     */
8260.LOP_NEW_INSTANCE_resolve:
8261    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
8262    mov     r2, #0                      @ r2<- false
8263    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8264    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
8265    cmp     r0, #0                      @ got null?
8266    bne     .LOP_NEW_INSTANCE_resolved        @ no, continue
8267    b       common_exceptionThrown      @ yes, handle exception
8268
8269/* continuation for OP_NEW_ARRAY */
8270
8271
8272    /*
8273     * Resolve class.  (This is an uncommon case.)
8274     *
8275     *  r1 holds array length
8276     *  r2 holds class ref CCCC
8277     */
8278.LOP_NEW_ARRAY_resolve:
8279    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
8280    mov     r9, r1                      @ r9<- length (save)
8281    mov     r1, r2                      @ r1<- CCCC
8282    mov     r2, #0                      @ r2<- false
8283    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
8284    bl      dvmResolveClass             @ r0<- call(clazz, ref)
8285    cmp     r0, #0                      @ got null?
8286    mov     r1, r9                      @ r1<- length (restore)
8287    beq     common_exceptionThrown      @ yes, handle exception
8288    @ fall through to OP_NEW_ARRAY_finish
8289
8290    /*
8291     * Finish allocation.
8292     *
8293     *  r0 holds class
8294     *  r1 holds array length
8295     */
8296.LOP_NEW_ARRAY_finish:
8297    mov     r2, #ALLOC_DONT_TRACK       @ don't track in local refs table
8298    bl      dvmAllocArrayByClass        @ r0<- call(clazz, length, flags)
8299    cmp     r0, #0                      @ failed?
8300    mov     r2, rINST, lsr #8           @ r2<- A+
8301    beq     common_exceptionThrown      @ yes, handle the exception
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)                    @ vA<- r0
8306    GOTO_OPCODE(ip)                     @ jump to next instruction
8307
8308/* continuation for OP_FILLED_NEW_ARRAY */
8309
8310    /*
8311     * On entry:
8312     *  r0 holds array class
8313     *  r10 holds AA or BA
8314     */
8315.LOP_FILLED_NEW_ARRAY_continue:
8316    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
8317    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
8318    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
8319    .if     0
8320    mov     r1, r10                     @ r1<- AA (length)
8321    .else
8322    mov     r1, r10, lsr #4             @ r1<- B (length)
8323    .endif
8324    cmp     rINST, #'I'                 @ array of ints?
8325    cmpne   rINST, #'L'                 @ array of objects?
8326    cmpne   rINST, #'['                 @ array of arrays?
8327    mov     r9, r1                      @ save length in r9
8328    bne     .LOP_FILLED_NEW_ARRAY_notimpl         @ no, not handled yet
8329    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
8330    cmp     r0, #0                      @ null return?
8331    beq     common_exceptionThrown      @ alloc failed, handle exception
8332
8333    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
8334    str     r0, [rSELF, #offThread_retval]      @ retval.l <- new array
8335    str     rINST, [rSELF, #offThread_retval+4] @ retval.h <- type
8336    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
8337    subs    r9, r9, #1                  @ length--, check for neg
8338    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
8339    bmi     2f                          @ was zero, bail
8340
8341    @ copy values from registers into the array
8342    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
8343    .if     0
8344    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
83451:  ldr     r3, [r2], #4                @ r3<- *r2++
8346    subs    r9, r9, #1                  @ count--
8347    str     r3, [r0], #4                @ *contents++ = vX
8348    bpl     1b
8349    @ continue at 2
8350    .else
8351    cmp     r9, #4                      @ length was initially 5?
8352    and     r2, r10, #15                @ r2<- A
8353    bne     1f                          @ <= 4 args, branch
8354    GET_VREG(r3, r2)                    @ r3<- vA
8355    sub     r9, r9, #1                  @ count--
8356    str     r3, [r0, #16]               @ contents[4] = vA
83571:  and     r2, r1, #15                 @ r2<- F/E/D/C
8358    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
8359    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
8360    subs    r9, r9, #1                  @ count--
8361    str     r3, [r0], #4                @ *contents++ = vX
8362    bpl     1b
8363    @ continue at 2
8364    .endif
8365
83662:
8367    ldr     r0, [rSELF, #offThread_retval]     @ r0<- object
8368    ldr     r1, [rSELF, #offThread_retval+4]   @ r1<- type
8369    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
8370    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
8371    cmp     r1, #'I'                         @ Is int array?
8372    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
8373    GOTO_OPCODE(ip)                          @ execute it
8374
8375    /*
8376     * Throw an exception indicating that we have not implemented this
8377     * mode of filled-new-array.
8378     */
8379.LOP_FILLED_NEW_ARRAY_notimpl:
8380    ldr     r0, .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY
83813:  add     r0, pc
8382    bl      dvmThrowInternalError
8383    b       common_exceptionThrown
8384
8385    /*
8386     * Ideally we'd only define this once, but depending on layout we can
8387     * exceed the range of the load above.
8388     */
8389
8390.L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY:
8391    .word   PCREL_REF(.LstrFilledNewArrayNotImpl,3b)
8392
8393/* continuation for OP_FILLED_NEW_ARRAY_RANGE */
8394
8395    /*
8396     * On entry:
8397     *  r0 holds array class
8398     *  r10 holds AA or BA
8399     */
8400.LOP_FILLED_NEW_ARRAY_RANGE_continue:
8401    ldr     r3, [r0, #offClassObject_descriptor] @ r3<- arrayClass->descriptor
8402    mov     r2, #ALLOC_DONT_TRACK       @ r2<- alloc flags
8403    ldrb    rINST, [r3, #1]             @ rINST<- descriptor[1]
8404    .if     1
8405    mov     r1, r10                     @ r1<- AA (length)
8406    .else
8407    mov     r1, r10, lsr #4             @ r1<- B (length)
8408    .endif
8409    cmp     rINST, #'I'                 @ array of ints?
8410    cmpne   rINST, #'L'                 @ array of objects?
8411    cmpne   rINST, #'['                 @ array of arrays?
8412    mov     r9, r1                      @ save length in r9
8413    bne     .LOP_FILLED_NEW_ARRAY_RANGE_notimpl         @ no, not handled yet
8414    bl      dvmAllocArrayByClass        @ r0<- call(arClass, length, flags)
8415    cmp     r0, #0                      @ null return?
8416    beq     common_exceptionThrown      @ alloc failed, handle exception
8417
8418    FETCH(r1, 2)                        @ r1<- FEDC or CCCC
8419    str     r0, [rSELF, #offThread_retval]      @ retval.l <- new array
8420    str     rINST, [rSELF, #offThread_retval+4] @ retval.h <- type
8421    add     r0, r0, #offArrayObject_contents @ r0<- newArray->contents
8422    subs    r9, r9, #1                  @ length--, check for neg
8423    FETCH_ADVANCE_INST(3)               @ advance to next instr, load rINST
8424    bmi     2f                          @ was zero, bail
8425
8426    @ copy values from registers into the array
8427    @ r0=array, r1=CCCC/FEDC, r9=length (from AA or B), r10=AA/BA
8428    .if     1
8429    add     r2, rFP, r1, lsl #2         @ r2<- &fp[CCCC]
84301:  ldr     r3, [r2], #4                @ r3<- *r2++
8431    subs    r9, r9, #1                  @ count--
8432    str     r3, [r0], #4                @ *contents++ = vX
8433    bpl     1b
8434    @ continue at 2
8435    .else
8436    cmp     r9, #4                      @ length was initially 5?
8437    and     r2, r10, #15                @ r2<- A
8438    bne     1f                          @ <= 4 args, branch
8439    GET_VREG(r3, r2)                    @ r3<- vA
8440    sub     r9, r9, #1                  @ count--
8441    str     r3, [r0, #16]               @ contents[4] = vA
84421:  and     r2, r1, #15                 @ r2<- F/E/D/C
8443    GET_VREG(r3, r2)                    @ r3<- vF/vE/vD/vC
8444    mov     r1, r1, lsr #4              @ r1<- next reg in low 4
8445    subs    r9, r9, #1                  @ count--
8446    str     r3, [r0], #4                @ *contents++ = vX
8447    bpl     1b
8448    @ continue at 2
8449    .endif
8450
84512:
8452    ldr     r0, [rSELF, #offThread_retval]     @ r0<- object
8453    ldr     r1, [rSELF, #offThread_retval+4]   @ r1<- type
8454    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
8455    GET_INST_OPCODE(ip)                      @ ip<- opcode from rINST
8456    cmp     r1, #'I'                         @ Is int array?
8457    strneb  r2, [r2, r0, lsr #GC_CARD_SHIFT] @ Mark card based on object head
8458    GOTO_OPCODE(ip)                          @ execute it
8459
8460    /*
8461     * Throw an exception indicating that we have not implemented this
8462     * mode of filled-new-array.
8463     */
8464.LOP_FILLED_NEW_ARRAY_RANGE_notimpl:
8465    ldr     r0, .L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY_RANGE
84663:  add     r0, pc
8467    bl      dvmThrowInternalError
8468    b       common_exceptionThrown
8469
8470    /*
8471     * Ideally we'd only define this once, but depending on layout we can
8472     * exceed the range of the load above.
8473     */
8474
8475.L_strFilledNewArrayNotImpl_OP_FILLED_NEW_ARRAY_RANGE:
8476    .word   PCREL_REF(.LstrFilledNewArrayNotImpl,3b)
8477
8478/* continuation for OP_CMPL_FLOAT */
8479
8480    @ Test for NaN with a second comparison.  EABI forbids testing bit
8481    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
8482    @ make the library call.
8483.LOP_CMPL_FLOAT_gt_or_nan:
8484    mov     r1, r9                      @ reverse order
8485    mov     r0, r10
8486    bl      __aeabi_cfcmple             @ r0<- Z set if eq, C clear if <
8487    @bleq    common_abort
8488    movcc   r1, #1                      @ (greater than) r1<- 1
8489    bcc     .LOP_CMPL_FLOAT_finish
8490    mvn     r1, #0                            @ r1<- 1 or -1 for NaN
8491    b       .LOP_CMPL_FLOAT_finish
8492
8493
8494#if 0       /* "clasic" form */
8495    FETCH(r0, 1)                        @ r0<- CCBB
8496    and     r2, r0, #255                @ r2<- BB
8497    mov     r3, r0, lsr #8              @ r3<- CC
8498    GET_VREG(r9, r2)                    @ r9<- vBB
8499    GET_VREG(r10, r3)                   @ r10<- vCC
8500    mov     r0, r9                      @ r0<- vBB
8501    mov     r1, r10                     @ r1<- vCC
8502    bl      __aeabi_fcmpeq              @ r0<- (vBB == vCC)
8503    cmp     r0, #0                      @ equal?
8504    movne   r1, #0                      @ yes, result is 0
8505    bne     OP_CMPL_FLOAT_finish
8506    mov     r0, r9                      @ r0<- vBB
8507    mov     r1, r10                     @ r1<- vCC
8508    bl      __aeabi_fcmplt              @ r0<- (vBB < vCC)
8509    cmp     r0, #0                      @ less than?
8510    b       OP_CMPL_FLOAT_continue
8511@%break
8512
8513OP_CMPL_FLOAT_continue:
8514    mvnne   r1, #0                      @ yes, result is -1
8515    bne     OP_CMPL_FLOAT_finish
8516    mov     r0, r9                      @ r0<- vBB
8517    mov     r1, r10                     @ r1<- vCC
8518    bl      __aeabi_fcmpgt              @ r0<- (vBB > vCC)
8519    cmp     r0, #0                      @ greater than?
8520    beq     OP_CMPL_FLOAT_nan               @ no, must be NaN
8521    mov     r1, #1                      @ yes, result is 1
8522    @ fall through to _finish
8523
8524OP_CMPL_FLOAT_finish:
8525    mov     r3, rINST, lsr #8           @ r3<- AA
8526    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8527    SET_VREG(r1, r3)                    @ vAA<- r1
8528    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8529    GOTO_OPCODE(ip)                     @ jump to next instruction
8530
8531    /*
8532     * This is expected to be uncommon, so we double-branch (once to here,
8533     * again back to _finish).
8534     */
8535OP_CMPL_FLOAT_nan:
8536    mvn     r1, #0                            @ r1<- 1 or -1 for NaN
8537    b       OP_CMPL_FLOAT_finish
8538
8539#endif
8540
8541/* continuation for OP_CMPG_FLOAT */
8542
8543    @ Test for NaN with a second comparison.  EABI forbids testing bit
8544    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
8545    @ make the library call.
8546.LOP_CMPG_FLOAT_gt_or_nan:
8547    mov     r1, r9                      @ reverse order
8548    mov     r0, r10
8549    bl      __aeabi_cfcmple             @ r0<- Z set if eq, C clear if <
8550    @bleq    common_abort
8551    movcc   r1, #1                      @ (greater than) r1<- 1
8552    bcc     .LOP_CMPG_FLOAT_finish
8553    mov     r1, #1                            @ r1<- 1 or -1 for NaN
8554    b       .LOP_CMPG_FLOAT_finish
8555
8556
8557#if 0       /* "clasic" form */
8558    FETCH(r0, 1)                        @ r0<- CCBB
8559    and     r2, r0, #255                @ r2<- BB
8560    mov     r3, r0, lsr #8              @ r3<- CC
8561    GET_VREG(r9, r2)                    @ r9<- vBB
8562    GET_VREG(r10, r3)                   @ r10<- vCC
8563    mov     r0, r9                      @ r0<- vBB
8564    mov     r1, r10                     @ r1<- vCC
8565    bl      __aeabi_fcmpeq              @ r0<- (vBB == vCC)
8566    cmp     r0, #0                      @ equal?
8567    movne   r1, #0                      @ yes, result is 0
8568    bne     OP_CMPG_FLOAT_finish
8569    mov     r0, r9                      @ r0<- vBB
8570    mov     r1, r10                     @ r1<- vCC
8571    bl      __aeabi_fcmplt              @ r0<- (vBB < vCC)
8572    cmp     r0, #0                      @ less than?
8573    b       OP_CMPG_FLOAT_continue
8574@%break
8575
8576OP_CMPG_FLOAT_continue:
8577    mvnne   r1, #0                      @ yes, result is -1
8578    bne     OP_CMPG_FLOAT_finish
8579    mov     r0, r9                      @ r0<- vBB
8580    mov     r1, r10                     @ r1<- vCC
8581    bl      __aeabi_fcmpgt              @ r0<- (vBB > vCC)
8582    cmp     r0, #0                      @ greater than?
8583    beq     OP_CMPG_FLOAT_nan               @ no, must be NaN
8584    mov     r1, #1                      @ yes, result is 1
8585    @ fall through to _finish
8586
8587OP_CMPG_FLOAT_finish:
8588    mov     r3, rINST, lsr #8           @ r3<- AA
8589    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8590    SET_VREG(r1, r3)                    @ vAA<- r1
8591    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8592    GOTO_OPCODE(ip)                     @ jump to next instruction
8593
8594    /*
8595     * This is expected to be uncommon, so we double-branch (once to here,
8596     * again back to _finish).
8597     */
8598OP_CMPG_FLOAT_nan:
8599    mov     r1, #1                            @ r1<- 1 or -1 for NaN
8600    b       OP_CMPG_FLOAT_finish
8601
8602#endif
8603
8604/* continuation for OP_CMPL_DOUBLE */
8605
8606    @ Test for NaN with a second comparison.  EABI forbids testing bit
8607    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
8608    @ make the library call.
8609.LOP_CMPL_DOUBLE_gt_or_nan:
8610    ldmia   r10, {r0-r1}                @ reverse order
8611    ldmia   r9, {r2-r3}
8612    bl      __aeabi_cdcmple             @ r0<- Z set if eq, C clear if <
8613    @bleq    common_abort
8614    movcc   r1, #1                      @ (greater than) r1<- 1
8615    bcc     .LOP_CMPL_DOUBLE_finish
8616    mvn     r1, #0                            @ r1<- 1 or -1 for NaN
8617    b       .LOP_CMPL_DOUBLE_finish
8618
8619/* continuation for OP_CMPG_DOUBLE */
8620
8621    @ Test for NaN with a second comparison.  EABI forbids testing bit
8622    @ patterns, and we can't represent 0x7fc00000 in immediate form, so
8623    @ make the library call.
8624.LOP_CMPG_DOUBLE_gt_or_nan:
8625    ldmia   r10, {r0-r1}                @ reverse order
8626    ldmia   r9, {r2-r3}
8627    bl      __aeabi_cdcmple             @ r0<- Z set if eq, C clear if <
8628    @bleq    common_abort
8629    movcc   r1, #1                      @ (greater than) r1<- 1
8630    bcc     .LOP_CMPG_DOUBLE_finish
8631    mov     r1, #1                            @ r1<- 1 or -1 for NaN
8632    b       .LOP_CMPG_DOUBLE_finish
8633
8634/* continuation for OP_CMP_LONG */
8635
8636.LOP_CMP_LONG_less:
8637    mvn     r1, #0                      @ r1<- -1
8638    @ Want to cond code the next mov so we can avoid branch, but don't see it;
8639    @ instead, we just replicate the tail end.
8640    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8641    SET_VREG(r1, r9)                    @ vAA<- r1
8642    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8643    GOTO_OPCODE(ip)                     @ jump to next instruction
8644
8645.LOP_CMP_LONG_greater:
8646    mov     r1, #1                      @ r1<- 1
8647    @ fall through to _finish
8648
8649.LOP_CMP_LONG_finish:
8650    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8651    SET_VREG(r1, r9)                    @ vAA<- r1
8652    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8653    GOTO_OPCODE(ip)                     @ jump to next instruction
8654
8655/* continuation for OP_AGET_WIDE */
8656
8657.LOP_AGET_WIDE_finish:
8658    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8659    ldrd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
8660    add     r9, rFP, r9, lsl #2         @ r9<- &fp[AA]
8661    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8662    stmia   r9, {r2-r3}                 @ vAA/vAA+1<- r2/r3
8663    GOTO_OPCODE(ip)                     @ jump to next instruction
8664
8665/* continuation for OP_APUT_WIDE */
8666
8667.LOP_APUT_WIDE_finish:
8668    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8669    ldmia   r9, {r2-r3}                 @ r2/r3<- vAA/vAA+1
8670    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8671    strd    r2, [r0, #offArrayObject_contents]  @ r2/r3<- vBB[vCC]
8672    GOTO_OPCODE(ip)                     @ jump to next instruction
8673
8674/* continuation for OP_APUT_OBJECT */
8675    /*
8676     * On entry:
8677     *  rINST = vBB (arrayObj)
8678     *  r9 = vAA (obj)
8679     *  r10 = offset into array (vBB + vCC * width)
8680     */
8681.LOP_APUT_OBJECT_finish:
8682    cmp     r9, #0                      @ storing null reference?
8683    beq     .LOP_APUT_OBJECT_skip_check      @ yes, skip type checks
8684    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
8685    ldr     r1, [rINST, #offObject_clazz]  @ r1<- arrayObj->clazz
8686    bl      dvmCanPutArrayElement       @ test object type vs. array type
8687    cmp     r0, #0                      @ okay?
8688    beq     .LOP_APUT_OBJECT_throw           @ no
8689    mov     r1, rINST                   @ r1<- arrayObj
8690    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8691    ldr     r2, [rSELF, #offThread_cardTable]     @ get biased CT base
8692    add     r10, #offArrayObject_contents   @ r0<- pointer to slot
8693    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8694    str     r9, [r10]                   @ vBB[vCC]<- vAA
8695    strb    r2, [r2, r1, lsr #GC_CARD_SHIFT] @ mark card using object head
8696    GOTO_OPCODE(ip)                     @ jump to next instruction
8697.LOP_APUT_OBJECT_skip_check:
8698    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8699    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8700    str     r9, [r10, #offArrayObject_contents] @ vBB[vCC]<- vAA
8701    GOTO_OPCODE(ip)                     @ jump to next instruction
8702.LOP_APUT_OBJECT_throw:
8703    @ The types don't match.  We need to throw an ArrayStoreException.
8704    ldr     r0, [r9, #offObject_clazz]
8705    ldr     r1, [rINST, #offObject_clazz]
8706    EXPORT_PC()
8707    bl      dvmThrowArrayStoreExceptionIncompatibleElement
8708    b       common_exceptionThrown
8709
8710/* continuation for OP_IGET */
8711
8712    /*
8713     * Currently:
8714     *  r0 holds resolved field
8715     *  r9 holds object
8716     */
8717.LOP_IGET_finish:
8718    @bl      common_squeak0
8719    cmp     r9, #0                      @ check object for null
8720    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8721    beq     common_errNullObject        @ object was null
8722    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8723    @ no-op                             @ acquiring load
8724    mov     r2, rINST, lsr #8           @ r2<- A+
8725    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8726    and     r2, r2, #15                 @ r2<- A
8727    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8728    SET_VREG(r0, r2)                    @ fp[A]<- r0
8729    GOTO_OPCODE(ip)                     @ jump to next instruction
8730
8731/* continuation for OP_IGET_WIDE */
8732
8733    /*
8734     * Currently:
8735     *  r0 holds resolved field
8736     *  r9 holds object
8737     */
8738.LOP_IGET_WIDE_finish:
8739    cmp     r9, #0                      @ check object for null
8740    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8741    beq     common_errNullObject        @ object was null
8742    .if     0
8743    add     r0, r9, r3                  @ r0<- address of field
8744    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
8745    .else
8746    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
8747    .endif
8748    mov     r2, rINST, lsr #8           @ r2<- A+
8749    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8750    and     r2, r2, #15                 @ r2<- A
8751    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
8752    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8753    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
8754    GOTO_OPCODE(ip)                     @ jump to next instruction
8755
8756/* continuation for OP_IGET_OBJECT */
8757
8758    /*
8759     * Currently:
8760     *  r0 holds resolved field
8761     *  r9 holds object
8762     */
8763.LOP_IGET_OBJECT_finish:
8764    @bl      common_squeak0
8765    cmp     r9, #0                      @ check object for null
8766    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8767    beq     common_errNullObject        @ object was null
8768    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8769    @ no-op                             @ acquiring load
8770    mov     r2, rINST, lsr #8           @ r2<- A+
8771    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8772    and     r2, r2, #15                 @ r2<- A
8773    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8774    SET_VREG(r0, r2)                    @ fp[A]<- r0
8775    GOTO_OPCODE(ip)                     @ jump to next instruction
8776
8777/* continuation for OP_IGET_BOOLEAN */
8778
8779    /*
8780     * Currently:
8781     *  r0 holds resolved field
8782     *  r9 holds object
8783     */
8784.LOP_IGET_BOOLEAN_finish:
8785    @bl      common_squeak1
8786    cmp     r9, #0                      @ check object for null
8787    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8788    beq     common_errNullObject        @ object was null
8789    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8790    @ no-op                             @ acquiring load
8791    mov     r2, rINST, lsr #8           @ r2<- A+
8792    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8793    and     r2, r2, #15                 @ r2<- A
8794    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8795    SET_VREG(r0, r2)                    @ fp[A]<- r0
8796    GOTO_OPCODE(ip)                     @ jump to next instruction
8797
8798/* continuation for OP_IGET_BYTE */
8799
8800    /*
8801     * Currently:
8802     *  r0 holds resolved field
8803     *  r9 holds object
8804     */
8805.LOP_IGET_BYTE_finish:
8806    @bl      common_squeak2
8807    cmp     r9, #0                      @ check object for null
8808    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8809    beq     common_errNullObject        @ object was null
8810    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8811    @ no-op                             @ acquiring load
8812    mov     r2, rINST, lsr #8           @ r2<- A+
8813    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8814    and     r2, r2, #15                 @ r2<- A
8815    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8816    SET_VREG(r0, r2)                    @ fp[A]<- r0
8817    GOTO_OPCODE(ip)                     @ jump to next instruction
8818
8819/* continuation for OP_IGET_CHAR */
8820
8821    /*
8822     * Currently:
8823     *  r0 holds resolved field
8824     *  r9 holds object
8825     */
8826.LOP_IGET_CHAR_finish:
8827    @bl      common_squeak3
8828    cmp     r9, #0                      @ check object for null
8829    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8830    beq     common_errNullObject        @ object was null
8831    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8832    @ no-op                             @ acquiring load
8833    mov     r2, rINST, lsr #8           @ r2<- A+
8834    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8835    and     r2, r2, #15                 @ r2<- A
8836    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8837    SET_VREG(r0, r2)                    @ fp[A]<- r0
8838    GOTO_OPCODE(ip)                     @ jump to next instruction
8839
8840/* continuation for OP_IGET_SHORT */
8841
8842    /*
8843     * Currently:
8844     *  r0 holds resolved field
8845     *  r9 holds object
8846     */
8847.LOP_IGET_SHORT_finish:
8848    @bl      common_squeak4
8849    cmp     r9, #0                      @ check object for null
8850    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8851    beq     common_errNullObject        @ object was null
8852    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
8853    @ no-op                             @ acquiring load
8854    mov     r2, rINST, lsr #8           @ r2<- A+
8855    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8856    and     r2, r2, #15                 @ r2<- A
8857    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8858    SET_VREG(r0, r2)                    @ fp[A]<- r0
8859    GOTO_OPCODE(ip)                     @ jump to next instruction
8860
8861/* continuation for OP_IPUT */
8862
8863    /*
8864     * Currently:
8865     *  r0 holds resolved field
8866     *  r9 holds object
8867     */
8868.LOP_IPUT_finish:
8869    @bl      common_squeak0
8870    mov     r1, rINST, lsr #8           @ r1<- A+
8871    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8872    and     r1, r1, #15                 @ r1<- A
8873    cmp     r9, #0                      @ check object for null
8874    GET_VREG(r0, r1)                    @ r0<- fp[A]
8875    beq     common_errNullObject        @ object was null
8876    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8877    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8878    @ no-op                         @ releasing store
8879    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
8880    @ no-op
8881    GOTO_OPCODE(ip)                     @ jump to next instruction
8882
8883/* continuation for OP_IPUT_WIDE */
8884
8885    /*
8886     * Currently:
8887     *  r0 holds resolved field
8888     *  r9 holds object
8889     */
8890.LOP_IPUT_WIDE_finish:
8891    mov     r2, rINST, lsr #8           @ r2<- A+
8892    cmp     r9, #0                      @ check object for null
8893    and     r2, r2, #15                 @ r2<- A
8894    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8895    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
8896    beq     common_errNullObject        @ object was null
8897    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8898    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
8899    GET_INST_OPCODE(r10)                @ extract opcode from rINST
8900    .if     0
8901    add     r2, r9, r3                  @ r2<- target address
8902    bl      dvmQuasiAtomicSwap64Sync    @ stores r0/r1 into addr r2
8903    .else
8904    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
8905    .endif
8906    GOTO_OPCODE(r10)                    @ jump to next instruction
8907
8908/* continuation for OP_IPUT_OBJECT */
8909
8910    /*
8911     * Currently:
8912     *  r0 holds resolved field
8913     *  r9 holds object
8914     */
8915.LOP_IPUT_OBJECT_finish:
8916    @bl      common_squeak0
8917    mov     r1, rINST, lsr #8           @ r1<- A+
8918    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8919    and     r1, r1, #15                 @ r1<- A
8920    cmp     r9, #0                      @ check object for null
8921    GET_VREG(r0, r1)                    @ r0<- fp[A]
8922    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
8923    beq     common_errNullObject        @ object was null
8924    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8925    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8926    @ no-op                         @ releasing store
8927    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
8928    @ no-op
8929    cmp     r0, #0                      @ stored a null reference?
8930    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
8931    GOTO_OPCODE(ip)                     @ jump to next instruction
8932
8933/* continuation for OP_IPUT_BOOLEAN */
8934
8935    /*
8936     * Currently:
8937     *  r0 holds resolved field
8938     *  r9 holds object
8939     */
8940.LOP_IPUT_BOOLEAN_finish:
8941    @bl      common_squeak1
8942    mov     r1, rINST, lsr #8           @ r1<- A+
8943    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8944    and     r1, r1, #15                 @ r1<- A
8945    cmp     r9, #0                      @ check object for null
8946    GET_VREG(r0, r1)                    @ r0<- fp[A]
8947    beq     common_errNullObject        @ object was null
8948    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8949    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8950    @ no-op                         @ releasing store
8951    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
8952    @ no-op
8953    GOTO_OPCODE(ip)                     @ jump to next instruction
8954
8955/* continuation for OP_IPUT_BYTE */
8956
8957    /*
8958     * Currently:
8959     *  r0 holds resolved field
8960     *  r9 holds object
8961     */
8962.LOP_IPUT_BYTE_finish:
8963    @bl      common_squeak2
8964    mov     r1, rINST, lsr #8           @ r1<- A+
8965    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8966    and     r1, r1, #15                 @ r1<- A
8967    cmp     r9, #0                      @ check object for null
8968    GET_VREG(r0, r1)                    @ r0<- fp[A]
8969    beq     common_errNullObject        @ object was null
8970    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8971    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8972    @ no-op                         @ releasing store
8973    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
8974    @ no-op
8975    GOTO_OPCODE(ip)                     @ jump to next instruction
8976
8977/* continuation for OP_IPUT_CHAR */
8978
8979    /*
8980     * Currently:
8981     *  r0 holds resolved field
8982     *  r9 holds object
8983     */
8984.LOP_IPUT_CHAR_finish:
8985    @bl      common_squeak3
8986    mov     r1, rINST, lsr #8           @ r1<- A+
8987    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
8988    and     r1, r1, #15                 @ r1<- A
8989    cmp     r9, #0                      @ check object for null
8990    GET_VREG(r0, r1)                    @ r0<- fp[A]
8991    beq     common_errNullObject        @ object was null
8992    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
8993    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
8994    @ no-op                         @ releasing store
8995    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
8996    @ no-op
8997    GOTO_OPCODE(ip)                     @ jump to next instruction
8998
8999/* continuation for OP_IPUT_SHORT */
9000
9001    /*
9002     * Currently:
9003     *  r0 holds resolved field
9004     *  r9 holds object
9005     */
9006.LOP_IPUT_SHORT_finish:
9007    @bl      common_squeak4
9008    mov     r1, rINST, lsr #8           @ r1<- A+
9009    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9010    and     r1, r1, #15                 @ r1<- A
9011    cmp     r9, #0                      @ check object for null
9012    GET_VREG(r0, r1)                    @ r0<- fp[A]
9013    beq     common_errNullObject        @ object was null
9014    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9015    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9016    @ no-op                         @ releasing store
9017    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
9018    @ no-op
9019    GOTO_OPCODE(ip)                     @ jump to next instruction
9020
9021/* continuation for OP_SGET */
9022
9023    /*
9024     * Continuation if the field has not yet been resolved.
9025     *  r1:  BBBB field ref
9026     *  r10: dvmDex->pResFields
9027     */
9028.LOP_SGET_resolve:
9029    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9030#if defined(WITH_JIT)
9031    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9032#endif
9033    EXPORT_PC()                         @ resolve() could throw, so export now
9034    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9035    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9036    cmp     r0, #0                      @ success?
9037    beq     common_exceptionThrown      @ no, handle exception
9038#if defined(WITH_JIT)
9039    /*
9040     * If the JIT is actively building a trace we need to make sure
9041     * that the field is fully resolved before including this instruction.
9042     */
9043    bl      common_verifyField
9044#endif
9045    b       .LOP_SGET_finish
9046
9047/* continuation for OP_SGET_WIDE */
9048
9049    /*
9050     * Continuation if the field has not yet been resolved.
9051     *  r1:  BBBB field ref
9052     *  r10: dvmDex->pResFields
9053     *
9054     * Returns StaticField pointer in r0.
9055     */
9056.LOP_SGET_WIDE_resolve:
9057    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9058#if defined(WITH_JIT)
9059    add     r10, r10, r1, lsl #2        @ r1<- &dvmDex->pResFields[field]
9060#endif
9061    EXPORT_PC()                         @ resolve() could throw, so export now
9062    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9063    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9064    cmp     r0, #0                      @ success?
9065    beq     common_exceptionThrown      @ no, handle exception
9066#if defined(WITH_JIT)
9067    /*
9068     * If the JIT is actively building a trace we need to make sure
9069     * that the field is fully resolved before including this instruction.
9070     */
9071    bl      common_verifyField
9072#endif
9073    b       .LOP_SGET_WIDE_finish          @ resume
9074
9075/* continuation for OP_SGET_OBJECT */
9076
9077    /*
9078     * Continuation if the field has not yet been resolved.
9079     *  r1:  BBBB field ref
9080     *  r10: dvmDex->pResFields
9081     */
9082.LOP_SGET_OBJECT_resolve:
9083    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9084#if defined(WITH_JIT)
9085    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9086#endif
9087    EXPORT_PC()                         @ resolve() could throw, so export now
9088    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9089    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9090    cmp     r0, #0                      @ success?
9091    beq     common_exceptionThrown      @ no, handle exception
9092#if defined(WITH_JIT)
9093    /*
9094     * If the JIT is actively building a trace we need to make sure
9095     * that the field is fully resolved before including this instruction.
9096     */
9097    bl      common_verifyField
9098#endif
9099    b       .LOP_SGET_OBJECT_finish
9100
9101/* continuation for OP_SGET_BOOLEAN */
9102
9103    /*
9104     * Continuation if the field has not yet been resolved.
9105     *  r1:  BBBB field ref
9106     *  r10: dvmDex->pResFields
9107     */
9108.LOP_SGET_BOOLEAN_resolve:
9109    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9110#if defined(WITH_JIT)
9111    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9112#endif
9113    EXPORT_PC()                         @ resolve() could throw, so export now
9114    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9115    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9116    cmp     r0, #0                      @ success?
9117    beq     common_exceptionThrown      @ no, handle exception
9118#if defined(WITH_JIT)
9119    /*
9120     * If the JIT is actively building a trace we need to make sure
9121     * that the field is fully resolved before including this instruction.
9122     */
9123    bl      common_verifyField
9124#endif
9125    b       .LOP_SGET_BOOLEAN_finish
9126
9127/* continuation for OP_SGET_BYTE */
9128
9129    /*
9130     * Continuation if the field has not yet been resolved.
9131     *  r1:  BBBB field ref
9132     *  r10: dvmDex->pResFields
9133     */
9134.LOP_SGET_BYTE_resolve:
9135    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9136#if defined(WITH_JIT)
9137    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9138#endif
9139    EXPORT_PC()                         @ resolve() could throw, so export now
9140    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9141    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9142    cmp     r0, #0                      @ success?
9143    beq     common_exceptionThrown      @ no, handle exception
9144#if defined(WITH_JIT)
9145    /*
9146     * If the JIT is actively building a trace we need to make sure
9147     * that the field is fully resolved before including this instruction.
9148     */
9149    bl      common_verifyField
9150#endif
9151    b       .LOP_SGET_BYTE_finish
9152
9153/* continuation for OP_SGET_CHAR */
9154
9155    /*
9156     * Continuation if the field has not yet been resolved.
9157     *  r1:  BBBB field ref
9158     *  r10: dvmDex->pResFields
9159     */
9160.LOP_SGET_CHAR_resolve:
9161    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9162#if defined(WITH_JIT)
9163    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9164#endif
9165    EXPORT_PC()                         @ resolve() could throw, so export now
9166    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9167    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9168    cmp     r0, #0                      @ success?
9169    beq     common_exceptionThrown      @ no, handle exception
9170#if defined(WITH_JIT)
9171    /*
9172     * If the JIT is actively building a trace we need to make sure
9173     * that the field is fully resolved before including this instruction.
9174     */
9175    bl      common_verifyField
9176#endif
9177    b       .LOP_SGET_CHAR_finish
9178
9179/* continuation for OP_SGET_SHORT */
9180
9181    /*
9182     * Continuation if the field has not yet been resolved.
9183     *  r1:  BBBB field ref
9184     *  r10: dvmDex->pResFields
9185     */
9186.LOP_SGET_SHORT_resolve:
9187    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9188#if defined(WITH_JIT)
9189    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9190#endif
9191    EXPORT_PC()                         @ resolve() could throw, so export now
9192    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9193    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9194    cmp     r0, #0                      @ success?
9195    beq     common_exceptionThrown      @ no, handle exception
9196#if defined(WITH_JIT)
9197    /*
9198     * If the JIT is actively building a trace we need to make sure
9199     * that the field is fully resolved before including this instruction.
9200     */
9201    bl      common_verifyField
9202#endif
9203    b       .LOP_SGET_SHORT_finish
9204
9205/* continuation for OP_SPUT */
9206
9207    /*
9208     * Continuation if the field has not yet been resolved.
9209     *  r1:  BBBB field ref
9210     *  r10: dvmDex->pResFields
9211     */
9212.LOP_SPUT_resolve:
9213    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9214#if defined(WITH_JIT)
9215    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9216#endif
9217    EXPORT_PC()                         @ resolve() could throw, so export now
9218    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9219    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9220    cmp     r0, #0                      @ success?
9221    beq     common_exceptionThrown      @ no, handle exception
9222#if defined(WITH_JIT)
9223    /*
9224     * If the JIT is actively building a trace we need to make sure
9225     * that the field is fully resolved before including this instruction.
9226     */
9227    bl      common_verifyField
9228#endif
9229    b       .LOP_SPUT_finish          @ resume
9230
9231/* continuation for OP_SPUT_WIDE */
9232
9233    /*
9234     * Continuation if the field has not yet been resolved.
9235     *  r1:  BBBB field ref
9236     *  r9:  &fp[AA]
9237     *  r10: dvmDex->pResFields
9238     *
9239     * Returns StaticField pointer in r2.
9240     */
9241.LOP_SPUT_WIDE_resolve:
9242    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9243#if defined(WITH_JIT)
9244    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9245#endif
9246    EXPORT_PC()                         @ resolve() could throw, so export now
9247    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9248    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9249    cmp     r0, #0                      @ success?
9250    mov     r2, r0                      @ copy to r2
9251    beq     common_exceptionThrown      @ no, handle exception
9252#if defined(WITH_JIT)
9253    /*
9254     * If the JIT is actively building a trace we need to make sure
9255     * that the field is fully resolved before including this instruction.
9256     */
9257    bl      common_verifyField
9258#endif
9259    b       .LOP_SPUT_WIDE_finish          @ resume
9260
9261/* continuation for OP_SPUT_OBJECT */
9262
9263
9264.LOP_SPUT_OBJECT_end:
9265    str     r1, [r0, #offStaticField_value]  @ field<- vAA
9266    @ no-op
9267    cmp     r1, #0                      @ stored a null object?
9268    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
9269    GOTO_OPCODE(ip)                     @ jump to next instruction
9270
9271    /* Continuation if the field has not yet been resolved.
9272     * r1:  BBBB field ref
9273     * r10: dvmDex->pResFields
9274     */
9275.LOP_SPUT_OBJECT_resolve:
9276    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9277#if defined(WITH_JIT)
9278    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9279#endif
9280    EXPORT_PC()                         @ resolve() could throw, so export now
9281    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9282    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9283    cmp     r0, #0                      @ success?
9284    beq     common_exceptionThrown      @ no, handle exception
9285#if defined(WITH_JIT)
9286    /*
9287     * If the JIT is actively building a trace we need to make sure
9288     * that the field is fully resolved before including this instruction.
9289     */
9290    bl      common_verifyField
9291#endif
9292    b       .LOP_SPUT_OBJECT_finish          @ resume
9293
9294
9295/* continuation for OP_SPUT_BOOLEAN */
9296
9297    /*
9298     * Continuation if the field has not yet been resolved.
9299     *  r1:  BBBB field ref
9300     *  r10: dvmDex->pResFields
9301     */
9302.LOP_SPUT_BOOLEAN_resolve:
9303    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9304#if defined(WITH_JIT)
9305    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9306#endif
9307    EXPORT_PC()                         @ resolve() could throw, so export now
9308    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9309    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9310    cmp     r0, #0                      @ success?
9311    beq     common_exceptionThrown      @ no, handle exception
9312#if defined(WITH_JIT)
9313    /*
9314     * If the JIT is actively building a trace we need to make sure
9315     * that the field is fully resolved before including this instruction.
9316     */
9317    bl      common_verifyField
9318#endif
9319    b       .LOP_SPUT_BOOLEAN_finish          @ resume
9320
9321/* continuation for OP_SPUT_BYTE */
9322
9323    /*
9324     * Continuation if the field has not yet been resolved.
9325     *  r1:  BBBB field ref
9326     *  r10: dvmDex->pResFields
9327     */
9328.LOP_SPUT_BYTE_resolve:
9329    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9330#if defined(WITH_JIT)
9331    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9332#endif
9333    EXPORT_PC()                         @ resolve() could throw, so export now
9334    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9335    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9336    cmp     r0, #0                      @ success?
9337    beq     common_exceptionThrown      @ no, handle exception
9338#if defined(WITH_JIT)
9339    /*
9340     * If the JIT is actively building a trace we need to make sure
9341     * that the field is fully resolved before including this instruction.
9342     */
9343    bl      common_verifyField
9344#endif
9345    b       .LOP_SPUT_BYTE_finish          @ resume
9346
9347/* continuation for OP_SPUT_CHAR */
9348
9349    /*
9350     * Continuation if the field has not yet been resolved.
9351     *  r1:  BBBB field ref
9352     *  r10: dvmDex->pResFields
9353     */
9354.LOP_SPUT_CHAR_resolve:
9355    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9356#if defined(WITH_JIT)
9357    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9358#endif
9359    EXPORT_PC()                         @ resolve() could throw, so export now
9360    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9361    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9362    cmp     r0, #0                      @ success?
9363    beq     common_exceptionThrown      @ no, handle exception
9364#if defined(WITH_JIT)
9365    /*
9366     * If the JIT is actively building a trace we need to make sure
9367     * that the field is fully resolved before including this instruction.
9368     */
9369    bl      common_verifyField
9370#endif
9371    b       .LOP_SPUT_CHAR_finish          @ resume
9372
9373/* continuation for OP_SPUT_SHORT */
9374
9375    /*
9376     * Continuation if the field has not yet been resolved.
9377     *  r1:  BBBB field ref
9378     *  r10: dvmDex->pResFields
9379     */
9380.LOP_SPUT_SHORT_resolve:
9381    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9382#if defined(WITH_JIT)
9383    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9384#endif
9385    EXPORT_PC()                         @ resolve() could throw, so export now
9386    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9387    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9388    cmp     r0, #0                      @ success?
9389    beq     common_exceptionThrown      @ no, handle exception
9390#if defined(WITH_JIT)
9391    /*
9392     * If the JIT is actively building a trace we need to make sure
9393     * that the field is fully resolved before including this instruction.
9394     */
9395    bl      common_verifyField
9396#endif
9397    b       .LOP_SPUT_SHORT_finish          @ resume
9398
9399/* continuation for OP_INVOKE_VIRTUAL */
9400
9401    /*
9402     * At this point:
9403     *  r0 = resolved base method
9404     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
9405     */
9406.LOP_INVOKE_VIRTUAL_continue:
9407    GET_VREG(r9, r10)                   @ r9<- "this" ptr
9408    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
9409    cmp     r9, #0                      @ is "this" null?
9410    beq     common_errNullObject        @ null "this", throw exception
9411    ldr     r3, [r9, #offObject_clazz]  @ r3<- thisPtr->clazz
9412    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
9413    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
9414    bl      common_invokeMethodNoRange @ (r0=method, r9="this")
9415
9416/* continuation for OP_INVOKE_SUPER */
9417
9418    /*
9419     * At this point:
9420     *  r0 = resolved base method
9421     *  r10 = method->clazz
9422     */
9423.LOP_INVOKE_SUPER_continue:
9424    ldr     r1, [r10, #offClassObject_super]    @ r1<- method->clazz->super
9425    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
9426    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
9427    EXPORT_PC()                         @ must export for invoke
9428    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
9429    bcs     .LOP_INVOKE_SUPER_nsm             @ method not present in superclass
9430    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
9431    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
9432    bl      common_invokeMethodNoRange @ continue on
9433
9434.LOP_INVOKE_SUPER_resolve:
9435    mov     r0, r10                     @ r0<- method->clazz
9436    mov     r2, #METHOD_VIRTUAL         @ resolver method type
9437    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
9438    cmp     r0, #0                      @ got null?
9439    bne     .LOP_INVOKE_SUPER_continue        @ no, continue
9440    b       common_exceptionThrown      @ yes, handle exception
9441
9442    /*
9443     * Throw a NoSuchMethodError with the method name as the message.
9444     *  r0 = resolved base method
9445     */
9446.LOP_INVOKE_SUPER_nsm:
9447    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
9448    b       common_errNoSuchMethod
9449
9450/* continuation for OP_INVOKE_DIRECT */
9451
9452    /*
9453     * On entry:
9454     *  r1 = reference (BBBB or CCCC)
9455     *  r10 = "this" register
9456     */
9457.LOP_INVOKE_DIRECT_resolve:
9458    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
9459    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
9460    mov     r2, #METHOD_DIRECT          @ resolver method type
9461    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
9462    cmp     r0, #0                      @ got null?
9463    bne     .LOP_INVOKE_DIRECT_finish          @ no, continue
9464    b       common_exceptionThrown      @ yes, handle exception
9465
9466/* continuation for OP_INVOKE_STATIC */
9467
9468
9469.LOP_INVOKE_STATIC_resolve:
9470    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
9471    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
9472    mov     r2, #METHOD_STATIC          @ resolver method type
9473    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
9474    cmp     r0, #0                      @ got null?
9475#if defined(WITH_JIT)
9476    /*
9477     * Check to see if we're actively building a trace.  If so,
9478     * we need to keep this instruction out of it.
9479     * r10: &resolved_methodToCall
9480     */
9481    ldrh    r2, [rSELF, #offThread_subMode]
9482    beq     common_exceptionThrown            @ null, handle exception
9483    ands    r2, #kSubModeJitTraceBuild        @ trace under construction?
9484    beq     common_invokeMethodNoRange     @ no (r0=method, r9="this")
9485    ldr     r1, [r10]                         @ reload resolved method
9486    cmp     r1, #0                            @ finished resolving?
9487    bne     common_invokeMethodNoRange     @ yes (r0=method, r9="this")
9488    mov     r10, r0                           @ preserve method
9489    mov     r0, rSELF
9490    mov     r1, rPC
9491    bl      dvmJitEndTraceSelect              @ (self, pc)
9492    mov     r0, r10
9493    b       common_invokeMethodNoRange     @ whew, finally!
9494#else
9495    bne     common_invokeMethodNoRange     @ (r0=method, r9="this")
9496    b       common_exceptionThrown            @ yes, handle exception
9497#endif
9498
9499/* continuation for OP_INVOKE_VIRTUAL_RANGE */
9500
9501    /*
9502     * At this point:
9503     *  r0 = resolved base method
9504     *  r10 = C or CCCC (index of first arg, which is the "this" ptr)
9505     */
9506.LOP_INVOKE_VIRTUAL_RANGE_continue:
9507    GET_VREG(r9, r10)                   @ r9<- "this" ptr
9508    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
9509    cmp     r9, #0                      @ is "this" null?
9510    beq     common_errNullObject        @ null "this", throw exception
9511    ldr     r3, [r9, #offObject_clazz]  @ r3<- thisPtr->clazz
9512    ldr     r3, [r3, #offClassObject_vtable]    @ r3<- thisPtr->clazz->vtable
9513    ldr     r0, [r3, r2, lsl #2]        @ r3<- vtable[methodIndex]
9514    bl      common_invokeMethodRange @ (r0=method, r9="this")
9515
9516/* continuation for OP_INVOKE_SUPER_RANGE */
9517
9518    /*
9519     * At this point:
9520     *  r0 = resolved base method
9521     *  r10 = method->clazz
9522     */
9523.LOP_INVOKE_SUPER_RANGE_continue:
9524    ldr     r1, [r10, #offClassObject_super]    @ r1<- method->clazz->super
9525    ldrh    r2, [r0, #offMethod_methodIndex]    @ r2<- baseMethod->methodIndex
9526    ldr     r3, [r1, #offClassObject_vtableCount]   @ r3<- super->vtableCount
9527    EXPORT_PC()                         @ must export for invoke
9528    cmp     r2, r3                      @ compare (methodIndex, vtableCount)
9529    bcs     .LOP_INVOKE_SUPER_RANGE_nsm             @ method not present in superclass
9530    ldr     r1, [r1, #offClassObject_vtable]    @ r1<- ...clazz->super->vtable
9531    ldr     r0, [r1, r2, lsl #2]        @ r3<- vtable[methodIndex]
9532    bl      common_invokeMethodRange @ continue on
9533
9534.LOP_INVOKE_SUPER_RANGE_resolve:
9535    mov     r0, r10                     @ r0<- method->clazz
9536    mov     r2, #METHOD_VIRTUAL         @ resolver method type
9537    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
9538    cmp     r0, #0                      @ got null?
9539    bne     .LOP_INVOKE_SUPER_RANGE_continue        @ no, continue
9540    b       common_exceptionThrown      @ yes, handle exception
9541
9542    /*
9543     * Throw a NoSuchMethodError with the method name as the message.
9544     *  r0 = resolved base method
9545     */
9546.LOP_INVOKE_SUPER_RANGE_nsm:
9547    ldr     r1, [r0, #offMethod_name]   @ r1<- method name
9548    b       common_errNoSuchMethod
9549
9550/* continuation for OP_INVOKE_DIRECT_RANGE */
9551
9552    /*
9553     * On entry:
9554     *  r1 = reference (BBBB or CCCC)
9555     *  r10 = "this" register
9556     */
9557.LOP_INVOKE_DIRECT_RANGE_resolve:
9558    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
9559    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
9560    mov     r2, #METHOD_DIRECT          @ resolver method type
9561    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
9562    cmp     r0, #0                      @ got null?
9563    bne     .LOP_INVOKE_DIRECT_RANGE_finish          @ no, continue
9564    b       common_exceptionThrown      @ yes, handle exception
9565
9566/* continuation for OP_INVOKE_STATIC_RANGE */
9567
9568
9569.LOP_INVOKE_STATIC_RANGE_resolve:
9570    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
9571    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
9572    mov     r2, #METHOD_STATIC          @ resolver method type
9573    bl      dvmResolveMethod            @ r0<- call(clazz, ref, flags)
9574    cmp     r0, #0                      @ got null?
9575#if defined(WITH_JIT)
9576    /*
9577     * Check to see if we're actively building a trace.  If so,
9578     * we need to keep this instruction out of it.
9579     * r10: &resolved_methodToCall
9580     */
9581    ldrh    r2, [rSELF, #offThread_subMode]
9582    beq     common_exceptionThrown            @ null, handle exception
9583    ands    r2, #kSubModeJitTraceBuild        @ trace under construction?
9584    beq     common_invokeMethodRange     @ no (r0=method, r9="this")
9585    ldr     r1, [r10]                         @ reload resolved method
9586    cmp     r1, #0                            @ finished resolving?
9587    bne     common_invokeMethodRange     @ yes (r0=method, r9="this")
9588    mov     r10, r0                           @ preserve method
9589    mov     r0, rSELF
9590    mov     r1, rPC
9591    bl      dvmJitEndTraceSelect              @ (self, pc)
9592    mov     r0, r10
9593    b       common_invokeMethodRange     @ whew, finally!
9594#else
9595    bne     common_invokeMethodRange     @ (r0=method, r9="this")
9596    b       common_exceptionThrown            @ yes, handle exception
9597#endif
9598
9599/* continuation for OP_FLOAT_TO_LONG */
9600/*
9601 * Convert the float in r0 to a long in r0/r1.
9602 *
9603 * We have to clip values to long min/max per the specification.  The
9604 * expected common case is a "reasonable" value that converts directly
9605 * to modest integer.  The EABI convert function isn't doing this for us.
9606 */
9607f2l_doconv:
9608    stmfd   sp!, {r4, lr}
9609    mov     r1, #0x5f000000             @ (float)maxlong
9610    mov     r4, r0
9611    bl      __aeabi_fcmpge              @ is arg >= maxlong?
9612    cmp     r0, #0                      @ nonzero == yes
9613    mvnne   r0, #0                      @ return maxlong (7fffffff)
9614    mvnne   r1, #0x80000000
9615    ldmnefd sp!, {r4, pc}
9616
9617    mov     r0, r4                      @ recover arg
9618    mov     r1, #0xdf000000             @ (float)minlong
9619    bl      __aeabi_fcmple              @ is arg <= minlong?
9620    cmp     r0, #0                      @ nonzero == yes
9621    movne   r0, #0                      @ return minlong (80000000)
9622    movne   r1, #0x80000000
9623    ldmnefd sp!, {r4, pc}
9624
9625    mov     r0, r4                      @ recover arg
9626    mov     r1, r4
9627    bl      __aeabi_fcmpeq              @ is arg == self?
9628    cmp     r0, #0                      @ zero == no
9629    moveq   r1, #0                      @ return zero for NaN
9630    ldmeqfd sp!, {r4, pc}
9631
9632    mov     r0, r4                      @ recover arg
9633    bl      __aeabi_f2lz                @ convert float to long
9634    ldmfd   sp!, {r4, pc}
9635
9636/* continuation for OP_DOUBLE_TO_LONG */
9637/*
9638 * Convert the double in r0/r1 to a long in r0/r1.
9639 *
9640 * We have to clip values to long min/max per the specification.  The
9641 * expected common case is a "reasonable" value that converts directly
9642 * to modest integer.  The EABI convert function isn't doing this for us.
9643 */
9644d2l_doconv:
9645    stmfd   sp!, {r4, r5, lr}           @ save regs
9646    mov     r3, #0x43000000             @ maxlong, as a double (high word)
9647    add     r3, #0x00e00000             @  0x43e00000
9648    mov     r2, #0                      @ maxlong, as a double (low word)
9649    sub     sp, sp, #4                  @ align for EABI
9650    mov     r4, r0                      @ save a copy of r0
9651    mov     r5, r1                      @  and r1
9652    bl      __aeabi_dcmpge              @ is arg >= maxlong?
9653    cmp     r0, #0                      @ nonzero == yes
9654    mvnne   r0, #0                      @ return maxlong (7fffffffffffffff)
9655    mvnne   r1, #0x80000000
9656    bne     1f
9657
9658    mov     r0, r4                      @ recover arg
9659    mov     r1, r5
9660    mov     r3, #0xc3000000             @ minlong, as a double (high word)
9661    add     r3, #0x00e00000             @  0xc3e00000
9662    mov     r2, #0                      @ minlong, as a double (low word)
9663    bl      __aeabi_dcmple              @ is arg <= minlong?
9664    cmp     r0, #0                      @ nonzero == yes
9665    movne   r0, #0                      @ return minlong (8000000000000000)
9666    movne   r1, #0x80000000
9667    bne     1f
9668
9669    mov     r0, r4                      @ recover arg
9670    mov     r1, r5
9671    mov     r2, r4                      @ compare against self
9672    mov     r3, r5
9673    bl      __aeabi_dcmpeq              @ is arg == self?
9674    cmp     r0, #0                      @ zero == no
9675    moveq   r1, #0                      @ return zero for NaN
9676    beq     1f
9677
9678    mov     r0, r4                      @ recover arg
9679    mov     r1, r5
9680    bl      __aeabi_d2lz                @ convert double to long
9681
96821:
9683    add     sp, sp, #4
9684    ldmfd   sp!, {r4, r5, pc}
9685
9686/* continuation for OP_MUL_LONG */
9687
9688.LOP_MUL_LONG_finish:
9689    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9690    stmia   r0, {r9-r10}                @ vAA/vAA+1<- r9/r10
9691    GOTO_OPCODE(ip)                     @ jump to next instruction
9692
9693/* continuation for OP_SHL_LONG */
9694
9695.LOP_SHL_LONG_finish:
9696    mov     r0, r0, asl r2              @  r0<- r0 << r2
9697    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9698    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9699    GOTO_OPCODE(ip)                     @ jump to next instruction
9700
9701/* continuation for OP_SHR_LONG */
9702
9703.LOP_SHR_LONG_finish:
9704    mov     r1, r1, asr r2              @  r1<- r1 >> r2
9705    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9706    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9707    GOTO_OPCODE(ip)                     @ jump to next instruction
9708
9709/* continuation for OP_USHR_LONG */
9710
9711.LOP_USHR_LONG_finish:
9712    mov     r1, r1, lsr r2              @  r1<- r1 >>> r2
9713    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9714    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9715    GOTO_OPCODE(ip)                     @ jump to next instruction
9716
9717/* continuation for OP_SHL_LONG_2ADDR */
9718
9719.LOP_SHL_LONG_2ADDR_finish:
9720    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9721    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9722    GOTO_OPCODE(ip)                     @ jump to next instruction
9723
9724/* continuation for OP_SHR_LONG_2ADDR */
9725
9726.LOP_SHR_LONG_2ADDR_finish:
9727    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9728    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9729    GOTO_OPCODE(ip)                     @ jump to next instruction
9730
9731/* continuation for OP_USHR_LONG_2ADDR */
9732
9733.LOP_USHR_LONG_2ADDR_finish:
9734    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9735    stmia   r9, {r0-r1}                 @ vAA/vAA+1<- r0/r1
9736    GOTO_OPCODE(ip)                     @ jump to next instruction
9737
9738/* continuation for OP_IGET_VOLATILE */
9739
9740    /*
9741     * Currently:
9742     *  r0 holds resolved field
9743     *  r9 holds object
9744     */
9745.LOP_IGET_VOLATILE_finish:
9746    @bl      common_squeak0
9747    cmp     r9, #0                      @ check object for null
9748    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9749    beq     common_errNullObject        @ object was null
9750    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
9751    SMP_DMB                            @ acquiring load
9752    mov     r2, rINST, lsr #8           @ r2<- A+
9753    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9754    and     r2, r2, #15                 @ r2<- A
9755    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9756    SET_VREG(r0, r2)                    @ fp[A]<- r0
9757    GOTO_OPCODE(ip)                     @ jump to next instruction
9758
9759/* continuation for OP_IPUT_VOLATILE */
9760
9761    /*
9762     * Currently:
9763     *  r0 holds resolved field
9764     *  r9 holds object
9765     */
9766.LOP_IPUT_VOLATILE_finish:
9767    @bl      common_squeak0
9768    mov     r1, rINST, lsr #8           @ r1<- A+
9769    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9770    and     r1, r1, #15                 @ r1<- A
9771    cmp     r9, #0                      @ check object for null
9772    GET_VREG(r0, r1)                    @ r0<- fp[A]
9773    beq     common_errNullObject        @ object was null
9774    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9775    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9776    SMP_DMB_ST                        @ releasing store
9777    str  r0, [r9, r3]                @ obj.field (8/16/32 bits)<- r0
9778    SMP_DMB
9779    GOTO_OPCODE(ip)                     @ jump to next instruction
9780
9781/* continuation for OP_SGET_VOLATILE */
9782
9783    /*
9784     * Continuation if the field has not yet been resolved.
9785     *  r1:  BBBB field ref
9786     *  r10: dvmDex->pResFields
9787     */
9788.LOP_SGET_VOLATILE_resolve:
9789    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9790#if defined(WITH_JIT)
9791    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9792#endif
9793    EXPORT_PC()                         @ resolve() could throw, so export now
9794    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9795    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9796    cmp     r0, #0                      @ success?
9797    beq     common_exceptionThrown      @ no, handle exception
9798#if defined(WITH_JIT)
9799    /*
9800     * If the JIT is actively building a trace we need to make sure
9801     * that the field is fully resolved before including this instruction.
9802     */
9803    bl      common_verifyField
9804#endif
9805    b       .LOP_SGET_VOLATILE_finish
9806
9807/* continuation for OP_SPUT_VOLATILE */
9808
9809    /*
9810     * Continuation if the field has not yet been resolved.
9811     *  r1:  BBBB field ref
9812     *  r10: dvmDex->pResFields
9813     */
9814.LOP_SPUT_VOLATILE_resolve:
9815    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9816#if defined(WITH_JIT)
9817    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9818#endif
9819    EXPORT_PC()                         @ resolve() could throw, so export now
9820    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9821    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9822    cmp     r0, #0                      @ success?
9823    beq     common_exceptionThrown      @ no, handle exception
9824#if defined(WITH_JIT)
9825    /*
9826     * If the JIT is actively building a trace we need to make sure
9827     * that the field is fully resolved before including this instruction.
9828     */
9829    bl      common_verifyField
9830#endif
9831    b       .LOP_SPUT_VOLATILE_finish          @ resume
9832
9833/* continuation for OP_IGET_OBJECT_VOLATILE */
9834
9835    /*
9836     * Currently:
9837     *  r0 holds resolved field
9838     *  r9 holds object
9839     */
9840.LOP_IGET_OBJECT_VOLATILE_finish:
9841    @bl      common_squeak0
9842    cmp     r9, #0                      @ check object for null
9843    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9844    beq     common_errNullObject        @ object was null
9845    ldr   r0, [r9, r3]                @ r0<- obj.field (8/16/32 bits)
9846    SMP_DMB                            @ acquiring load
9847    mov     r2, rINST, lsr #8           @ r2<- A+
9848    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9849    and     r2, r2, #15                 @ r2<- A
9850    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9851    SET_VREG(r0, r2)                    @ fp[A]<- r0
9852    GOTO_OPCODE(ip)                     @ jump to next instruction
9853
9854/* continuation for OP_IGET_WIDE_VOLATILE */
9855
9856    /*
9857     * Currently:
9858     *  r0 holds resolved field
9859     *  r9 holds object
9860     */
9861.LOP_IGET_WIDE_VOLATILE_finish:
9862    cmp     r9, #0                      @ check object for null
9863    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9864    beq     common_errNullObject        @ object was null
9865    .if     1
9866    add     r0, r9, r3                  @ r0<- address of field
9867    bl      dvmQuasiAtomicRead64        @ r0/r1<- contents of field
9868    .else
9869    ldrd    r0, [r9, r3]                @ r0/r1<- obj.field (64-bit align ok)
9870    .endif
9871    mov     r2, rINST, lsr #8           @ r2<- A+
9872    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9873    and     r2, r2, #15                 @ r2<- A
9874    add     r3, rFP, r2, lsl #2         @ r3<- &fp[A]
9875    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
9876    stmia   r3, {r0-r1}                 @ fp[A]<- r0/r1
9877    GOTO_OPCODE(ip)                     @ jump to next instruction
9878
9879/* continuation for OP_IPUT_WIDE_VOLATILE */
9880
9881    /*
9882     * Currently:
9883     *  r0 holds resolved field
9884     *  r9 holds object
9885     */
9886.LOP_IPUT_WIDE_VOLATILE_finish:
9887    mov     r2, rINST, lsr #8           @ r2<- A+
9888    cmp     r9, #0                      @ check object for null
9889    and     r2, r2, #15                 @ r2<- A
9890    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
9891    add     r2, rFP, r2, lsl #2         @ r3<- &fp[A]
9892    beq     common_errNullObject        @ object was null
9893    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
9894    ldmia   r2, {r0-r1}                 @ r0/r1<- fp[A]
9895    GET_INST_OPCODE(r10)                @ extract opcode from rINST
9896    .if     1
9897    add     r2, r9, r3                  @ r2<- target address
9898    bl      dvmQuasiAtomicSwap64Sync    @ stores r0/r1 into addr r2
9899    .else
9900    strd    r0, [r9, r3]                @ obj.field (64 bits, aligned)<- r0/r1
9901    .endif
9902    GOTO_OPCODE(r10)                    @ jump to next instruction
9903
9904/* continuation for OP_SGET_WIDE_VOLATILE */
9905
9906    /*
9907     * Continuation if the field has not yet been resolved.
9908     *  r1:  BBBB field ref
9909     *  r10: dvmDex->pResFields
9910     *
9911     * Returns StaticField pointer in r0.
9912     */
9913.LOP_SGET_WIDE_VOLATILE_resolve:
9914    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9915#if defined(WITH_JIT)
9916    add     r10, r10, r1, lsl #2        @ r1<- &dvmDex->pResFields[field]
9917#endif
9918    EXPORT_PC()                         @ resolve() could throw, so export now
9919    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9920    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9921    cmp     r0, #0                      @ success?
9922    beq     common_exceptionThrown      @ no, handle exception
9923#if defined(WITH_JIT)
9924    /*
9925     * If the JIT is actively building a trace we need to make sure
9926     * that the field is fully resolved before including this instruction.
9927     */
9928    bl      common_verifyField
9929#endif
9930    b       .LOP_SGET_WIDE_VOLATILE_finish          @ resume
9931
9932/* continuation for OP_SPUT_WIDE_VOLATILE */
9933
9934    /*
9935     * Continuation if the field has not yet been resolved.
9936     *  r1:  BBBB field ref
9937     *  r9:  &fp[AA]
9938     *  r10: dvmDex->pResFields
9939     *
9940     * Returns StaticField pointer in r2.
9941     */
9942.LOP_SPUT_WIDE_VOLATILE_resolve:
9943    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
9944#if defined(WITH_JIT)
9945    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
9946#endif
9947    EXPORT_PC()                         @ resolve() could throw, so export now
9948    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
9949    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
9950    cmp     r0, #0                      @ success?
9951    mov     r2, r0                      @ copy to r2
9952    beq     common_exceptionThrown      @ no, handle exception
9953#if defined(WITH_JIT)
9954    /*
9955     * If the JIT is actively building a trace we need to make sure
9956     * that the field is fully resolved before including this instruction.
9957     */
9958    bl      common_verifyField
9959#endif
9960    b       .LOP_SPUT_WIDE_VOLATILE_finish          @ resume
9961
9962/* continuation for OP_EXECUTE_INLINE */
9963
9964    /*
9965     * Extract args, call function.
9966     *  r0 = #of args (0-4)
9967     *  r10 = call index
9968     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
9969     *
9970     * Other ideas:
9971     * - Use a jump table from the main piece to jump directly into the
9972     *   AND/LDR pairs.  Costs a data load, saves a branch.
9973     * - Have five separate pieces that do the loading, so we can work the
9974     *   interleave a little better.  Increases code size.
9975     */
9976.LOP_EXECUTE_INLINE_continue:
9977    rsb     r0, r0, #4                  @ r0<- 4-r0
9978    FETCH(rINST, 2)                     @ rINST<- FEDC
9979    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
9980    bl      common_abort                @ (skipped due to ARM prefetch)
99814:  and     ip, rINST, #0xf000          @ isolate F
9982    ldr     r3, [rFP, ip, lsr #10]      @ r3<- vF (shift right 12, left 2)
99833:  and     ip, rINST, #0x0f00          @ isolate E
9984    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vE
99852:  and     ip, rINST, #0x00f0          @ isolate D
9986    ldr     r1, [rFP, ip, lsr #2]       @ r1<- vD
99871:  and     ip, rINST, #0x000f          @ isolate C
9988    ldr     r0, [rFP, ip, lsl #2]       @ r0<- vC
99890:
9990    ldr     rINST, .LOP_EXECUTE_INLINE_table    @ table of InlineOperation
99915:  add     rINST, pc
9992    ldr     pc, [rINST, r10, lsl #4]    @ sizeof=16, "func" is first entry
9993    @ (not reached)
9994
9995    /*
9996     * We're debugging or profiling.
9997     * r10: opIndex
9998     */
9999.LOP_EXECUTE_INLINE_debugmode:
10000    mov     r0, r10
10001    bl      dvmResolveInlineNative
10002    cmp     r0, #0                      @ did it resolve?
10003    beq     .LOP_EXECUTE_INLINE_resume          @ no, just move on
10004    mov     r9, r0                      @ remember method
10005    mov     r1, rSELF
10006    bl      dvmFastMethodTraceEnter     @ (method, self)
10007    add     r1, rSELF, #offThread_retval@ r1<- &self->retval
10008    sub     sp, sp, #8                  @ make room for arg, +64 bit align
10009    mov     r0, rINST, lsr #12          @ r0<- B
10010    str     r1, [sp]                    @ push &self->retval
10011    bl      .LOP_EXECUTE_INLINE_continue        @ make call; will return after
10012    mov     rINST, r0                   @ save result of inline
10013    add     sp, sp, #8                  @ pop stack
10014    mov     r0, r9                      @ r0<- method
10015    mov     r1, rSELF
10016    bl      dvmFastNativeMethodTraceExit @ (method, self)
10017    cmp     rINST, #0                   @ test boolean result of inline
10018    beq     common_exceptionThrown      @ returned false, handle exception
10019    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
10020    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10021    GOTO_OPCODE(ip)                     @ jump to next instruction
10022
10023
10024
10025
10026.LOP_EXECUTE_INLINE_table:
10027    .word   PCREL_REF(gDvmInlineOpsTable,5b)
10028
10029/* continuation for OP_EXECUTE_INLINE_RANGE */
10030
10031    /*
10032     * Extract args, call function.
10033     *  r0 = #of args (0-4)
10034     *  r10 = call index
10035     *  lr = return addr, above  [DO NOT bl out of here w/o preserving LR]
10036     */
10037.LOP_EXECUTE_INLINE_RANGE_continue:
10038    rsb     r0, r0, #4                  @ r0<- 4-r0
10039    FETCH(r9, 2)                        @ r9<- CCCC
10040    add     pc, pc, r0, lsl #3          @ computed goto, 2 instrs each
10041    bl      common_abort                @ (skipped due to ARM prefetch)
100424:  add     ip, r9, #3                  @ base+3
10043    GET_VREG(r3, ip)                    @ r3<- vBase[3]
100443:  add     ip, r9, #2                  @ base+2
10045    GET_VREG(r2, ip)                    @ r2<- vBase[2]
100462:  add     ip, r9, #1                  @ base+1
10047    GET_VREG(r1, ip)                    @ r1<- vBase[1]
100481:  add     ip, r9, #0                  @ (nop)
10049    GET_VREG(r0, ip)                    @ r0<- vBase[0]
100500:
10051    ldr     r9, .LOP_EXECUTE_INLINE_RANGE_table       @ table of InlineOperation
100525:  add     r9, pc
10053    ldr     pc, [r9, r10, lsl #4]       @ sizeof=16, "func" is first entry
10054    @ (not reached)
10055
10056
10057    /*
10058     * We're debugging or profiling.
10059     * r10: opIndex
10060     */
10061.LOP_EXECUTE_INLINE_RANGE_debugmode:
10062    mov     r0, r10
10063    bl      dvmResolveInlineNative
10064    cmp     r0, #0                      @ did it resolve?
10065    beq     .LOP_EXECUTE_INLINE_RANGE_resume          @ no, just move on
10066    mov     r9, r0                      @ remember method
10067    mov     r1, rSELF
10068    bl      dvmFastMethodTraceEnter     @ (method, self)
10069    add     r1, rSELF, #offThread_retval@ r1<- &self->retval
10070    sub     sp, sp, #8                  @ make room for arg, +64 bit align
10071    mov     r0, rINST, lsr #8           @ r0<- B
10072    mov     rINST, r9                   @ rINST<- method
10073    str     r1, [sp]                    @ push &self->retval
10074    bl      .LOP_EXECUTE_INLINE_RANGE_continue        @ make call; will return after
10075    mov     r9, r0                      @ save result of inline
10076    add     sp, sp, #8                  @ pop stack
10077    mov     r0, rINST                   @ r0<- method
10078    mov     r1, rSELF
10079    bl      dvmFastNativeMethodTraceExit  @ (method, self)
10080    cmp     r9, #0                      @ test boolean result of inline
10081    beq     common_exceptionThrown      @ returned false, handle exception
10082    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
10083    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10084    GOTO_OPCODE(ip)                     @ jump to next instruction
10085
10086
10087
10088
10089.LOP_EXECUTE_INLINE_RANGE_table:
10090    .word   PCREL_REF(gDvmInlineOpsTable,5b)
10091
10092
10093/* continuation for OP_INVOKE_OBJECT_INIT_RANGE */
10094
10095.LOP_INVOKE_OBJECT_INIT_RANGE_setFinal:
10096    EXPORT_PC()                         @ can throw
10097    bl      dvmSetFinalizable           @ call dvmSetFinalizable(obj)
10098    ldr     r0, [rSELF, #offThread_exception] @ r0<- self->exception
10099    cmp     r0, #0                      @ exception pending?
10100    bne     common_exceptionThrown      @ yes, handle it
10101    b       .LOP_INVOKE_OBJECT_INIT_RANGE_finish
10102
10103    /*
10104     * A debugger is attached, so we need to go ahead and do
10105     * this.  For simplicity, we'll just jump directly to the
10106     * corresponding handler.  Note that we can't use
10107     * rIBASE here because it may be in single-step mode.
10108     * Load the primary table base directly.
10109     */
10110.LOP_INVOKE_OBJECT_INIT_RANGE_debugger:
10111    ldr     r1, [rSELF, #offThread_mainHandlerTable]
10112    mov     ip, #OP_INVOKE_DIRECT_RANGE
10113    GOTO_OPCODE_BASE(r1,ip)             @ execute it
10114
10115/* continuation for OP_IPUT_OBJECT_VOLATILE */
10116
10117    /*
10118     * Currently:
10119     *  r0 holds resolved field
10120     *  r9 holds object
10121     */
10122.LOP_IPUT_OBJECT_VOLATILE_finish:
10123    @bl      common_squeak0
10124    mov     r1, rINST, lsr #8           @ r1<- A+
10125    ldr     r3, [r0, #offInstField_byteOffset]  @ r3<- byte offset of field
10126    and     r1, r1, #15                 @ r1<- A
10127    cmp     r9, #0                      @ check object for null
10128    GET_VREG(r0, r1)                    @ r0<- fp[A]
10129    ldr     r2, [rSELF, #offThread_cardTable]  @ r2<- card table base
10130    beq     common_errNullObject        @ object was null
10131    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
10132    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
10133    SMP_DMB_ST                        @ releasing store
10134    str     r0, [r9, r3]                @ obj.field (32 bits)<- r0
10135    SMP_DMB
10136    cmp     r0, #0                      @ stored a null reference?
10137    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card if not
10138    GOTO_OPCODE(ip)                     @ jump to next instruction
10139
10140/* continuation for OP_SGET_OBJECT_VOLATILE */
10141
10142    /*
10143     * Continuation if the field has not yet been resolved.
10144     *  r1:  BBBB field ref
10145     *  r10: dvmDex->pResFields
10146     */
10147.LOP_SGET_OBJECT_VOLATILE_resolve:
10148    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
10149#if defined(WITH_JIT)
10150    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
10151#endif
10152    EXPORT_PC()                         @ resolve() could throw, so export now
10153    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
10154    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
10155    cmp     r0, #0                      @ success?
10156    beq     common_exceptionThrown      @ no, handle exception
10157#if defined(WITH_JIT)
10158    /*
10159     * If the JIT is actively building a trace we need to make sure
10160     * that the field is fully resolved before including this instruction.
10161     */
10162    bl      common_verifyField
10163#endif
10164    b       .LOP_SGET_OBJECT_VOLATILE_finish
10165
10166/* continuation for OP_SPUT_OBJECT_VOLATILE */
10167
10168
10169.LOP_SPUT_OBJECT_VOLATILE_end:
10170    str     r1, [r0, #offStaticField_value]  @ field<- vAA
10171    SMP_DMB
10172    cmp     r1, #0                      @ stored a null object?
10173    strneb  r2, [r2, r9, lsr #GC_CARD_SHIFT]  @ mark card based on obj head
10174    GOTO_OPCODE(ip)                     @ jump to next instruction
10175
10176    /* Continuation if the field has not yet been resolved.
10177     * r1:  BBBB field ref
10178     * r10: dvmDex->pResFields
10179     */
10180.LOP_SPUT_OBJECT_VOLATILE_resolve:
10181    ldr     r2, [rSELF, #offThread_method]    @ r2<- current method
10182#if defined(WITH_JIT)
10183    add     r10, r10, r1, lsl #2        @ r10<- &dvmDex->pResFields[field]
10184#endif
10185    EXPORT_PC()                         @ resolve() could throw, so export now
10186    ldr     r0, [r2, #offMethod_clazz]  @ r0<- method->clazz
10187    bl      dvmResolveStaticField       @ r0<- resolved StaticField ptr
10188    cmp     r0, #0                      @ success?
10189    beq     common_exceptionThrown      @ no, handle exception
10190#if defined(WITH_JIT)
10191    /*
10192     * If the JIT is actively building a trace we need to make sure
10193     * that the field is fully resolved before including this instruction.
10194     */
10195    bl      common_verifyField
10196#endif
10197    b       .LOP_SPUT_OBJECT_VOLATILE_finish          @ resume
10198
10199
10200    .size   dvmAsmSisterStart, .-dvmAsmSisterStart
10201    .global dvmAsmSisterEnd
10202dvmAsmSisterEnd:
10203
10204
10205    .global dvmAsmAltInstructionStart
10206    .type   dvmAsmAltInstructionStart, %function
10207    .text
10208
10209dvmAsmAltInstructionStart = .L_ALT_OP_NOP
10210/* ------------------------------ */
10211    .balign 64
10212.L_ALT_OP_NOP: /* 0x00 */
10213/* File: armv5te/alt_stub.S */
10214/*
10215 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10216 * any interesting requests and then jump to the real instruction
10217 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10218 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10219 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10220 * bail to the real handler if breakFlags==0.
10221 */
10222    ldrb   r3, [rSELF, #offThread_breakFlags]
10223    adrl   lr, dvmAsmInstructionStart + (0 * 64)
10224    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10225    cmp    r3, #0
10226    bxeq   lr                   @ nothing to do - jump to real handler
10227    EXPORT_PC()
10228    mov    r0, rPC              @ arg0
10229    mov    r1, rFP              @ arg1
10230    mov    r2, rSELF            @ arg2
10231    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10232
10233/* ------------------------------ */
10234    .balign 64
10235.L_ALT_OP_MOVE: /* 0x01 */
10236/* File: armv5te/alt_stub.S */
10237/*
10238 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10239 * any interesting requests and then jump to the real instruction
10240 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10241 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10242 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10243 * bail to the real handler if breakFlags==0.
10244 */
10245    ldrb   r3, [rSELF, #offThread_breakFlags]
10246    adrl   lr, dvmAsmInstructionStart + (1 * 64)
10247    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10248    cmp    r3, #0
10249    bxeq   lr                   @ nothing to do - jump to real handler
10250    EXPORT_PC()
10251    mov    r0, rPC              @ arg0
10252    mov    r1, rFP              @ arg1
10253    mov    r2, rSELF            @ arg2
10254    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10255
10256/* ------------------------------ */
10257    .balign 64
10258.L_ALT_OP_MOVE_FROM16: /* 0x02 */
10259/* File: armv5te/alt_stub.S */
10260/*
10261 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10262 * any interesting requests and then jump to the real instruction
10263 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10264 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10265 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10266 * bail to the real handler if breakFlags==0.
10267 */
10268    ldrb   r3, [rSELF, #offThread_breakFlags]
10269    adrl   lr, dvmAsmInstructionStart + (2 * 64)
10270    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10271    cmp    r3, #0
10272    bxeq   lr                   @ nothing to do - jump to real handler
10273    EXPORT_PC()
10274    mov    r0, rPC              @ arg0
10275    mov    r1, rFP              @ arg1
10276    mov    r2, rSELF            @ arg2
10277    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10278
10279/* ------------------------------ */
10280    .balign 64
10281.L_ALT_OP_MOVE_16: /* 0x03 */
10282/* File: armv5te/alt_stub.S */
10283/*
10284 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10285 * any interesting requests and then jump to the real instruction
10286 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10287 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10288 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10289 * bail to the real handler if breakFlags==0.
10290 */
10291    ldrb   r3, [rSELF, #offThread_breakFlags]
10292    adrl   lr, dvmAsmInstructionStart + (3 * 64)
10293    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10294    cmp    r3, #0
10295    bxeq   lr                   @ nothing to do - jump to real handler
10296    EXPORT_PC()
10297    mov    r0, rPC              @ arg0
10298    mov    r1, rFP              @ arg1
10299    mov    r2, rSELF            @ arg2
10300    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10301
10302/* ------------------------------ */
10303    .balign 64
10304.L_ALT_OP_MOVE_WIDE: /* 0x04 */
10305/* File: armv5te/alt_stub.S */
10306/*
10307 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10308 * any interesting requests and then jump to the real instruction
10309 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10310 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10311 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10312 * bail to the real handler if breakFlags==0.
10313 */
10314    ldrb   r3, [rSELF, #offThread_breakFlags]
10315    adrl   lr, dvmAsmInstructionStart + (4 * 64)
10316    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10317    cmp    r3, #0
10318    bxeq   lr                   @ nothing to do - jump to real handler
10319    EXPORT_PC()
10320    mov    r0, rPC              @ arg0
10321    mov    r1, rFP              @ arg1
10322    mov    r2, rSELF            @ arg2
10323    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10324
10325/* ------------------------------ */
10326    .balign 64
10327.L_ALT_OP_MOVE_WIDE_FROM16: /* 0x05 */
10328/* File: armv5te/alt_stub.S */
10329/*
10330 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10331 * any interesting requests and then jump to the real instruction
10332 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10333 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10334 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10335 * bail to the real handler if breakFlags==0.
10336 */
10337    ldrb   r3, [rSELF, #offThread_breakFlags]
10338    adrl   lr, dvmAsmInstructionStart + (5 * 64)
10339    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10340    cmp    r3, #0
10341    bxeq   lr                   @ nothing to do - jump to real handler
10342    EXPORT_PC()
10343    mov    r0, rPC              @ arg0
10344    mov    r1, rFP              @ arg1
10345    mov    r2, rSELF            @ arg2
10346    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10347
10348/* ------------------------------ */
10349    .balign 64
10350.L_ALT_OP_MOVE_WIDE_16: /* 0x06 */
10351/* File: armv5te/alt_stub.S */
10352/*
10353 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10354 * any interesting requests and then jump to the real instruction
10355 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10356 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10357 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10358 * bail to the real handler if breakFlags==0.
10359 */
10360    ldrb   r3, [rSELF, #offThread_breakFlags]
10361    adrl   lr, dvmAsmInstructionStart + (6 * 64)
10362    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10363    cmp    r3, #0
10364    bxeq   lr                   @ nothing to do - jump to real handler
10365    EXPORT_PC()
10366    mov    r0, rPC              @ arg0
10367    mov    r1, rFP              @ arg1
10368    mov    r2, rSELF            @ arg2
10369    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10370
10371/* ------------------------------ */
10372    .balign 64
10373.L_ALT_OP_MOVE_OBJECT: /* 0x07 */
10374/* File: armv5te/alt_stub.S */
10375/*
10376 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10377 * any interesting requests and then jump to the real instruction
10378 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10379 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10380 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10381 * bail to the real handler if breakFlags==0.
10382 */
10383    ldrb   r3, [rSELF, #offThread_breakFlags]
10384    adrl   lr, dvmAsmInstructionStart + (7 * 64)
10385    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10386    cmp    r3, #0
10387    bxeq   lr                   @ nothing to do - jump to real handler
10388    EXPORT_PC()
10389    mov    r0, rPC              @ arg0
10390    mov    r1, rFP              @ arg1
10391    mov    r2, rSELF            @ arg2
10392    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10393
10394/* ------------------------------ */
10395    .balign 64
10396.L_ALT_OP_MOVE_OBJECT_FROM16: /* 0x08 */
10397/* File: armv5te/alt_stub.S */
10398/*
10399 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10400 * any interesting requests and then jump to the real instruction
10401 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10402 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10403 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10404 * bail to the real handler if breakFlags==0.
10405 */
10406    ldrb   r3, [rSELF, #offThread_breakFlags]
10407    adrl   lr, dvmAsmInstructionStart + (8 * 64)
10408    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10409    cmp    r3, #0
10410    bxeq   lr                   @ nothing to do - jump to real handler
10411    EXPORT_PC()
10412    mov    r0, rPC              @ arg0
10413    mov    r1, rFP              @ arg1
10414    mov    r2, rSELF            @ arg2
10415    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10416
10417/* ------------------------------ */
10418    .balign 64
10419.L_ALT_OP_MOVE_OBJECT_16: /* 0x09 */
10420/* File: armv5te/alt_stub.S */
10421/*
10422 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10423 * any interesting requests and then jump to the real instruction
10424 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10425 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10426 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10427 * bail to the real handler if breakFlags==0.
10428 */
10429    ldrb   r3, [rSELF, #offThread_breakFlags]
10430    adrl   lr, dvmAsmInstructionStart + (9 * 64)
10431    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10432    cmp    r3, #0
10433    bxeq   lr                   @ nothing to do - jump to real handler
10434    EXPORT_PC()
10435    mov    r0, rPC              @ arg0
10436    mov    r1, rFP              @ arg1
10437    mov    r2, rSELF            @ arg2
10438    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10439
10440/* ------------------------------ */
10441    .balign 64
10442.L_ALT_OP_MOVE_RESULT: /* 0x0a */
10443/* File: armv5te/alt_stub.S */
10444/*
10445 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10446 * any interesting requests and then jump to the real instruction
10447 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10448 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10449 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10450 * bail to the real handler if breakFlags==0.
10451 */
10452    ldrb   r3, [rSELF, #offThread_breakFlags]
10453    adrl   lr, dvmAsmInstructionStart + (10 * 64)
10454    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10455    cmp    r3, #0
10456    bxeq   lr                   @ nothing to do - jump to real handler
10457    EXPORT_PC()
10458    mov    r0, rPC              @ arg0
10459    mov    r1, rFP              @ arg1
10460    mov    r2, rSELF            @ arg2
10461    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10462
10463/* ------------------------------ */
10464    .balign 64
10465.L_ALT_OP_MOVE_RESULT_WIDE: /* 0x0b */
10466/* File: armv5te/alt_stub.S */
10467/*
10468 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10469 * any interesting requests and then jump to the real instruction
10470 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10471 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10472 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10473 * bail to the real handler if breakFlags==0.
10474 */
10475    ldrb   r3, [rSELF, #offThread_breakFlags]
10476    adrl   lr, dvmAsmInstructionStart + (11 * 64)
10477    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10478    cmp    r3, #0
10479    bxeq   lr                   @ nothing to do - jump to real handler
10480    EXPORT_PC()
10481    mov    r0, rPC              @ arg0
10482    mov    r1, rFP              @ arg1
10483    mov    r2, rSELF            @ arg2
10484    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10485
10486/* ------------------------------ */
10487    .balign 64
10488.L_ALT_OP_MOVE_RESULT_OBJECT: /* 0x0c */
10489/* File: armv5te/alt_stub.S */
10490/*
10491 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10492 * any interesting requests and then jump to the real instruction
10493 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10494 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10495 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10496 * bail to the real handler if breakFlags==0.
10497 */
10498    ldrb   r3, [rSELF, #offThread_breakFlags]
10499    adrl   lr, dvmAsmInstructionStart + (12 * 64)
10500    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10501    cmp    r3, #0
10502    bxeq   lr                   @ nothing to do - jump to real handler
10503    EXPORT_PC()
10504    mov    r0, rPC              @ arg0
10505    mov    r1, rFP              @ arg1
10506    mov    r2, rSELF            @ arg2
10507    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10508
10509/* ------------------------------ */
10510    .balign 64
10511.L_ALT_OP_MOVE_EXCEPTION: /* 0x0d */
10512/* File: armv5te/alt_stub.S */
10513/*
10514 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10515 * any interesting requests and then jump to the real instruction
10516 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10517 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10518 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10519 * bail to the real handler if breakFlags==0.
10520 */
10521    ldrb   r3, [rSELF, #offThread_breakFlags]
10522    adrl   lr, dvmAsmInstructionStart + (13 * 64)
10523    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10524    cmp    r3, #0
10525    bxeq   lr                   @ nothing to do - jump to real handler
10526    EXPORT_PC()
10527    mov    r0, rPC              @ arg0
10528    mov    r1, rFP              @ arg1
10529    mov    r2, rSELF            @ arg2
10530    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10531
10532/* ------------------------------ */
10533    .balign 64
10534.L_ALT_OP_RETURN_VOID: /* 0x0e */
10535/* File: armv5te/alt_stub.S */
10536/*
10537 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10538 * any interesting requests and then jump to the real instruction
10539 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10540 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10541 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10542 * bail to the real handler if breakFlags==0.
10543 */
10544    ldrb   r3, [rSELF, #offThread_breakFlags]
10545    adrl   lr, dvmAsmInstructionStart + (14 * 64)
10546    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10547    cmp    r3, #0
10548    bxeq   lr                   @ nothing to do - jump to real handler
10549    EXPORT_PC()
10550    mov    r0, rPC              @ arg0
10551    mov    r1, rFP              @ arg1
10552    mov    r2, rSELF            @ arg2
10553    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10554
10555/* ------------------------------ */
10556    .balign 64
10557.L_ALT_OP_RETURN: /* 0x0f */
10558/* File: armv5te/alt_stub.S */
10559/*
10560 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10561 * any interesting requests and then jump to the real instruction
10562 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10563 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10564 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10565 * bail to the real handler if breakFlags==0.
10566 */
10567    ldrb   r3, [rSELF, #offThread_breakFlags]
10568    adrl   lr, dvmAsmInstructionStart + (15 * 64)
10569    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10570    cmp    r3, #0
10571    bxeq   lr                   @ nothing to do - jump to real handler
10572    EXPORT_PC()
10573    mov    r0, rPC              @ arg0
10574    mov    r1, rFP              @ arg1
10575    mov    r2, rSELF            @ arg2
10576    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10577
10578/* ------------------------------ */
10579    .balign 64
10580.L_ALT_OP_RETURN_WIDE: /* 0x10 */
10581/* File: armv5te/alt_stub.S */
10582/*
10583 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10584 * any interesting requests and then jump to the real instruction
10585 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10586 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10587 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10588 * bail to the real handler if breakFlags==0.
10589 */
10590    ldrb   r3, [rSELF, #offThread_breakFlags]
10591    adrl   lr, dvmAsmInstructionStart + (16 * 64)
10592    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10593    cmp    r3, #0
10594    bxeq   lr                   @ nothing to do - jump to real handler
10595    EXPORT_PC()
10596    mov    r0, rPC              @ arg0
10597    mov    r1, rFP              @ arg1
10598    mov    r2, rSELF            @ arg2
10599    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10600
10601/* ------------------------------ */
10602    .balign 64
10603.L_ALT_OP_RETURN_OBJECT: /* 0x11 */
10604/* File: armv5te/alt_stub.S */
10605/*
10606 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10607 * any interesting requests and then jump to the real instruction
10608 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10609 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10610 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10611 * bail to the real handler if breakFlags==0.
10612 */
10613    ldrb   r3, [rSELF, #offThread_breakFlags]
10614    adrl   lr, dvmAsmInstructionStart + (17 * 64)
10615    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10616    cmp    r3, #0
10617    bxeq   lr                   @ nothing to do - jump to real handler
10618    EXPORT_PC()
10619    mov    r0, rPC              @ arg0
10620    mov    r1, rFP              @ arg1
10621    mov    r2, rSELF            @ arg2
10622    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10623
10624/* ------------------------------ */
10625    .balign 64
10626.L_ALT_OP_CONST_4: /* 0x12 */
10627/* File: armv5te/alt_stub.S */
10628/*
10629 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10630 * any interesting requests and then jump to the real instruction
10631 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10632 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10633 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10634 * bail to the real handler if breakFlags==0.
10635 */
10636    ldrb   r3, [rSELF, #offThread_breakFlags]
10637    adrl   lr, dvmAsmInstructionStart + (18 * 64)
10638    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10639    cmp    r3, #0
10640    bxeq   lr                   @ nothing to do - jump to real handler
10641    EXPORT_PC()
10642    mov    r0, rPC              @ arg0
10643    mov    r1, rFP              @ arg1
10644    mov    r2, rSELF            @ arg2
10645    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10646
10647/* ------------------------------ */
10648    .balign 64
10649.L_ALT_OP_CONST_16: /* 0x13 */
10650/* File: armv5te/alt_stub.S */
10651/*
10652 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10653 * any interesting requests and then jump to the real instruction
10654 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10655 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10656 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10657 * bail to the real handler if breakFlags==0.
10658 */
10659    ldrb   r3, [rSELF, #offThread_breakFlags]
10660    adrl   lr, dvmAsmInstructionStart + (19 * 64)
10661    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10662    cmp    r3, #0
10663    bxeq   lr                   @ nothing to do - jump to real handler
10664    EXPORT_PC()
10665    mov    r0, rPC              @ arg0
10666    mov    r1, rFP              @ arg1
10667    mov    r2, rSELF            @ arg2
10668    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10669
10670/* ------------------------------ */
10671    .balign 64
10672.L_ALT_OP_CONST: /* 0x14 */
10673/* File: armv5te/alt_stub.S */
10674/*
10675 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10676 * any interesting requests and then jump to the real instruction
10677 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10678 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10679 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10680 * bail to the real handler if breakFlags==0.
10681 */
10682    ldrb   r3, [rSELF, #offThread_breakFlags]
10683    adrl   lr, dvmAsmInstructionStart + (20 * 64)
10684    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10685    cmp    r3, #0
10686    bxeq   lr                   @ nothing to do - jump to real handler
10687    EXPORT_PC()
10688    mov    r0, rPC              @ arg0
10689    mov    r1, rFP              @ arg1
10690    mov    r2, rSELF            @ arg2
10691    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10692
10693/* ------------------------------ */
10694    .balign 64
10695.L_ALT_OP_CONST_HIGH16: /* 0x15 */
10696/* File: armv5te/alt_stub.S */
10697/*
10698 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10699 * any interesting requests and then jump to the real instruction
10700 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10701 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10702 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10703 * bail to the real handler if breakFlags==0.
10704 */
10705    ldrb   r3, [rSELF, #offThread_breakFlags]
10706    adrl   lr, dvmAsmInstructionStart + (21 * 64)
10707    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10708    cmp    r3, #0
10709    bxeq   lr                   @ nothing to do - jump to real handler
10710    EXPORT_PC()
10711    mov    r0, rPC              @ arg0
10712    mov    r1, rFP              @ arg1
10713    mov    r2, rSELF            @ arg2
10714    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10715
10716/* ------------------------------ */
10717    .balign 64
10718.L_ALT_OP_CONST_WIDE_16: /* 0x16 */
10719/* File: armv5te/alt_stub.S */
10720/*
10721 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10722 * any interesting requests and then jump to the real instruction
10723 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10724 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10725 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10726 * bail to the real handler if breakFlags==0.
10727 */
10728    ldrb   r3, [rSELF, #offThread_breakFlags]
10729    adrl   lr, dvmAsmInstructionStart + (22 * 64)
10730    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10731    cmp    r3, #0
10732    bxeq   lr                   @ nothing to do - jump to real handler
10733    EXPORT_PC()
10734    mov    r0, rPC              @ arg0
10735    mov    r1, rFP              @ arg1
10736    mov    r2, rSELF            @ arg2
10737    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10738
10739/* ------------------------------ */
10740    .balign 64
10741.L_ALT_OP_CONST_WIDE_32: /* 0x17 */
10742/* File: armv5te/alt_stub.S */
10743/*
10744 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10745 * any interesting requests and then jump to the real instruction
10746 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10747 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10748 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10749 * bail to the real handler if breakFlags==0.
10750 */
10751    ldrb   r3, [rSELF, #offThread_breakFlags]
10752    adrl   lr, dvmAsmInstructionStart + (23 * 64)
10753    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10754    cmp    r3, #0
10755    bxeq   lr                   @ nothing to do - jump to real handler
10756    EXPORT_PC()
10757    mov    r0, rPC              @ arg0
10758    mov    r1, rFP              @ arg1
10759    mov    r2, rSELF            @ arg2
10760    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10761
10762/* ------------------------------ */
10763    .balign 64
10764.L_ALT_OP_CONST_WIDE: /* 0x18 */
10765/* File: armv5te/alt_stub.S */
10766/*
10767 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10768 * any interesting requests and then jump to the real instruction
10769 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10770 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10771 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10772 * bail to the real handler if breakFlags==0.
10773 */
10774    ldrb   r3, [rSELF, #offThread_breakFlags]
10775    adrl   lr, dvmAsmInstructionStart + (24 * 64)
10776    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10777    cmp    r3, #0
10778    bxeq   lr                   @ nothing to do - jump to real handler
10779    EXPORT_PC()
10780    mov    r0, rPC              @ arg0
10781    mov    r1, rFP              @ arg1
10782    mov    r2, rSELF            @ arg2
10783    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10784
10785/* ------------------------------ */
10786    .balign 64
10787.L_ALT_OP_CONST_WIDE_HIGH16: /* 0x19 */
10788/* File: armv5te/alt_stub.S */
10789/*
10790 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10791 * any interesting requests and then jump to the real instruction
10792 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10793 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10794 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10795 * bail to the real handler if breakFlags==0.
10796 */
10797    ldrb   r3, [rSELF, #offThread_breakFlags]
10798    adrl   lr, dvmAsmInstructionStart + (25 * 64)
10799    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10800    cmp    r3, #0
10801    bxeq   lr                   @ nothing to do - jump to real handler
10802    EXPORT_PC()
10803    mov    r0, rPC              @ arg0
10804    mov    r1, rFP              @ arg1
10805    mov    r2, rSELF            @ arg2
10806    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10807
10808/* ------------------------------ */
10809    .balign 64
10810.L_ALT_OP_CONST_STRING: /* 0x1a */
10811/* File: armv5te/alt_stub.S */
10812/*
10813 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10814 * any interesting requests and then jump to the real instruction
10815 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10816 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10817 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10818 * bail to the real handler if breakFlags==0.
10819 */
10820    ldrb   r3, [rSELF, #offThread_breakFlags]
10821    adrl   lr, dvmAsmInstructionStart + (26 * 64)
10822    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10823    cmp    r3, #0
10824    bxeq   lr                   @ nothing to do - jump to real handler
10825    EXPORT_PC()
10826    mov    r0, rPC              @ arg0
10827    mov    r1, rFP              @ arg1
10828    mov    r2, rSELF            @ arg2
10829    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10830
10831/* ------------------------------ */
10832    .balign 64
10833.L_ALT_OP_CONST_STRING_JUMBO: /* 0x1b */
10834/* File: armv5te/alt_stub.S */
10835/*
10836 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10837 * any interesting requests and then jump to the real instruction
10838 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10839 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10840 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10841 * bail to the real handler if breakFlags==0.
10842 */
10843    ldrb   r3, [rSELF, #offThread_breakFlags]
10844    adrl   lr, dvmAsmInstructionStart + (27 * 64)
10845    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10846    cmp    r3, #0
10847    bxeq   lr                   @ nothing to do - jump to real handler
10848    EXPORT_PC()
10849    mov    r0, rPC              @ arg0
10850    mov    r1, rFP              @ arg1
10851    mov    r2, rSELF            @ arg2
10852    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10853
10854/* ------------------------------ */
10855    .balign 64
10856.L_ALT_OP_CONST_CLASS: /* 0x1c */
10857/* File: armv5te/alt_stub.S */
10858/*
10859 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10860 * any interesting requests and then jump to the real instruction
10861 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10862 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10863 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10864 * bail to the real handler if breakFlags==0.
10865 */
10866    ldrb   r3, [rSELF, #offThread_breakFlags]
10867    adrl   lr, dvmAsmInstructionStart + (28 * 64)
10868    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10869    cmp    r3, #0
10870    bxeq   lr                   @ nothing to do - jump to real handler
10871    EXPORT_PC()
10872    mov    r0, rPC              @ arg0
10873    mov    r1, rFP              @ arg1
10874    mov    r2, rSELF            @ arg2
10875    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10876
10877/* ------------------------------ */
10878    .balign 64
10879.L_ALT_OP_MONITOR_ENTER: /* 0x1d */
10880/* File: armv5te/alt_stub.S */
10881/*
10882 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10883 * any interesting requests and then jump to the real instruction
10884 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10885 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10886 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10887 * bail to the real handler if breakFlags==0.
10888 */
10889    ldrb   r3, [rSELF, #offThread_breakFlags]
10890    adrl   lr, dvmAsmInstructionStart + (29 * 64)
10891    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10892    cmp    r3, #0
10893    bxeq   lr                   @ nothing to do - jump to real handler
10894    EXPORT_PC()
10895    mov    r0, rPC              @ arg0
10896    mov    r1, rFP              @ arg1
10897    mov    r2, rSELF            @ arg2
10898    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10899
10900/* ------------------------------ */
10901    .balign 64
10902.L_ALT_OP_MONITOR_EXIT: /* 0x1e */
10903/* File: armv5te/alt_stub.S */
10904/*
10905 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10906 * any interesting requests and then jump to the real instruction
10907 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10908 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10909 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10910 * bail to the real handler if breakFlags==0.
10911 */
10912    ldrb   r3, [rSELF, #offThread_breakFlags]
10913    adrl   lr, dvmAsmInstructionStart + (30 * 64)
10914    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10915    cmp    r3, #0
10916    bxeq   lr                   @ nothing to do - jump to real handler
10917    EXPORT_PC()
10918    mov    r0, rPC              @ arg0
10919    mov    r1, rFP              @ arg1
10920    mov    r2, rSELF            @ arg2
10921    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10922
10923/* ------------------------------ */
10924    .balign 64
10925.L_ALT_OP_CHECK_CAST: /* 0x1f */
10926/* File: armv5te/alt_stub.S */
10927/*
10928 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10929 * any interesting requests and then jump to the real instruction
10930 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10931 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10932 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10933 * bail to the real handler if breakFlags==0.
10934 */
10935    ldrb   r3, [rSELF, #offThread_breakFlags]
10936    adrl   lr, dvmAsmInstructionStart + (31 * 64)
10937    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10938    cmp    r3, #0
10939    bxeq   lr                   @ nothing to do - jump to real handler
10940    EXPORT_PC()
10941    mov    r0, rPC              @ arg0
10942    mov    r1, rFP              @ arg1
10943    mov    r2, rSELF            @ arg2
10944    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10945
10946/* ------------------------------ */
10947    .balign 64
10948.L_ALT_OP_INSTANCE_OF: /* 0x20 */
10949/* File: armv5te/alt_stub.S */
10950/*
10951 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10952 * any interesting requests and then jump to the real instruction
10953 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10954 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10955 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10956 * bail to the real handler if breakFlags==0.
10957 */
10958    ldrb   r3, [rSELF, #offThread_breakFlags]
10959    adrl   lr, dvmAsmInstructionStart + (32 * 64)
10960    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10961    cmp    r3, #0
10962    bxeq   lr                   @ nothing to do - jump to real handler
10963    EXPORT_PC()
10964    mov    r0, rPC              @ arg0
10965    mov    r1, rFP              @ arg1
10966    mov    r2, rSELF            @ arg2
10967    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10968
10969/* ------------------------------ */
10970    .balign 64
10971.L_ALT_OP_ARRAY_LENGTH: /* 0x21 */
10972/* File: armv5te/alt_stub.S */
10973/*
10974 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10975 * any interesting requests and then jump to the real instruction
10976 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
10977 * rIBASE updates won't be seen until a refresh, and we can tell we have a
10978 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
10979 * bail to the real handler if breakFlags==0.
10980 */
10981    ldrb   r3, [rSELF, #offThread_breakFlags]
10982    adrl   lr, dvmAsmInstructionStart + (33 * 64)
10983    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
10984    cmp    r3, #0
10985    bxeq   lr                   @ nothing to do - jump to real handler
10986    EXPORT_PC()
10987    mov    r0, rPC              @ arg0
10988    mov    r1, rFP              @ arg1
10989    mov    r2, rSELF            @ arg2
10990    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
10991
10992/* ------------------------------ */
10993    .balign 64
10994.L_ALT_OP_NEW_INSTANCE: /* 0x22 */
10995/* File: armv5te/alt_stub.S */
10996/*
10997 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
10998 * any interesting requests and then jump to the real instruction
10999 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11000 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11001 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11002 * bail to the real handler if breakFlags==0.
11003 */
11004    ldrb   r3, [rSELF, #offThread_breakFlags]
11005    adrl   lr, dvmAsmInstructionStart + (34 * 64)
11006    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11007    cmp    r3, #0
11008    bxeq   lr                   @ nothing to do - jump to real handler
11009    EXPORT_PC()
11010    mov    r0, rPC              @ arg0
11011    mov    r1, rFP              @ arg1
11012    mov    r2, rSELF            @ arg2
11013    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11014
11015/* ------------------------------ */
11016    .balign 64
11017.L_ALT_OP_NEW_ARRAY: /* 0x23 */
11018/* File: armv5te/alt_stub.S */
11019/*
11020 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11021 * any interesting requests and then jump to the real instruction
11022 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11023 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11024 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11025 * bail to the real handler if breakFlags==0.
11026 */
11027    ldrb   r3, [rSELF, #offThread_breakFlags]
11028    adrl   lr, dvmAsmInstructionStart + (35 * 64)
11029    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11030    cmp    r3, #0
11031    bxeq   lr                   @ nothing to do - jump to real handler
11032    EXPORT_PC()
11033    mov    r0, rPC              @ arg0
11034    mov    r1, rFP              @ arg1
11035    mov    r2, rSELF            @ arg2
11036    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11037
11038/* ------------------------------ */
11039    .balign 64
11040.L_ALT_OP_FILLED_NEW_ARRAY: /* 0x24 */
11041/* File: armv5te/alt_stub.S */
11042/*
11043 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11044 * any interesting requests and then jump to the real instruction
11045 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11046 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11047 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11048 * bail to the real handler if breakFlags==0.
11049 */
11050    ldrb   r3, [rSELF, #offThread_breakFlags]
11051    adrl   lr, dvmAsmInstructionStart + (36 * 64)
11052    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11053    cmp    r3, #0
11054    bxeq   lr                   @ nothing to do - jump to real handler
11055    EXPORT_PC()
11056    mov    r0, rPC              @ arg0
11057    mov    r1, rFP              @ arg1
11058    mov    r2, rSELF            @ arg2
11059    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11060
11061/* ------------------------------ */
11062    .balign 64
11063.L_ALT_OP_FILLED_NEW_ARRAY_RANGE: /* 0x25 */
11064/* File: armv5te/alt_stub.S */
11065/*
11066 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11067 * any interesting requests and then jump to the real instruction
11068 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11069 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11070 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11071 * bail to the real handler if breakFlags==0.
11072 */
11073    ldrb   r3, [rSELF, #offThread_breakFlags]
11074    adrl   lr, dvmAsmInstructionStart + (37 * 64)
11075    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11076    cmp    r3, #0
11077    bxeq   lr                   @ nothing to do - jump to real handler
11078    EXPORT_PC()
11079    mov    r0, rPC              @ arg0
11080    mov    r1, rFP              @ arg1
11081    mov    r2, rSELF            @ arg2
11082    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11083
11084/* ------------------------------ */
11085    .balign 64
11086.L_ALT_OP_FILL_ARRAY_DATA: /* 0x26 */
11087/* File: armv5te/alt_stub.S */
11088/*
11089 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11090 * any interesting requests and then jump to the real instruction
11091 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11092 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11093 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11094 * bail to the real handler if breakFlags==0.
11095 */
11096    ldrb   r3, [rSELF, #offThread_breakFlags]
11097    adrl   lr, dvmAsmInstructionStart + (38 * 64)
11098    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11099    cmp    r3, #0
11100    bxeq   lr                   @ nothing to do - jump to real handler
11101    EXPORT_PC()
11102    mov    r0, rPC              @ arg0
11103    mov    r1, rFP              @ arg1
11104    mov    r2, rSELF            @ arg2
11105    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11106
11107/* ------------------------------ */
11108    .balign 64
11109.L_ALT_OP_THROW: /* 0x27 */
11110/* File: armv5te/alt_stub.S */
11111/*
11112 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11113 * any interesting requests and then jump to the real instruction
11114 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11115 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11116 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11117 * bail to the real handler if breakFlags==0.
11118 */
11119    ldrb   r3, [rSELF, #offThread_breakFlags]
11120    adrl   lr, dvmAsmInstructionStart + (39 * 64)
11121    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11122    cmp    r3, #0
11123    bxeq   lr                   @ nothing to do - jump to real handler
11124    EXPORT_PC()
11125    mov    r0, rPC              @ arg0
11126    mov    r1, rFP              @ arg1
11127    mov    r2, rSELF            @ arg2
11128    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11129
11130/* ------------------------------ */
11131    .balign 64
11132.L_ALT_OP_GOTO: /* 0x28 */
11133/* File: armv5te/alt_stub.S */
11134/*
11135 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11136 * any interesting requests and then jump to the real instruction
11137 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11138 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11139 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11140 * bail to the real handler if breakFlags==0.
11141 */
11142    ldrb   r3, [rSELF, #offThread_breakFlags]
11143    adrl   lr, dvmAsmInstructionStart + (40 * 64)
11144    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11145    cmp    r3, #0
11146    bxeq   lr                   @ nothing to do - jump to real handler
11147    EXPORT_PC()
11148    mov    r0, rPC              @ arg0
11149    mov    r1, rFP              @ arg1
11150    mov    r2, rSELF            @ arg2
11151    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11152
11153/* ------------------------------ */
11154    .balign 64
11155.L_ALT_OP_GOTO_16: /* 0x29 */
11156/* File: armv5te/alt_stub.S */
11157/*
11158 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11159 * any interesting requests and then jump to the real instruction
11160 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11161 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11162 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11163 * bail to the real handler if breakFlags==0.
11164 */
11165    ldrb   r3, [rSELF, #offThread_breakFlags]
11166    adrl   lr, dvmAsmInstructionStart + (41 * 64)
11167    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11168    cmp    r3, #0
11169    bxeq   lr                   @ nothing to do - jump to real handler
11170    EXPORT_PC()
11171    mov    r0, rPC              @ arg0
11172    mov    r1, rFP              @ arg1
11173    mov    r2, rSELF            @ arg2
11174    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11175
11176/* ------------------------------ */
11177    .balign 64
11178.L_ALT_OP_GOTO_32: /* 0x2a */
11179/* File: armv5te/alt_stub.S */
11180/*
11181 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11182 * any interesting requests and then jump to the real instruction
11183 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11184 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11185 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11186 * bail to the real handler if breakFlags==0.
11187 */
11188    ldrb   r3, [rSELF, #offThread_breakFlags]
11189    adrl   lr, dvmAsmInstructionStart + (42 * 64)
11190    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11191    cmp    r3, #0
11192    bxeq   lr                   @ nothing to do - jump to real handler
11193    EXPORT_PC()
11194    mov    r0, rPC              @ arg0
11195    mov    r1, rFP              @ arg1
11196    mov    r2, rSELF            @ arg2
11197    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11198
11199/* ------------------------------ */
11200    .balign 64
11201.L_ALT_OP_PACKED_SWITCH: /* 0x2b */
11202/* File: armv5te/alt_stub.S */
11203/*
11204 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11205 * any interesting requests and then jump to the real instruction
11206 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11207 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11208 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11209 * bail to the real handler if breakFlags==0.
11210 */
11211    ldrb   r3, [rSELF, #offThread_breakFlags]
11212    adrl   lr, dvmAsmInstructionStart + (43 * 64)
11213    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11214    cmp    r3, #0
11215    bxeq   lr                   @ nothing to do - jump to real handler
11216    EXPORT_PC()
11217    mov    r0, rPC              @ arg0
11218    mov    r1, rFP              @ arg1
11219    mov    r2, rSELF            @ arg2
11220    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11221
11222/* ------------------------------ */
11223    .balign 64
11224.L_ALT_OP_SPARSE_SWITCH: /* 0x2c */
11225/* File: armv5te/alt_stub.S */
11226/*
11227 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11228 * any interesting requests and then jump to the real instruction
11229 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11230 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11231 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11232 * bail to the real handler if breakFlags==0.
11233 */
11234    ldrb   r3, [rSELF, #offThread_breakFlags]
11235    adrl   lr, dvmAsmInstructionStart + (44 * 64)
11236    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11237    cmp    r3, #0
11238    bxeq   lr                   @ nothing to do - jump to real handler
11239    EXPORT_PC()
11240    mov    r0, rPC              @ arg0
11241    mov    r1, rFP              @ arg1
11242    mov    r2, rSELF            @ arg2
11243    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11244
11245/* ------------------------------ */
11246    .balign 64
11247.L_ALT_OP_CMPL_FLOAT: /* 0x2d */
11248/* File: armv5te/alt_stub.S */
11249/*
11250 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11251 * any interesting requests and then jump to the real instruction
11252 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11253 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11254 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11255 * bail to the real handler if breakFlags==0.
11256 */
11257    ldrb   r3, [rSELF, #offThread_breakFlags]
11258    adrl   lr, dvmAsmInstructionStart + (45 * 64)
11259    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11260    cmp    r3, #0
11261    bxeq   lr                   @ nothing to do - jump to real handler
11262    EXPORT_PC()
11263    mov    r0, rPC              @ arg0
11264    mov    r1, rFP              @ arg1
11265    mov    r2, rSELF            @ arg2
11266    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11267
11268/* ------------------------------ */
11269    .balign 64
11270.L_ALT_OP_CMPG_FLOAT: /* 0x2e */
11271/* File: armv5te/alt_stub.S */
11272/*
11273 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11274 * any interesting requests and then jump to the real instruction
11275 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11276 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11277 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11278 * bail to the real handler if breakFlags==0.
11279 */
11280    ldrb   r3, [rSELF, #offThread_breakFlags]
11281    adrl   lr, dvmAsmInstructionStart + (46 * 64)
11282    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11283    cmp    r3, #0
11284    bxeq   lr                   @ nothing to do - jump to real handler
11285    EXPORT_PC()
11286    mov    r0, rPC              @ arg0
11287    mov    r1, rFP              @ arg1
11288    mov    r2, rSELF            @ arg2
11289    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11290
11291/* ------------------------------ */
11292    .balign 64
11293.L_ALT_OP_CMPL_DOUBLE: /* 0x2f */
11294/* File: armv5te/alt_stub.S */
11295/*
11296 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11297 * any interesting requests and then jump to the real instruction
11298 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11299 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11300 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11301 * bail to the real handler if breakFlags==0.
11302 */
11303    ldrb   r3, [rSELF, #offThread_breakFlags]
11304    adrl   lr, dvmAsmInstructionStart + (47 * 64)
11305    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11306    cmp    r3, #0
11307    bxeq   lr                   @ nothing to do - jump to real handler
11308    EXPORT_PC()
11309    mov    r0, rPC              @ arg0
11310    mov    r1, rFP              @ arg1
11311    mov    r2, rSELF            @ arg2
11312    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11313
11314/* ------------------------------ */
11315    .balign 64
11316.L_ALT_OP_CMPG_DOUBLE: /* 0x30 */
11317/* File: armv5te/alt_stub.S */
11318/*
11319 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11320 * any interesting requests and then jump to the real instruction
11321 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11322 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11323 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11324 * bail to the real handler if breakFlags==0.
11325 */
11326    ldrb   r3, [rSELF, #offThread_breakFlags]
11327    adrl   lr, dvmAsmInstructionStart + (48 * 64)
11328    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11329    cmp    r3, #0
11330    bxeq   lr                   @ nothing to do - jump to real handler
11331    EXPORT_PC()
11332    mov    r0, rPC              @ arg0
11333    mov    r1, rFP              @ arg1
11334    mov    r2, rSELF            @ arg2
11335    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11336
11337/* ------------------------------ */
11338    .balign 64
11339.L_ALT_OP_CMP_LONG: /* 0x31 */
11340/* File: armv5te/alt_stub.S */
11341/*
11342 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11343 * any interesting requests and then jump to the real instruction
11344 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11345 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11346 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11347 * bail to the real handler if breakFlags==0.
11348 */
11349    ldrb   r3, [rSELF, #offThread_breakFlags]
11350    adrl   lr, dvmAsmInstructionStart + (49 * 64)
11351    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11352    cmp    r3, #0
11353    bxeq   lr                   @ nothing to do - jump to real handler
11354    EXPORT_PC()
11355    mov    r0, rPC              @ arg0
11356    mov    r1, rFP              @ arg1
11357    mov    r2, rSELF            @ arg2
11358    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11359
11360/* ------------------------------ */
11361    .balign 64
11362.L_ALT_OP_IF_EQ: /* 0x32 */
11363/* File: armv5te/alt_stub.S */
11364/*
11365 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11366 * any interesting requests and then jump to the real instruction
11367 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11368 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11369 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11370 * bail to the real handler if breakFlags==0.
11371 */
11372    ldrb   r3, [rSELF, #offThread_breakFlags]
11373    adrl   lr, dvmAsmInstructionStart + (50 * 64)
11374    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11375    cmp    r3, #0
11376    bxeq   lr                   @ nothing to do - jump to real handler
11377    EXPORT_PC()
11378    mov    r0, rPC              @ arg0
11379    mov    r1, rFP              @ arg1
11380    mov    r2, rSELF            @ arg2
11381    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11382
11383/* ------------------------------ */
11384    .balign 64
11385.L_ALT_OP_IF_NE: /* 0x33 */
11386/* File: armv5te/alt_stub.S */
11387/*
11388 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11389 * any interesting requests and then jump to the real instruction
11390 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11391 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11392 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11393 * bail to the real handler if breakFlags==0.
11394 */
11395    ldrb   r3, [rSELF, #offThread_breakFlags]
11396    adrl   lr, dvmAsmInstructionStart + (51 * 64)
11397    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11398    cmp    r3, #0
11399    bxeq   lr                   @ nothing to do - jump to real handler
11400    EXPORT_PC()
11401    mov    r0, rPC              @ arg0
11402    mov    r1, rFP              @ arg1
11403    mov    r2, rSELF            @ arg2
11404    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11405
11406/* ------------------------------ */
11407    .balign 64
11408.L_ALT_OP_IF_LT: /* 0x34 */
11409/* File: armv5te/alt_stub.S */
11410/*
11411 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11412 * any interesting requests and then jump to the real instruction
11413 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11414 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11415 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11416 * bail to the real handler if breakFlags==0.
11417 */
11418    ldrb   r3, [rSELF, #offThread_breakFlags]
11419    adrl   lr, dvmAsmInstructionStart + (52 * 64)
11420    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11421    cmp    r3, #0
11422    bxeq   lr                   @ nothing to do - jump to real handler
11423    EXPORT_PC()
11424    mov    r0, rPC              @ arg0
11425    mov    r1, rFP              @ arg1
11426    mov    r2, rSELF            @ arg2
11427    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11428
11429/* ------------------------------ */
11430    .balign 64
11431.L_ALT_OP_IF_GE: /* 0x35 */
11432/* File: armv5te/alt_stub.S */
11433/*
11434 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11435 * any interesting requests and then jump to the real instruction
11436 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11437 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11438 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11439 * bail to the real handler if breakFlags==0.
11440 */
11441    ldrb   r3, [rSELF, #offThread_breakFlags]
11442    adrl   lr, dvmAsmInstructionStart + (53 * 64)
11443    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11444    cmp    r3, #0
11445    bxeq   lr                   @ nothing to do - jump to real handler
11446    EXPORT_PC()
11447    mov    r0, rPC              @ arg0
11448    mov    r1, rFP              @ arg1
11449    mov    r2, rSELF            @ arg2
11450    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11451
11452/* ------------------------------ */
11453    .balign 64
11454.L_ALT_OP_IF_GT: /* 0x36 */
11455/* File: armv5te/alt_stub.S */
11456/*
11457 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11458 * any interesting requests and then jump to the real instruction
11459 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11460 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11461 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11462 * bail to the real handler if breakFlags==0.
11463 */
11464    ldrb   r3, [rSELF, #offThread_breakFlags]
11465    adrl   lr, dvmAsmInstructionStart + (54 * 64)
11466    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11467    cmp    r3, #0
11468    bxeq   lr                   @ nothing to do - jump to real handler
11469    EXPORT_PC()
11470    mov    r0, rPC              @ arg0
11471    mov    r1, rFP              @ arg1
11472    mov    r2, rSELF            @ arg2
11473    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11474
11475/* ------------------------------ */
11476    .balign 64
11477.L_ALT_OP_IF_LE: /* 0x37 */
11478/* File: armv5te/alt_stub.S */
11479/*
11480 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11481 * any interesting requests and then jump to the real instruction
11482 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11483 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11484 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11485 * bail to the real handler if breakFlags==0.
11486 */
11487    ldrb   r3, [rSELF, #offThread_breakFlags]
11488    adrl   lr, dvmAsmInstructionStart + (55 * 64)
11489    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11490    cmp    r3, #0
11491    bxeq   lr                   @ nothing to do - jump to real handler
11492    EXPORT_PC()
11493    mov    r0, rPC              @ arg0
11494    mov    r1, rFP              @ arg1
11495    mov    r2, rSELF            @ arg2
11496    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11497
11498/* ------------------------------ */
11499    .balign 64
11500.L_ALT_OP_IF_EQZ: /* 0x38 */
11501/* File: armv5te/alt_stub.S */
11502/*
11503 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11504 * any interesting requests and then jump to the real instruction
11505 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11506 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11507 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11508 * bail to the real handler if breakFlags==0.
11509 */
11510    ldrb   r3, [rSELF, #offThread_breakFlags]
11511    adrl   lr, dvmAsmInstructionStart + (56 * 64)
11512    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11513    cmp    r3, #0
11514    bxeq   lr                   @ nothing to do - jump to real handler
11515    EXPORT_PC()
11516    mov    r0, rPC              @ arg0
11517    mov    r1, rFP              @ arg1
11518    mov    r2, rSELF            @ arg2
11519    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11520
11521/* ------------------------------ */
11522    .balign 64
11523.L_ALT_OP_IF_NEZ: /* 0x39 */
11524/* File: armv5te/alt_stub.S */
11525/*
11526 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11527 * any interesting requests and then jump to the real instruction
11528 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11529 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11530 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11531 * bail to the real handler if breakFlags==0.
11532 */
11533    ldrb   r3, [rSELF, #offThread_breakFlags]
11534    adrl   lr, dvmAsmInstructionStart + (57 * 64)
11535    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11536    cmp    r3, #0
11537    bxeq   lr                   @ nothing to do - jump to real handler
11538    EXPORT_PC()
11539    mov    r0, rPC              @ arg0
11540    mov    r1, rFP              @ arg1
11541    mov    r2, rSELF            @ arg2
11542    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11543
11544/* ------------------------------ */
11545    .balign 64
11546.L_ALT_OP_IF_LTZ: /* 0x3a */
11547/* File: armv5te/alt_stub.S */
11548/*
11549 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11550 * any interesting requests and then jump to the real instruction
11551 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11552 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11553 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11554 * bail to the real handler if breakFlags==0.
11555 */
11556    ldrb   r3, [rSELF, #offThread_breakFlags]
11557    adrl   lr, dvmAsmInstructionStart + (58 * 64)
11558    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11559    cmp    r3, #0
11560    bxeq   lr                   @ nothing to do - jump to real handler
11561    EXPORT_PC()
11562    mov    r0, rPC              @ arg0
11563    mov    r1, rFP              @ arg1
11564    mov    r2, rSELF            @ arg2
11565    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11566
11567/* ------------------------------ */
11568    .balign 64
11569.L_ALT_OP_IF_GEZ: /* 0x3b */
11570/* File: armv5te/alt_stub.S */
11571/*
11572 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11573 * any interesting requests and then jump to the real instruction
11574 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11575 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11576 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11577 * bail to the real handler if breakFlags==0.
11578 */
11579    ldrb   r3, [rSELF, #offThread_breakFlags]
11580    adrl   lr, dvmAsmInstructionStart + (59 * 64)
11581    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11582    cmp    r3, #0
11583    bxeq   lr                   @ nothing to do - jump to real handler
11584    EXPORT_PC()
11585    mov    r0, rPC              @ arg0
11586    mov    r1, rFP              @ arg1
11587    mov    r2, rSELF            @ arg2
11588    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11589
11590/* ------------------------------ */
11591    .balign 64
11592.L_ALT_OP_IF_GTZ: /* 0x3c */
11593/* File: armv5te/alt_stub.S */
11594/*
11595 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11596 * any interesting requests and then jump to the real instruction
11597 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11598 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11599 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11600 * bail to the real handler if breakFlags==0.
11601 */
11602    ldrb   r3, [rSELF, #offThread_breakFlags]
11603    adrl   lr, dvmAsmInstructionStart + (60 * 64)
11604    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11605    cmp    r3, #0
11606    bxeq   lr                   @ nothing to do - jump to real handler
11607    EXPORT_PC()
11608    mov    r0, rPC              @ arg0
11609    mov    r1, rFP              @ arg1
11610    mov    r2, rSELF            @ arg2
11611    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11612
11613/* ------------------------------ */
11614    .balign 64
11615.L_ALT_OP_IF_LEZ: /* 0x3d */
11616/* File: armv5te/alt_stub.S */
11617/*
11618 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11619 * any interesting requests and then jump to the real instruction
11620 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11621 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11622 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11623 * bail to the real handler if breakFlags==0.
11624 */
11625    ldrb   r3, [rSELF, #offThread_breakFlags]
11626    adrl   lr, dvmAsmInstructionStart + (61 * 64)
11627    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11628    cmp    r3, #0
11629    bxeq   lr                   @ nothing to do - jump to real handler
11630    EXPORT_PC()
11631    mov    r0, rPC              @ arg0
11632    mov    r1, rFP              @ arg1
11633    mov    r2, rSELF            @ arg2
11634    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11635
11636/* ------------------------------ */
11637    .balign 64
11638.L_ALT_OP_UNUSED_3E: /* 0x3e */
11639/* File: armv5te/alt_stub.S */
11640/*
11641 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11642 * any interesting requests and then jump to the real instruction
11643 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11644 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11645 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11646 * bail to the real handler if breakFlags==0.
11647 */
11648    ldrb   r3, [rSELF, #offThread_breakFlags]
11649    adrl   lr, dvmAsmInstructionStart + (62 * 64)
11650    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11651    cmp    r3, #0
11652    bxeq   lr                   @ nothing to do - jump to real handler
11653    EXPORT_PC()
11654    mov    r0, rPC              @ arg0
11655    mov    r1, rFP              @ arg1
11656    mov    r2, rSELF            @ arg2
11657    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11658
11659/* ------------------------------ */
11660    .balign 64
11661.L_ALT_OP_UNUSED_3F: /* 0x3f */
11662/* File: armv5te/alt_stub.S */
11663/*
11664 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11665 * any interesting requests and then jump to the real instruction
11666 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11667 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11668 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11669 * bail to the real handler if breakFlags==0.
11670 */
11671    ldrb   r3, [rSELF, #offThread_breakFlags]
11672    adrl   lr, dvmAsmInstructionStart + (63 * 64)
11673    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11674    cmp    r3, #0
11675    bxeq   lr                   @ nothing to do - jump to real handler
11676    EXPORT_PC()
11677    mov    r0, rPC              @ arg0
11678    mov    r1, rFP              @ arg1
11679    mov    r2, rSELF            @ arg2
11680    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11681
11682/* ------------------------------ */
11683    .balign 64
11684.L_ALT_OP_UNUSED_40: /* 0x40 */
11685/* File: armv5te/alt_stub.S */
11686/*
11687 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11688 * any interesting requests and then jump to the real instruction
11689 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11690 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11691 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11692 * bail to the real handler if breakFlags==0.
11693 */
11694    ldrb   r3, [rSELF, #offThread_breakFlags]
11695    adrl   lr, dvmAsmInstructionStart + (64 * 64)
11696    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11697    cmp    r3, #0
11698    bxeq   lr                   @ nothing to do - jump to real handler
11699    EXPORT_PC()
11700    mov    r0, rPC              @ arg0
11701    mov    r1, rFP              @ arg1
11702    mov    r2, rSELF            @ arg2
11703    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11704
11705/* ------------------------------ */
11706    .balign 64
11707.L_ALT_OP_UNUSED_41: /* 0x41 */
11708/* File: armv5te/alt_stub.S */
11709/*
11710 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11711 * any interesting requests and then jump to the real instruction
11712 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11713 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11714 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11715 * bail to the real handler if breakFlags==0.
11716 */
11717    ldrb   r3, [rSELF, #offThread_breakFlags]
11718    adrl   lr, dvmAsmInstructionStart + (65 * 64)
11719    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11720    cmp    r3, #0
11721    bxeq   lr                   @ nothing to do - jump to real handler
11722    EXPORT_PC()
11723    mov    r0, rPC              @ arg0
11724    mov    r1, rFP              @ arg1
11725    mov    r2, rSELF            @ arg2
11726    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11727
11728/* ------------------------------ */
11729    .balign 64
11730.L_ALT_OP_UNUSED_42: /* 0x42 */
11731/* File: armv5te/alt_stub.S */
11732/*
11733 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11734 * any interesting requests and then jump to the real instruction
11735 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11736 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11737 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11738 * bail to the real handler if breakFlags==0.
11739 */
11740    ldrb   r3, [rSELF, #offThread_breakFlags]
11741    adrl   lr, dvmAsmInstructionStart + (66 * 64)
11742    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11743    cmp    r3, #0
11744    bxeq   lr                   @ nothing to do - jump to real handler
11745    EXPORT_PC()
11746    mov    r0, rPC              @ arg0
11747    mov    r1, rFP              @ arg1
11748    mov    r2, rSELF            @ arg2
11749    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11750
11751/* ------------------------------ */
11752    .balign 64
11753.L_ALT_OP_UNUSED_43: /* 0x43 */
11754/* File: armv5te/alt_stub.S */
11755/*
11756 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11757 * any interesting requests and then jump to the real instruction
11758 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11759 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11760 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11761 * bail to the real handler if breakFlags==0.
11762 */
11763    ldrb   r3, [rSELF, #offThread_breakFlags]
11764    adrl   lr, dvmAsmInstructionStart + (67 * 64)
11765    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11766    cmp    r3, #0
11767    bxeq   lr                   @ nothing to do - jump to real handler
11768    EXPORT_PC()
11769    mov    r0, rPC              @ arg0
11770    mov    r1, rFP              @ arg1
11771    mov    r2, rSELF            @ arg2
11772    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11773
11774/* ------------------------------ */
11775    .balign 64
11776.L_ALT_OP_AGET: /* 0x44 */
11777/* File: armv5te/alt_stub.S */
11778/*
11779 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11780 * any interesting requests and then jump to the real instruction
11781 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11782 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11783 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11784 * bail to the real handler if breakFlags==0.
11785 */
11786    ldrb   r3, [rSELF, #offThread_breakFlags]
11787    adrl   lr, dvmAsmInstructionStart + (68 * 64)
11788    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11789    cmp    r3, #0
11790    bxeq   lr                   @ nothing to do - jump to real handler
11791    EXPORT_PC()
11792    mov    r0, rPC              @ arg0
11793    mov    r1, rFP              @ arg1
11794    mov    r2, rSELF            @ arg2
11795    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11796
11797/* ------------------------------ */
11798    .balign 64
11799.L_ALT_OP_AGET_WIDE: /* 0x45 */
11800/* File: armv5te/alt_stub.S */
11801/*
11802 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11803 * any interesting requests and then jump to the real instruction
11804 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11805 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11806 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11807 * bail to the real handler if breakFlags==0.
11808 */
11809    ldrb   r3, [rSELF, #offThread_breakFlags]
11810    adrl   lr, dvmAsmInstructionStart + (69 * 64)
11811    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11812    cmp    r3, #0
11813    bxeq   lr                   @ nothing to do - jump to real handler
11814    EXPORT_PC()
11815    mov    r0, rPC              @ arg0
11816    mov    r1, rFP              @ arg1
11817    mov    r2, rSELF            @ arg2
11818    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11819
11820/* ------------------------------ */
11821    .balign 64
11822.L_ALT_OP_AGET_OBJECT: /* 0x46 */
11823/* File: armv5te/alt_stub.S */
11824/*
11825 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11826 * any interesting requests and then jump to the real instruction
11827 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11828 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11829 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11830 * bail to the real handler if breakFlags==0.
11831 */
11832    ldrb   r3, [rSELF, #offThread_breakFlags]
11833    adrl   lr, dvmAsmInstructionStart + (70 * 64)
11834    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11835    cmp    r3, #0
11836    bxeq   lr                   @ nothing to do - jump to real handler
11837    EXPORT_PC()
11838    mov    r0, rPC              @ arg0
11839    mov    r1, rFP              @ arg1
11840    mov    r2, rSELF            @ arg2
11841    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11842
11843/* ------------------------------ */
11844    .balign 64
11845.L_ALT_OP_AGET_BOOLEAN: /* 0x47 */
11846/* File: armv5te/alt_stub.S */
11847/*
11848 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11849 * any interesting requests and then jump to the real instruction
11850 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11851 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11852 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11853 * bail to the real handler if breakFlags==0.
11854 */
11855    ldrb   r3, [rSELF, #offThread_breakFlags]
11856    adrl   lr, dvmAsmInstructionStart + (71 * 64)
11857    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11858    cmp    r3, #0
11859    bxeq   lr                   @ nothing to do - jump to real handler
11860    EXPORT_PC()
11861    mov    r0, rPC              @ arg0
11862    mov    r1, rFP              @ arg1
11863    mov    r2, rSELF            @ arg2
11864    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11865
11866/* ------------------------------ */
11867    .balign 64
11868.L_ALT_OP_AGET_BYTE: /* 0x48 */
11869/* File: armv5te/alt_stub.S */
11870/*
11871 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11872 * any interesting requests and then jump to the real instruction
11873 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11874 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11875 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11876 * bail to the real handler if breakFlags==0.
11877 */
11878    ldrb   r3, [rSELF, #offThread_breakFlags]
11879    adrl   lr, dvmAsmInstructionStart + (72 * 64)
11880    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11881    cmp    r3, #0
11882    bxeq   lr                   @ nothing to do - jump to real handler
11883    EXPORT_PC()
11884    mov    r0, rPC              @ arg0
11885    mov    r1, rFP              @ arg1
11886    mov    r2, rSELF            @ arg2
11887    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11888
11889/* ------------------------------ */
11890    .balign 64
11891.L_ALT_OP_AGET_CHAR: /* 0x49 */
11892/* File: armv5te/alt_stub.S */
11893/*
11894 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11895 * any interesting requests and then jump to the real instruction
11896 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11897 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11898 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11899 * bail to the real handler if breakFlags==0.
11900 */
11901    ldrb   r3, [rSELF, #offThread_breakFlags]
11902    adrl   lr, dvmAsmInstructionStart + (73 * 64)
11903    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11904    cmp    r3, #0
11905    bxeq   lr                   @ nothing to do - jump to real handler
11906    EXPORT_PC()
11907    mov    r0, rPC              @ arg0
11908    mov    r1, rFP              @ arg1
11909    mov    r2, rSELF            @ arg2
11910    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11911
11912/* ------------------------------ */
11913    .balign 64
11914.L_ALT_OP_AGET_SHORT: /* 0x4a */
11915/* File: armv5te/alt_stub.S */
11916/*
11917 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11918 * any interesting requests and then jump to the real instruction
11919 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11920 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11921 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11922 * bail to the real handler if breakFlags==0.
11923 */
11924    ldrb   r3, [rSELF, #offThread_breakFlags]
11925    adrl   lr, dvmAsmInstructionStart + (74 * 64)
11926    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11927    cmp    r3, #0
11928    bxeq   lr                   @ nothing to do - jump to real handler
11929    EXPORT_PC()
11930    mov    r0, rPC              @ arg0
11931    mov    r1, rFP              @ arg1
11932    mov    r2, rSELF            @ arg2
11933    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11934
11935/* ------------------------------ */
11936    .balign 64
11937.L_ALT_OP_APUT: /* 0x4b */
11938/* File: armv5te/alt_stub.S */
11939/*
11940 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11941 * any interesting requests and then jump to the real instruction
11942 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11943 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11944 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11945 * bail to the real handler if breakFlags==0.
11946 */
11947    ldrb   r3, [rSELF, #offThread_breakFlags]
11948    adrl   lr, dvmAsmInstructionStart + (75 * 64)
11949    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11950    cmp    r3, #0
11951    bxeq   lr                   @ nothing to do - jump to real handler
11952    EXPORT_PC()
11953    mov    r0, rPC              @ arg0
11954    mov    r1, rFP              @ arg1
11955    mov    r2, rSELF            @ arg2
11956    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11957
11958/* ------------------------------ */
11959    .balign 64
11960.L_ALT_OP_APUT_WIDE: /* 0x4c */
11961/* File: armv5te/alt_stub.S */
11962/*
11963 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11964 * any interesting requests and then jump to the real instruction
11965 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11966 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11967 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11968 * bail to the real handler if breakFlags==0.
11969 */
11970    ldrb   r3, [rSELF, #offThread_breakFlags]
11971    adrl   lr, dvmAsmInstructionStart + (76 * 64)
11972    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11973    cmp    r3, #0
11974    bxeq   lr                   @ nothing to do - jump to real handler
11975    EXPORT_PC()
11976    mov    r0, rPC              @ arg0
11977    mov    r1, rFP              @ arg1
11978    mov    r2, rSELF            @ arg2
11979    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
11980
11981/* ------------------------------ */
11982    .balign 64
11983.L_ALT_OP_APUT_OBJECT: /* 0x4d */
11984/* File: armv5te/alt_stub.S */
11985/*
11986 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
11987 * any interesting requests and then jump to the real instruction
11988 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
11989 * rIBASE updates won't be seen until a refresh, and we can tell we have a
11990 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
11991 * bail to the real handler if breakFlags==0.
11992 */
11993    ldrb   r3, [rSELF, #offThread_breakFlags]
11994    adrl   lr, dvmAsmInstructionStart + (77 * 64)
11995    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
11996    cmp    r3, #0
11997    bxeq   lr                   @ nothing to do - jump to real handler
11998    EXPORT_PC()
11999    mov    r0, rPC              @ arg0
12000    mov    r1, rFP              @ arg1
12001    mov    r2, rSELF            @ arg2
12002    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12003
12004/* ------------------------------ */
12005    .balign 64
12006.L_ALT_OP_APUT_BOOLEAN: /* 0x4e */
12007/* File: armv5te/alt_stub.S */
12008/*
12009 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12010 * any interesting requests and then jump to the real instruction
12011 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12012 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12013 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12014 * bail to the real handler if breakFlags==0.
12015 */
12016    ldrb   r3, [rSELF, #offThread_breakFlags]
12017    adrl   lr, dvmAsmInstructionStart + (78 * 64)
12018    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12019    cmp    r3, #0
12020    bxeq   lr                   @ nothing to do - jump to real handler
12021    EXPORT_PC()
12022    mov    r0, rPC              @ arg0
12023    mov    r1, rFP              @ arg1
12024    mov    r2, rSELF            @ arg2
12025    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12026
12027/* ------------------------------ */
12028    .balign 64
12029.L_ALT_OP_APUT_BYTE: /* 0x4f */
12030/* File: armv5te/alt_stub.S */
12031/*
12032 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12033 * any interesting requests and then jump to the real instruction
12034 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12035 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12036 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12037 * bail to the real handler if breakFlags==0.
12038 */
12039    ldrb   r3, [rSELF, #offThread_breakFlags]
12040    adrl   lr, dvmAsmInstructionStart + (79 * 64)
12041    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12042    cmp    r3, #0
12043    bxeq   lr                   @ nothing to do - jump to real handler
12044    EXPORT_PC()
12045    mov    r0, rPC              @ arg0
12046    mov    r1, rFP              @ arg1
12047    mov    r2, rSELF            @ arg2
12048    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12049
12050/* ------------------------------ */
12051    .balign 64
12052.L_ALT_OP_APUT_CHAR: /* 0x50 */
12053/* File: armv5te/alt_stub.S */
12054/*
12055 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12056 * any interesting requests and then jump to the real instruction
12057 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12058 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12059 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12060 * bail to the real handler if breakFlags==0.
12061 */
12062    ldrb   r3, [rSELF, #offThread_breakFlags]
12063    adrl   lr, dvmAsmInstructionStart + (80 * 64)
12064    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12065    cmp    r3, #0
12066    bxeq   lr                   @ nothing to do - jump to real handler
12067    EXPORT_PC()
12068    mov    r0, rPC              @ arg0
12069    mov    r1, rFP              @ arg1
12070    mov    r2, rSELF            @ arg2
12071    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12072
12073/* ------------------------------ */
12074    .balign 64
12075.L_ALT_OP_APUT_SHORT: /* 0x51 */
12076/* File: armv5te/alt_stub.S */
12077/*
12078 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12079 * any interesting requests and then jump to the real instruction
12080 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12081 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12082 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12083 * bail to the real handler if breakFlags==0.
12084 */
12085    ldrb   r3, [rSELF, #offThread_breakFlags]
12086    adrl   lr, dvmAsmInstructionStart + (81 * 64)
12087    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12088    cmp    r3, #0
12089    bxeq   lr                   @ nothing to do - jump to real handler
12090    EXPORT_PC()
12091    mov    r0, rPC              @ arg0
12092    mov    r1, rFP              @ arg1
12093    mov    r2, rSELF            @ arg2
12094    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12095
12096/* ------------------------------ */
12097    .balign 64
12098.L_ALT_OP_IGET: /* 0x52 */
12099/* File: armv5te/alt_stub.S */
12100/*
12101 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12102 * any interesting requests and then jump to the real instruction
12103 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12104 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12105 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12106 * bail to the real handler if breakFlags==0.
12107 */
12108    ldrb   r3, [rSELF, #offThread_breakFlags]
12109    adrl   lr, dvmAsmInstructionStart + (82 * 64)
12110    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12111    cmp    r3, #0
12112    bxeq   lr                   @ nothing to do - jump to real handler
12113    EXPORT_PC()
12114    mov    r0, rPC              @ arg0
12115    mov    r1, rFP              @ arg1
12116    mov    r2, rSELF            @ arg2
12117    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12118
12119/* ------------------------------ */
12120    .balign 64
12121.L_ALT_OP_IGET_WIDE: /* 0x53 */
12122/* File: armv5te/alt_stub.S */
12123/*
12124 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12125 * any interesting requests and then jump to the real instruction
12126 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12127 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12128 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12129 * bail to the real handler if breakFlags==0.
12130 */
12131    ldrb   r3, [rSELF, #offThread_breakFlags]
12132    adrl   lr, dvmAsmInstructionStart + (83 * 64)
12133    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12134    cmp    r3, #0
12135    bxeq   lr                   @ nothing to do - jump to real handler
12136    EXPORT_PC()
12137    mov    r0, rPC              @ arg0
12138    mov    r1, rFP              @ arg1
12139    mov    r2, rSELF            @ arg2
12140    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12141
12142/* ------------------------------ */
12143    .balign 64
12144.L_ALT_OP_IGET_OBJECT: /* 0x54 */
12145/* File: armv5te/alt_stub.S */
12146/*
12147 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12148 * any interesting requests and then jump to the real instruction
12149 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12150 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12151 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12152 * bail to the real handler if breakFlags==0.
12153 */
12154    ldrb   r3, [rSELF, #offThread_breakFlags]
12155    adrl   lr, dvmAsmInstructionStart + (84 * 64)
12156    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12157    cmp    r3, #0
12158    bxeq   lr                   @ nothing to do - jump to real handler
12159    EXPORT_PC()
12160    mov    r0, rPC              @ arg0
12161    mov    r1, rFP              @ arg1
12162    mov    r2, rSELF            @ arg2
12163    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12164
12165/* ------------------------------ */
12166    .balign 64
12167.L_ALT_OP_IGET_BOOLEAN: /* 0x55 */
12168/* File: armv5te/alt_stub.S */
12169/*
12170 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12171 * any interesting requests and then jump to the real instruction
12172 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12173 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12174 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12175 * bail to the real handler if breakFlags==0.
12176 */
12177    ldrb   r3, [rSELF, #offThread_breakFlags]
12178    adrl   lr, dvmAsmInstructionStart + (85 * 64)
12179    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12180    cmp    r3, #0
12181    bxeq   lr                   @ nothing to do - jump to real handler
12182    EXPORT_PC()
12183    mov    r0, rPC              @ arg0
12184    mov    r1, rFP              @ arg1
12185    mov    r2, rSELF            @ arg2
12186    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12187
12188/* ------------------------------ */
12189    .balign 64
12190.L_ALT_OP_IGET_BYTE: /* 0x56 */
12191/* File: armv5te/alt_stub.S */
12192/*
12193 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12194 * any interesting requests and then jump to the real instruction
12195 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12196 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12197 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12198 * bail to the real handler if breakFlags==0.
12199 */
12200    ldrb   r3, [rSELF, #offThread_breakFlags]
12201    adrl   lr, dvmAsmInstructionStart + (86 * 64)
12202    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12203    cmp    r3, #0
12204    bxeq   lr                   @ nothing to do - jump to real handler
12205    EXPORT_PC()
12206    mov    r0, rPC              @ arg0
12207    mov    r1, rFP              @ arg1
12208    mov    r2, rSELF            @ arg2
12209    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12210
12211/* ------------------------------ */
12212    .balign 64
12213.L_ALT_OP_IGET_CHAR: /* 0x57 */
12214/* File: armv5te/alt_stub.S */
12215/*
12216 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12217 * any interesting requests and then jump to the real instruction
12218 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12219 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12220 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12221 * bail to the real handler if breakFlags==0.
12222 */
12223    ldrb   r3, [rSELF, #offThread_breakFlags]
12224    adrl   lr, dvmAsmInstructionStart + (87 * 64)
12225    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12226    cmp    r3, #0
12227    bxeq   lr                   @ nothing to do - jump to real handler
12228    EXPORT_PC()
12229    mov    r0, rPC              @ arg0
12230    mov    r1, rFP              @ arg1
12231    mov    r2, rSELF            @ arg2
12232    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12233
12234/* ------------------------------ */
12235    .balign 64
12236.L_ALT_OP_IGET_SHORT: /* 0x58 */
12237/* File: armv5te/alt_stub.S */
12238/*
12239 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12240 * any interesting requests and then jump to the real instruction
12241 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12242 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12243 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12244 * bail to the real handler if breakFlags==0.
12245 */
12246    ldrb   r3, [rSELF, #offThread_breakFlags]
12247    adrl   lr, dvmAsmInstructionStart + (88 * 64)
12248    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12249    cmp    r3, #0
12250    bxeq   lr                   @ nothing to do - jump to real handler
12251    EXPORT_PC()
12252    mov    r0, rPC              @ arg0
12253    mov    r1, rFP              @ arg1
12254    mov    r2, rSELF            @ arg2
12255    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12256
12257/* ------------------------------ */
12258    .balign 64
12259.L_ALT_OP_IPUT: /* 0x59 */
12260/* File: armv5te/alt_stub.S */
12261/*
12262 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12263 * any interesting requests and then jump to the real instruction
12264 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12265 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12266 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12267 * bail to the real handler if breakFlags==0.
12268 */
12269    ldrb   r3, [rSELF, #offThread_breakFlags]
12270    adrl   lr, dvmAsmInstructionStart + (89 * 64)
12271    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12272    cmp    r3, #0
12273    bxeq   lr                   @ nothing to do - jump to real handler
12274    EXPORT_PC()
12275    mov    r0, rPC              @ arg0
12276    mov    r1, rFP              @ arg1
12277    mov    r2, rSELF            @ arg2
12278    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12279
12280/* ------------------------------ */
12281    .balign 64
12282.L_ALT_OP_IPUT_WIDE: /* 0x5a */
12283/* File: armv5te/alt_stub.S */
12284/*
12285 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12286 * any interesting requests and then jump to the real instruction
12287 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12288 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12289 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12290 * bail to the real handler if breakFlags==0.
12291 */
12292    ldrb   r3, [rSELF, #offThread_breakFlags]
12293    adrl   lr, dvmAsmInstructionStart + (90 * 64)
12294    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12295    cmp    r3, #0
12296    bxeq   lr                   @ nothing to do - jump to real handler
12297    EXPORT_PC()
12298    mov    r0, rPC              @ arg0
12299    mov    r1, rFP              @ arg1
12300    mov    r2, rSELF            @ arg2
12301    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12302
12303/* ------------------------------ */
12304    .balign 64
12305.L_ALT_OP_IPUT_OBJECT: /* 0x5b */
12306/* File: armv5te/alt_stub.S */
12307/*
12308 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12309 * any interesting requests and then jump to the real instruction
12310 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12311 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12312 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12313 * bail to the real handler if breakFlags==0.
12314 */
12315    ldrb   r3, [rSELF, #offThread_breakFlags]
12316    adrl   lr, dvmAsmInstructionStart + (91 * 64)
12317    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12318    cmp    r3, #0
12319    bxeq   lr                   @ nothing to do - jump to real handler
12320    EXPORT_PC()
12321    mov    r0, rPC              @ arg0
12322    mov    r1, rFP              @ arg1
12323    mov    r2, rSELF            @ arg2
12324    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12325
12326/* ------------------------------ */
12327    .balign 64
12328.L_ALT_OP_IPUT_BOOLEAN: /* 0x5c */
12329/* File: armv5te/alt_stub.S */
12330/*
12331 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12332 * any interesting requests and then jump to the real instruction
12333 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12334 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12335 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12336 * bail to the real handler if breakFlags==0.
12337 */
12338    ldrb   r3, [rSELF, #offThread_breakFlags]
12339    adrl   lr, dvmAsmInstructionStart + (92 * 64)
12340    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12341    cmp    r3, #0
12342    bxeq   lr                   @ nothing to do - jump to real handler
12343    EXPORT_PC()
12344    mov    r0, rPC              @ arg0
12345    mov    r1, rFP              @ arg1
12346    mov    r2, rSELF            @ arg2
12347    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12348
12349/* ------------------------------ */
12350    .balign 64
12351.L_ALT_OP_IPUT_BYTE: /* 0x5d */
12352/* File: armv5te/alt_stub.S */
12353/*
12354 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12355 * any interesting requests and then jump to the real instruction
12356 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12357 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12358 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12359 * bail to the real handler if breakFlags==0.
12360 */
12361    ldrb   r3, [rSELF, #offThread_breakFlags]
12362    adrl   lr, dvmAsmInstructionStart + (93 * 64)
12363    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12364    cmp    r3, #0
12365    bxeq   lr                   @ nothing to do - jump to real handler
12366    EXPORT_PC()
12367    mov    r0, rPC              @ arg0
12368    mov    r1, rFP              @ arg1
12369    mov    r2, rSELF            @ arg2
12370    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12371
12372/* ------------------------------ */
12373    .balign 64
12374.L_ALT_OP_IPUT_CHAR: /* 0x5e */
12375/* File: armv5te/alt_stub.S */
12376/*
12377 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12378 * any interesting requests and then jump to the real instruction
12379 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12380 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12381 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12382 * bail to the real handler if breakFlags==0.
12383 */
12384    ldrb   r3, [rSELF, #offThread_breakFlags]
12385    adrl   lr, dvmAsmInstructionStart + (94 * 64)
12386    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12387    cmp    r3, #0
12388    bxeq   lr                   @ nothing to do - jump to real handler
12389    EXPORT_PC()
12390    mov    r0, rPC              @ arg0
12391    mov    r1, rFP              @ arg1
12392    mov    r2, rSELF            @ arg2
12393    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12394
12395/* ------------------------------ */
12396    .balign 64
12397.L_ALT_OP_IPUT_SHORT: /* 0x5f */
12398/* File: armv5te/alt_stub.S */
12399/*
12400 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12401 * any interesting requests and then jump to the real instruction
12402 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12403 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12404 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12405 * bail to the real handler if breakFlags==0.
12406 */
12407    ldrb   r3, [rSELF, #offThread_breakFlags]
12408    adrl   lr, dvmAsmInstructionStart + (95 * 64)
12409    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12410    cmp    r3, #0
12411    bxeq   lr                   @ nothing to do - jump to real handler
12412    EXPORT_PC()
12413    mov    r0, rPC              @ arg0
12414    mov    r1, rFP              @ arg1
12415    mov    r2, rSELF            @ arg2
12416    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12417
12418/* ------------------------------ */
12419    .balign 64
12420.L_ALT_OP_SGET: /* 0x60 */
12421/* File: armv5te/alt_stub.S */
12422/*
12423 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12424 * any interesting requests and then jump to the real instruction
12425 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12426 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12427 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12428 * bail to the real handler if breakFlags==0.
12429 */
12430    ldrb   r3, [rSELF, #offThread_breakFlags]
12431    adrl   lr, dvmAsmInstructionStart + (96 * 64)
12432    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12433    cmp    r3, #0
12434    bxeq   lr                   @ nothing to do - jump to real handler
12435    EXPORT_PC()
12436    mov    r0, rPC              @ arg0
12437    mov    r1, rFP              @ arg1
12438    mov    r2, rSELF            @ arg2
12439    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12440
12441/* ------------------------------ */
12442    .balign 64
12443.L_ALT_OP_SGET_WIDE: /* 0x61 */
12444/* File: armv5te/alt_stub.S */
12445/*
12446 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12447 * any interesting requests and then jump to the real instruction
12448 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12449 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12450 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12451 * bail to the real handler if breakFlags==0.
12452 */
12453    ldrb   r3, [rSELF, #offThread_breakFlags]
12454    adrl   lr, dvmAsmInstructionStart + (97 * 64)
12455    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12456    cmp    r3, #0
12457    bxeq   lr                   @ nothing to do - jump to real handler
12458    EXPORT_PC()
12459    mov    r0, rPC              @ arg0
12460    mov    r1, rFP              @ arg1
12461    mov    r2, rSELF            @ arg2
12462    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12463
12464/* ------------------------------ */
12465    .balign 64
12466.L_ALT_OP_SGET_OBJECT: /* 0x62 */
12467/* File: armv5te/alt_stub.S */
12468/*
12469 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12470 * any interesting requests and then jump to the real instruction
12471 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12472 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12473 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12474 * bail to the real handler if breakFlags==0.
12475 */
12476    ldrb   r3, [rSELF, #offThread_breakFlags]
12477    adrl   lr, dvmAsmInstructionStart + (98 * 64)
12478    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12479    cmp    r3, #0
12480    bxeq   lr                   @ nothing to do - jump to real handler
12481    EXPORT_PC()
12482    mov    r0, rPC              @ arg0
12483    mov    r1, rFP              @ arg1
12484    mov    r2, rSELF            @ arg2
12485    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12486
12487/* ------------------------------ */
12488    .balign 64
12489.L_ALT_OP_SGET_BOOLEAN: /* 0x63 */
12490/* File: armv5te/alt_stub.S */
12491/*
12492 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12493 * any interesting requests and then jump to the real instruction
12494 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12495 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12496 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12497 * bail to the real handler if breakFlags==0.
12498 */
12499    ldrb   r3, [rSELF, #offThread_breakFlags]
12500    adrl   lr, dvmAsmInstructionStart + (99 * 64)
12501    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12502    cmp    r3, #0
12503    bxeq   lr                   @ nothing to do - jump to real handler
12504    EXPORT_PC()
12505    mov    r0, rPC              @ arg0
12506    mov    r1, rFP              @ arg1
12507    mov    r2, rSELF            @ arg2
12508    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12509
12510/* ------------------------------ */
12511    .balign 64
12512.L_ALT_OP_SGET_BYTE: /* 0x64 */
12513/* File: armv5te/alt_stub.S */
12514/*
12515 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12516 * any interesting requests and then jump to the real instruction
12517 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12518 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12519 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12520 * bail to the real handler if breakFlags==0.
12521 */
12522    ldrb   r3, [rSELF, #offThread_breakFlags]
12523    adrl   lr, dvmAsmInstructionStart + (100 * 64)
12524    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12525    cmp    r3, #0
12526    bxeq   lr                   @ nothing to do - jump to real handler
12527    EXPORT_PC()
12528    mov    r0, rPC              @ arg0
12529    mov    r1, rFP              @ arg1
12530    mov    r2, rSELF            @ arg2
12531    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12532
12533/* ------------------------------ */
12534    .balign 64
12535.L_ALT_OP_SGET_CHAR: /* 0x65 */
12536/* File: armv5te/alt_stub.S */
12537/*
12538 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12539 * any interesting requests and then jump to the real instruction
12540 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12541 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12542 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12543 * bail to the real handler if breakFlags==0.
12544 */
12545    ldrb   r3, [rSELF, #offThread_breakFlags]
12546    adrl   lr, dvmAsmInstructionStart + (101 * 64)
12547    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12548    cmp    r3, #0
12549    bxeq   lr                   @ nothing to do - jump to real handler
12550    EXPORT_PC()
12551    mov    r0, rPC              @ arg0
12552    mov    r1, rFP              @ arg1
12553    mov    r2, rSELF            @ arg2
12554    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12555
12556/* ------------------------------ */
12557    .balign 64
12558.L_ALT_OP_SGET_SHORT: /* 0x66 */
12559/* File: armv5te/alt_stub.S */
12560/*
12561 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12562 * any interesting requests and then jump to the real instruction
12563 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12564 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12565 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12566 * bail to the real handler if breakFlags==0.
12567 */
12568    ldrb   r3, [rSELF, #offThread_breakFlags]
12569    adrl   lr, dvmAsmInstructionStart + (102 * 64)
12570    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12571    cmp    r3, #0
12572    bxeq   lr                   @ nothing to do - jump to real handler
12573    EXPORT_PC()
12574    mov    r0, rPC              @ arg0
12575    mov    r1, rFP              @ arg1
12576    mov    r2, rSELF            @ arg2
12577    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12578
12579/* ------------------------------ */
12580    .balign 64
12581.L_ALT_OP_SPUT: /* 0x67 */
12582/* File: armv5te/alt_stub.S */
12583/*
12584 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12585 * any interesting requests and then jump to the real instruction
12586 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12587 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12588 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12589 * bail to the real handler if breakFlags==0.
12590 */
12591    ldrb   r3, [rSELF, #offThread_breakFlags]
12592    adrl   lr, dvmAsmInstructionStart + (103 * 64)
12593    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12594    cmp    r3, #0
12595    bxeq   lr                   @ nothing to do - jump to real handler
12596    EXPORT_PC()
12597    mov    r0, rPC              @ arg0
12598    mov    r1, rFP              @ arg1
12599    mov    r2, rSELF            @ arg2
12600    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12601
12602/* ------------------------------ */
12603    .balign 64
12604.L_ALT_OP_SPUT_WIDE: /* 0x68 */
12605/* File: armv5te/alt_stub.S */
12606/*
12607 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12608 * any interesting requests and then jump to the real instruction
12609 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12610 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12611 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12612 * bail to the real handler if breakFlags==0.
12613 */
12614    ldrb   r3, [rSELF, #offThread_breakFlags]
12615    adrl   lr, dvmAsmInstructionStart + (104 * 64)
12616    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12617    cmp    r3, #0
12618    bxeq   lr                   @ nothing to do - jump to real handler
12619    EXPORT_PC()
12620    mov    r0, rPC              @ arg0
12621    mov    r1, rFP              @ arg1
12622    mov    r2, rSELF            @ arg2
12623    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12624
12625/* ------------------------------ */
12626    .balign 64
12627.L_ALT_OP_SPUT_OBJECT: /* 0x69 */
12628/* File: armv5te/alt_stub.S */
12629/*
12630 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12631 * any interesting requests and then jump to the real instruction
12632 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12633 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12634 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12635 * bail to the real handler if breakFlags==0.
12636 */
12637    ldrb   r3, [rSELF, #offThread_breakFlags]
12638    adrl   lr, dvmAsmInstructionStart + (105 * 64)
12639    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12640    cmp    r3, #0
12641    bxeq   lr                   @ nothing to do - jump to real handler
12642    EXPORT_PC()
12643    mov    r0, rPC              @ arg0
12644    mov    r1, rFP              @ arg1
12645    mov    r2, rSELF            @ arg2
12646    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12647
12648/* ------------------------------ */
12649    .balign 64
12650.L_ALT_OP_SPUT_BOOLEAN: /* 0x6a */
12651/* File: armv5te/alt_stub.S */
12652/*
12653 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12654 * any interesting requests and then jump to the real instruction
12655 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12656 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12657 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12658 * bail to the real handler if breakFlags==0.
12659 */
12660    ldrb   r3, [rSELF, #offThread_breakFlags]
12661    adrl   lr, dvmAsmInstructionStart + (106 * 64)
12662    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12663    cmp    r3, #0
12664    bxeq   lr                   @ nothing to do - jump to real handler
12665    EXPORT_PC()
12666    mov    r0, rPC              @ arg0
12667    mov    r1, rFP              @ arg1
12668    mov    r2, rSELF            @ arg2
12669    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12670
12671/* ------------------------------ */
12672    .balign 64
12673.L_ALT_OP_SPUT_BYTE: /* 0x6b */
12674/* File: armv5te/alt_stub.S */
12675/*
12676 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12677 * any interesting requests and then jump to the real instruction
12678 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12679 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12680 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12681 * bail to the real handler if breakFlags==0.
12682 */
12683    ldrb   r3, [rSELF, #offThread_breakFlags]
12684    adrl   lr, dvmAsmInstructionStart + (107 * 64)
12685    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12686    cmp    r3, #0
12687    bxeq   lr                   @ nothing to do - jump to real handler
12688    EXPORT_PC()
12689    mov    r0, rPC              @ arg0
12690    mov    r1, rFP              @ arg1
12691    mov    r2, rSELF            @ arg2
12692    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12693
12694/* ------------------------------ */
12695    .balign 64
12696.L_ALT_OP_SPUT_CHAR: /* 0x6c */
12697/* File: armv5te/alt_stub.S */
12698/*
12699 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12700 * any interesting requests and then jump to the real instruction
12701 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12702 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12703 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12704 * bail to the real handler if breakFlags==0.
12705 */
12706    ldrb   r3, [rSELF, #offThread_breakFlags]
12707    adrl   lr, dvmAsmInstructionStart + (108 * 64)
12708    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12709    cmp    r3, #0
12710    bxeq   lr                   @ nothing to do - jump to real handler
12711    EXPORT_PC()
12712    mov    r0, rPC              @ arg0
12713    mov    r1, rFP              @ arg1
12714    mov    r2, rSELF            @ arg2
12715    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12716
12717/* ------------------------------ */
12718    .balign 64
12719.L_ALT_OP_SPUT_SHORT: /* 0x6d */
12720/* File: armv5te/alt_stub.S */
12721/*
12722 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12723 * any interesting requests and then jump to the real instruction
12724 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12725 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12726 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12727 * bail to the real handler if breakFlags==0.
12728 */
12729    ldrb   r3, [rSELF, #offThread_breakFlags]
12730    adrl   lr, dvmAsmInstructionStart + (109 * 64)
12731    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12732    cmp    r3, #0
12733    bxeq   lr                   @ nothing to do - jump to real handler
12734    EXPORT_PC()
12735    mov    r0, rPC              @ arg0
12736    mov    r1, rFP              @ arg1
12737    mov    r2, rSELF            @ arg2
12738    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12739
12740/* ------------------------------ */
12741    .balign 64
12742.L_ALT_OP_INVOKE_VIRTUAL: /* 0x6e */
12743/* File: armv5te/alt_stub.S */
12744/*
12745 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12746 * any interesting requests and then jump to the real instruction
12747 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12748 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12749 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12750 * bail to the real handler if breakFlags==0.
12751 */
12752    ldrb   r3, [rSELF, #offThread_breakFlags]
12753    adrl   lr, dvmAsmInstructionStart + (110 * 64)
12754    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12755    cmp    r3, #0
12756    bxeq   lr                   @ nothing to do - jump to real handler
12757    EXPORT_PC()
12758    mov    r0, rPC              @ arg0
12759    mov    r1, rFP              @ arg1
12760    mov    r2, rSELF            @ arg2
12761    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12762
12763/* ------------------------------ */
12764    .balign 64
12765.L_ALT_OP_INVOKE_SUPER: /* 0x6f */
12766/* File: armv5te/alt_stub.S */
12767/*
12768 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12769 * any interesting requests and then jump to the real instruction
12770 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12771 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12772 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12773 * bail to the real handler if breakFlags==0.
12774 */
12775    ldrb   r3, [rSELF, #offThread_breakFlags]
12776    adrl   lr, dvmAsmInstructionStart + (111 * 64)
12777    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12778    cmp    r3, #0
12779    bxeq   lr                   @ nothing to do - jump to real handler
12780    EXPORT_PC()
12781    mov    r0, rPC              @ arg0
12782    mov    r1, rFP              @ arg1
12783    mov    r2, rSELF            @ arg2
12784    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12785
12786/* ------------------------------ */
12787    .balign 64
12788.L_ALT_OP_INVOKE_DIRECT: /* 0x70 */
12789/* File: armv5te/alt_stub.S */
12790/*
12791 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12792 * any interesting requests and then jump to the real instruction
12793 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12794 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12795 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12796 * bail to the real handler if breakFlags==0.
12797 */
12798    ldrb   r3, [rSELF, #offThread_breakFlags]
12799    adrl   lr, dvmAsmInstructionStart + (112 * 64)
12800    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12801    cmp    r3, #0
12802    bxeq   lr                   @ nothing to do - jump to real handler
12803    EXPORT_PC()
12804    mov    r0, rPC              @ arg0
12805    mov    r1, rFP              @ arg1
12806    mov    r2, rSELF            @ arg2
12807    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12808
12809/* ------------------------------ */
12810    .balign 64
12811.L_ALT_OP_INVOKE_STATIC: /* 0x71 */
12812/* File: armv5te/alt_stub.S */
12813/*
12814 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12815 * any interesting requests and then jump to the real instruction
12816 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12817 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12818 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12819 * bail to the real handler if breakFlags==0.
12820 */
12821    ldrb   r3, [rSELF, #offThread_breakFlags]
12822    adrl   lr, dvmAsmInstructionStart + (113 * 64)
12823    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12824    cmp    r3, #0
12825    bxeq   lr                   @ nothing to do - jump to real handler
12826    EXPORT_PC()
12827    mov    r0, rPC              @ arg0
12828    mov    r1, rFP              @ arg1
12829    mov    r2, rSELF            @ arg2
12830    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12831
12832/* ------------------------------ */
12833    .balign 64
12834.L_ALT_OP_INVOKE_INTERFACE: /* 0x72 */
12835/* File: armv5te/alt_stub.S */
12836/*
12837 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12838 * any interesting requests and then jump to the real instruction
12839 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12840 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12841 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12842 * bail to the real handler if breakFlags==0.
12843 */
12844    ldrb   r3, [rSELF, #offThread_breakFlags]
12845    adrl   lr, dvmAsmInstructionStart + (114 * 64)
12846    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12847    cmp    r3, #0
12848    bxeq   lr                   @ nothing to do - jump to real handler
12849    EXPORT_PC()
12850    mov    r0, rPC              @ arg0
12851    mov    r1, rFP              @ arg1
12852    mov    r2, rSELF            @ arg2
12853    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12854
12855/* ------------------------------ */
12856    .balign 64
12857.L_ALT_OP_UNUSED_73: /* 0x73 */
12858/* File: armv5te/alt_stub.S */
12859/*
12860 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12861 * any interesting requests and then jump to the real instruction
12862 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12863 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12864 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12865 * bail to the real handler if breakFlags==0.
12866 */
12867    ldrb   r3, [rSELF, #offThread_breakFlags]
12868    adrl   lr, dvmAsmInstructionStart + (115 * 64)
12869    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12870    cmp    r3, #0
12871    bxeq   lr                   @ nothing to do - jump to real handler
12872    EXPORT_PC()
12873    mov    r0, rPC              @ arg0
12874    mov    r1, rFP              @ arg1
12875    mov    r2, rSELF            @ arg2
12876    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12877
12878/* ------------------------------ */
12879    .balign 64
12880.L_ALT_OP_INVOKE_VIRTUAL_RANGE: /* 0x74 */
12881/* File: armv5te/alt_stub.S */
12882/*
12883 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12884 * any interesting requests and then jump to the real instruction
12885 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12886 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12887 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12888 * bail to the real handler if breakFlags==0.
12889 */
12890    ldrb   r3, [rSELF, #offThread_breakFlags]
12891    adrl   lr, dvmAsmInstructionStart + (116 * 64)
12892    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12893    cmp    r3, #0
12894    bxeq   lr                   @ nothing to do - jump to real handler
12895    EXPORT_PC()
12896    mov    r0, rPC              @ arg0
12897    mov    r1, rFP              @ arg1
12898    mov    r2, rSELF            @ arg2
12899    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12900
12901/* ------------------------------ */
12902    .balign 64
12903.L_ALT_OP_INVOKE_SUPER_RANGE: /* 0x75 */
12904/* File: armv5te/alt_stub.S */
12905/*
12906 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12907 * any interesting requests and then jump to the real instruction
12908 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12909 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12910 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12911 * bail to the real handler if breakFlags==0.
12912 */
12913    ldrb   r3, [rSELF, #offThread_breakFlags]
12914    adrl   lr, dvmAsmInstructionStart + (117 * 64)
12915    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12916    cmp    r3, #0
12917    bxeq   lr                   @ nothing to do - jump to real handler
12918    EXPORT_PC()
12919    mov    r0, rPC              @ arg0
12920    mov    r1, rFP              @ arg1
12921    mov    r2, rSELF            @ arg2
12922    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12923
12924/* ------------------------------ */
12925    .balign 64
12926.L_ALT_OP_INVOKE_DIRECT_RANGE: /* 0x76 */
12927/* File: armv5te/alt_stub.S */
12928/*
12929 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12930 * any interesting requests and then jump to the real instruction
12931 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12932 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12933 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12934 * bail to the real handler if breakFlags==0.
12935 */
12936    ldrb   r3, [rSELF, #offThread_breakFlags]
12937    adrl   lr, dvmAsmInstructionStart + (118 * 64)
12938    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12939    cmp    r3, #0
12940    bxeq   lr                   @ nothing to do - jump to real handler
12941    EXPORT_PC()
12942    mov    r0, rPC              @ arg0
12943    mov    r1, rFP              @ arg1
12944    mov    r2, rSELF            @ arg2
12945    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12946
12947/* ------------------------------ */
12948    .balign 64
12949.L_ALT_OP_INVOKE_STATIC_RANGE: /* 0x77 */
12950/* File: armv5te/alt_stub.S */
12951/*
12952 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12953 * any interesting requests and then jump to the real instruction
12954 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12955 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12956 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12957 * bail to the real handler if breakFlags==0.
12958 */
12959    ldrb   r3, [rSELF, #offThread_breakFlags]
12960    adrl   lr, dvmAsmInstructionStart + (119 * 64)
12961    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12962    cmp    r3, #0
12963    bxeq   lr                   @ nothing to do - jump to real handler
12964    EXPORT_PC()
12965    mov    r0, rPC              @ arg0
12966    mov    r1, rFP              @ arg1
12967    mov    r2, rSELF            @ arg2
12968    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12969
12970/* ------------------------------ */
12971    .balign 64
12972.L_ALT_OP_INVOKE_INTERFACE_RANGE: /* 0x78 */
12973/* File: armv5te/alt_stub.S */
12974/*
12975 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12976 * any interesting requests and then jump to the real instruction
12977 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
12978 * rIBASE updates won't be seen until a refresh, and we can tell we have a
12979 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
12980 * bail to the real handler if breakFlags==0.
12981 */
12982    ldrb   r3, [rSELF, #offThread_breakFlags]
12983    adrl   lr, dvmAsmInstructionStart + (120 * 64)
12984    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
12985    cmp    r3, #0
12986    bxeq   lr                   @ nothing to do - jump to real handler
12987    EXPORT_PC()
12988    mov    r0, rPC              @ arg0
12989    mov    r1, rFP              @ arg1
12990    mov    r2, rSELF            @ arg2
12991    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
12992
12993/* ------------------------------ */
12994    .balign 64
12995.L_ALT_OP_UNUSED_79: /* 0x79 */
12996/* File: armv5te/alt_stub.S */
12997/*
12998 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
12999 * any interesting requests and then jump to the real instruction
13000 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13001 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13002 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13003 * bail to the real handler if breakFlags==0.
13004 */
13005    ldrb   r3, [rSELF, #offThread_breakFlags]
13006    adrl   lr, dvmAsmInstructionStart + (121 * 64)
13007    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13008    cmp    r3, #0
13009    bxeq   lr                   @ nothing to do - jump to real handler
13010    EXPORT_PC()
13011    mov    r0, rPC              @ arg0
13012    mov    r1, rFP              @ arg1
13013    mov    r2, rSELF            @ arg2
13014    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13015
13016/* ------------------------------ */
13017    .balign 64
13018.L_ALT_OP_UNUSED_7A: /* 0x7a */
13019/* File: armv5te/alt_stub.S */
13020/*
13021 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13022 * any interesting requests and then jump to the real instruction
13023 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13024 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13025 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13026 * bail to the real handler if breakFlags==0.
13027 */
13028    ldrb   r3, [rSELF, #offThread_breakFlags]
13029    adrl   lr, dvmAsmInstructionStart + (122 * 64)
13030    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13031    cmp    r3, #0
13032    bxeq   lr                   @ nothing to do - jump to real handler
13033    EXPORT_PC()
13034    mov    r0, rPC              @ arg0
13035    mov    r1, rFP              @ arg1
13036    mov    r2, rSELF            @ arg2
13037    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13038
13039/* ------------------------------ */
13040    .balign 64
13041.L_ALT_OP_NEG_INT: /* 0x7b */
13042/* File: armv5te/alt_stub.S */
13043/*
13044 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13045 * any interesting requests and then jump to the real instruction
13046 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13047 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13048 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13049 * bail to the real handler if breakFlags==0.
13050 */
13051    ldrb   r3, [rSELF, #offThread_breakFlags]
13052    adrl   lr, dvmAsmInstructionStart + (123 * 64)
13053    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13054    cmp    r3, #0
13055    bxeq   lr                   @ nothing to do - jump to real handler
13056    EXPORT_PC()
13057    mov    r0, rPC              @ arg0
13058    mov    r1, rFP              @ arg1
13059    mov    r2, rSELF            @ arg2
13060    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13061
13062/* ------------------------------ */
13063    .balign 64
13064.L_ALT_OP_NOT_INT: /* 0x7c */
13065/* File: armv5te/alt_stub.S */
13066/*
13067 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13068 * any interesting requests and then jump to the real instruction
13069 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13070 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13071 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13072 * bail to the real handler if breakFlags==0.
13073 */
13074    ldrb   r3, [rSELF, #offThread_breakFlags]
13075    adrl   lr, dvmAsmInstructionStart + (124 * 64)
13076    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13077    cmp    r3, #0
13078    bxeq   lr                   @ nothing to do - jump to real handler
13079    EXPORT_PC()
13080    mov    r0, rPC              @ arg0
13081    mov    r1, rFP              @ arg1
13082    mov    r2, rSELF            @ arg2
13083    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13084
13085/* ------------------------------ */
13086    .balign 64
13087.L_ALT_OP_NEG_LONG: /* 0x7d */
13088/* File: armv5te/alt_stub.S */
13089/*
13090 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13091 * any interesting requests and then jump to the real instruction
13092 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13093 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13094 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13095 * bail to the real handler if breakFlags==0.
13096 */
13097    ldrb   r3, [rSELF, #offThread_breakFlags]
13098    adrl   lr, dvmAsmInstructionStart + (125 * 64)
13099    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13100    cmp    r3, #0
13101    bxeq   lr                   @ nothing to do - jump to real handler
13102    EXPORT_PC()
13103    mov    r0, rPC              @ arg0
13104    mov    r1, rFP              @ arg1
13105    mov    r2, rSELF            @ arg2
13106    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13107
13108/* ------------------------------ */
13109    .balign 64
13110.L_ALT_OP_NOT_LONG: /* 0x7e */
13111/* File: armv5te/alt_stub.S */
13112/*
13113 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13114 * any interesting requests and then jump to the real instruction
13115 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13116 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13117 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13118 * bail to the real handler if breakFlags==0.
13119 */
13120    ldrb   r3, [rSELF, #offThread_breakFlags]
13121    adrl   lr, dvmAsmInstructionStart + (126 * 64)
13122    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13123    cmp    r3, #0
13124    bxeq   lr                   @ nothing to do - jump to real handler
13125    EXPORT_PC()
13126    mov    r0, rPC              @ arg0
13127    mov    r1, rFP              @ arg1
13128    mov    r2, rSELF            @ arg2
13129    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13130
13131/* ------------------------------ */
13132    .balign 64
13133.L_ALT_OP_NEG_FLOAT: /* 0x7f */
13134/* File: armv5te/alt_stub.S */
13135/*
13136 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13137 * any interesting requests and then jump to the real instruction
13138 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13139 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13140 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13141 * bail to the real handler if breakFlags==0.
13142 */
13143    ldrb   r3, [rSELF, #offThread_breakFlags]
13144    adrl   lr, dvmAsmInstructionStart + (127 * 64)
13145    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13146    cmp    r3, #0
13147    bxeq   lr                   @ nothing to do - jump to real handler
13148    EXPORT_PC()
13149    mov    r0, rPC              @ arg0
13150    mov    r1, rFP              @ arg1
13151    mov    r2, rSELF            @ arg2
13152    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13153
13154/* ------------------------------ */
13155    .balign 64
13156.L_ALT_OP_NEG_DOUBLE: /* 0x80 */
13157/* File: armv5te/alt_stub.S */
13158/*
13159 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13160 * any interesting requests and then jump to the real instruction
13161 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13162 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13163 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13164 * bail to the real handler if breakFlags==0.
13165 */
13166    ldrb   r3, [rSELF, #offThread_breakFlags]
13167    adrl   lr, dvmAsmInstructionStart + (128 * 64)
13168    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13169    cmp    r3, #0
13170    bxeq   lr                   @ nothing to do - jump to real handler
13171    EXPORT_PC()
13172    mov    r0, rPC              @ arg0
13173    mov    r1, rFP              @ arg1
13174    mov    r2, rSELF            @ arg2
13175    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13176
13177/* ------------------------------ */
13178    .balign 64
13179.L_ALT_OP_INT_TO_LONG: /* 0x81 */
13180/* File: armv5te/alt_stub.S */
13181/*
13182 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13183 * any interesting requests and then jump to the real instruction
13184 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13185 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13186 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13187 * bail to the real handler if breakFlags==0.
13188 */
13189    ldrb   r3, [rSELF, #offThread_breakFlags]
13190    adrl   lr, dvmAsmInstructionStart + (129 * 64)
13191    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13192    cmp    r3, #0
13193    bxeq   lr                   @ nothing to do - jump to real handler
13194    EXPORT_PC()
13195    mov    r0, rPC              @ arg0
13196    mov    r1, rFP              @ arg1
13197    mov    r2, rSELF            @ arg2
13198    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13199
13200/* ------------------------------ */
13201    .balign 64
13202.L_ALT_OP_INT_TO_FLOAT: /* 0x82 */
13203/* File: armv5te/alt_stub.S */
13204/*
13205 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13206 * any interesting requests and then jump to the real instruction
13207 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13208 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13209 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13210 * bail to the real handler if breakFlags==0.
13211 */
13212    ldrb   r3, [rSELF, #offThread_breakFlags]
13213    adrl   lr, dvmAsmInstructionStart + (130 * 64)
13214    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13215    cmp    r3, #0
13216    bxeq   lr                   @ nothing to do - jump to real handler
13217    EXPORT_PC()
13218    mov    r0, rPC              @ arg0
13219    mov    r1, rFP              @ arg1
13220    mov    r2, rSELF            @ arg2
13221    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13222
13223/* ------------------------------ */
13224    .balign 64
13225.L_ALT_OP_INT_TO_DOUBLE: /* 0x83 */
13226/* File: armv5te/alt_stub.S */
13227/*
13228 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13229 * any interesting requests and then jump to the real instruction
13230 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13231 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13232 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13233 * bail to the real handler if breakFlags==0.
13234 */
13235    ldrb   r3, [rSELF, #offThread_breakFlags]
13236    adrl   lr, dvmAsmInstructionStart + (131 * 64)
13237    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13238    cmp    r3, #0
13239    bxeq   lr                   @ nothing to do - jump to real handler
13240    EXPORT_PC()
13241    mov    r0, rPC              @ arg0
13242    mov    r1, rFP              @ arg1
13243    mov    r2, rSELF            @ arg2
13244    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13245
13246/* ------------------------------ */
13247    .balign 64
13248.L_ALT_OP_LONG_TO_INT: /* 0x84 */
13249/* File: armv5te/alt_stub.S */
13250/*
13251 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13252 * any interesting requests and then jump to the real instruction
13253 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13254 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13255 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13256 * bail to the real handler if breakFlags==0.
13257 */
13258    ldrb   r3, [rSELF, #offThread_breakFlags]
13259    adrl   lr, dvmAsmInstructionStart + (132 * 64)
13260    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13261    cmp    r3, #0
13262    bxeq   lr                   @ nothing to do - jump to real handler
13263    EXPORT_PC()
13264    mov    r0, rPC              @ arg0
13265    mov    r1, rFP              @ arg1
13266    mov    r2, rSELF            @ arg2
13267    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13268
13269/* ------------------------------ */
13270    .balign 64
13271.L_ALT_OP_LONG_TO_FLOAT: /* 0x85 */
13272/* File: armv5te/alt_stub.S */
13273/*
13274 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13275 * any interesting requests and then jump to the real instruction
13276 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13277 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13278 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13279 * bail to the real handler if breakFlags==0.
13280 */
13281    ldrb   r3, [rSELF, #offThread_breakFlags]
13282    adrl   lr, dvmAsmInstructionStart + (133 * 64)
13283    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13284    cmp    r3, #0
13285    bxeq   lr                   @ nothing to do - jump to real handler
13286    EXPORT_PC()
13287    mov    r0, rPC              @ arg0
13288    mov    r1, rFP              @ arg1
13289    mov    r2, rSELF            @ arg2
13290    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13291
13292/* ------------------------------ */
13293    .balign 64
13294.L_ALT_OP_LONG_TO_DOUBLE: /* 0x86 */
13295/* File: armv5te/alt_stub.S */
13296/*
13297 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13298 * any interesting requests and then jump to the real instruction
13299 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13300 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13301 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13302 * bail to the real handler if breakFlags==0.
13303 */
13304    ldrb   r3, [rSELF, #offThread_breakFlags]
13305    adrl   lr, dvmAsmInstructionStart + (134 * 64)
13306    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13307    cmp    r3, #0
13308    bxeq   lr                   @ nothing to do - jump to real handler
13309    EXPORT_PC()
13310    mov    r0, rPC              @ arg0
13311    mov    r1, rFP              @ arg1
13312    mov    r2, rSELF            @ arg2
13313    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13314
13315/* ------------------------------ */
13316    .balign 64
13317.L_ALT_OP_FLOAT_TO_INT: /* 0x87 */
13318/* File: armv5te/alt_stub.S */
13319/*
13320 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13321 * any interesting requests and then jump to the real instruction
13322 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13323 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13324 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13325 * bail to the real handler if breakFlags==0.
13326 */
13327    ldrb   r3, [rSELF, #offThread_breakFlags]
13328    adrl   lr, dvmAsmInstructionStart + (135 * 64)
13329    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13330    cmp    r3, #0
13331    bxeq   lr                   @ nothing to do - jump to real handler
13332    EXPORT_PC()
13333    mov    r0, rPC              @ arg0
13334    mov    r1, rFP              @ arg1
13335    mov    r2, rSELF            @ arg2
13336    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13337
13338/* ------------------------------ */
13339    .balign 64
13340.L_ALT_OP_FLOAT_TO_LONG: /* 0x88 */
13341/* File: armv5te/alt_stub.S */
13342/*
13343 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13344 * any interesting requests and then jump to the real instruction
13345 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13346 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13347 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13348 * bail to the real handler if breakFlags==0.
13349 */
13350    ldrb   r3, [rSELF, #offThread_breakFlags]
13351    adrl   lr, dvmAsmInstructionStart + (136 * 64)
13352    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13353    cmp    r3, #0
13354    bxeq   lr                   @ nothing to do - jump to real handler
13355    EXPORT_PC()
13356    mov    r0, rPC              @ arg0
13357    mov    r1, rFP              @ arg1
13358    mov    r2, rSELF            @ arg2
13359    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13360
13361/* ------------------------------ */
13362    .balign 64
13363.L_ALT_OP_FLOAT_TO_DOUBLE: /* 0x89 */
13364/* File: armv5te/alt_stub.S */
13365/*
13366 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13367 * any interesting requests and then jump to the real instruction
13368 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13369 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13370 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13371 * bail to the real handler if breakFlags==0.
13372 */
13373    ldrb   r3, [rSELF, #offThread_breakFlags]
13374    adrl   lr, dvmAsmInstructionStart + (137 * 64)
13375    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13376    cmp    r3, #0
13377    bxeq   lr                   @ nothing to do - jump to real handler
13378    EXPORT_PC()
13379    mov    r0, rPC              @ arg0
13380    mov    r1, rFP              @ arg1
13381    mov    r2, rSELF            @ arg2
13382    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13383
13384/* ------------------------------ */
13385    .balign 64
13386.L_ALT_OP_DOUBLE_TO_INT: /* 0x8a */
13387/* File: armv5te/alt_stub.S */
13388/*
13389 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13390 * any interesting requests and then jump to the real instruction
13391 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13392 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13393 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13394 * bail to the real handler if breakFlags==0.
13395 */
13396    ldrb   r3, [rSELF, #offThread_breakFlags]
13397    adrl   lr, dvmAsmInstructionStart + (138 * 64)
13398    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13399    cmp    r3, #0
13400    bxeq   lr                   @ nothing to do - jump to real handler
13401    EXPORT_PC()
13402    mov    r0, rPC              @ arg0
13403    mov    r1, rFP              @ arg1
13404    mov    r2, rSELF            @ arg2
13405    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13406
13407/* ------------------------------ */
13408    .balign 64
13409.L_ALT_OP_DOUBLE_TO_LONG: /* 0x8b */
13410/* File: armv5te/alt_stub.S */
13411/*
13412 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13413 * any interesting requests and then jump to the real instruction
13414 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13415 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13416 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13417 * bail to the real handler if breakFlags==0.
13418 */
13419    ldrb   r3, [rSELF, #offThread_breakFlags]
13420    adrl   lr, dvmAsmInstructionStart + (139 * 64)
13421    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13422    cmp    r3, #0
13423    bxeq   lr                   @ nothing to do - jump to real handler
13424    EXPORT_PC()
13425    mov    r0, rPC              @ arg0
13426    mov    r1, rFP              @ arg1
13427    mov    r2, rSELF            @ arg2
13428    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13429
13430/* ------------------------------ */
13431    .balign 64
13432.L_ALT_OP_DOUBLE_TO_FLOAT: /* 0x8c */
13433/* File: armv5te/alt_stub.S */
13434/*
13435 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13436 * any interesting requests and then jump to the real instruction
13437 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13438 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13439 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13440 * bail to the real handler if breakFlags==0.
13441 */
13442    ldrb   r3, [rSELF, #offThread_breakFlags]
13443    adrl   lr, dvmAsmInstructionStart + (140 * 64)
13444    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13445    cmp    r3, #0
13446    bxeq   lr                   @ nothing to do - jump to real handler
13447    EXPORT_PC()
13448    mov    r0, rPC              @ arg0
13449    mov    r1, rFP              @ arg1
13450    mov    r2, rSELF            @ arg2
13451    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13452
13453/* ------------------------------ */
13454    .balign 64
13455.L_ALT_OP_INT_TO_BYTE: /* 0x8d */
13456/* File: armv5te/alt_stub.S */
13457/*
13458 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13459 * any interesting requests and then jump to the real instruction
13460 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13461 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13462 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13463 * bail to the real handler if breakFlags==0.
13464 */
13465    ldrb   r3, [rSELF, #offThread_breakFlags]
13466    adrl   lr, dvmAsmInstructionStart + (141 * 64)
13467    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13468    cmp    r3, #0
13469    bxeq   lr                   @ nothing to do - jump to real handler
13470    EXPORT_PC()
13471    mov    r0, rPC              @ arg0
13472    mov    r1, rFP              @ arg1
13473    mov    r2, rSELF            @ arg2
13474    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13475
13476/* ------------------------------ */
13477    .balign 64
13478.L_ALT_OP_INT_TO_CHAR: /* 0x8e */
13479/* File: armv5te/alt_stub.S */
13480/*
13481 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13482 * any interesting requests and then jump to the real instruction
13483 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13484 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13485 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13486 * bail to the real handler if breakFlags==0.
13487 */
13488    ldrb   r3, [rSELF, #offThread_breakFlags]
13489    adrl   lr, dvmAsmInstructionStart + (142 * 64)
13490    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13491    cmp    r3, #0
13492    bxeq   lr                   @ nothing to do - jump to real handler
13493    EXPORT_PC()
13494    mov    r0, rPC              @ arg0
13495    mov    r1, rFP              @ arg1
13496    mov    r2, rSELF            @ arg2
13497    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13498
13499/* ------------------------------ */
13500    .balign 64
13501.L_ALT_OP_INT_TO_SHORT: /* 0x8f */
13502/* File: armv5te/alt_stub.S */
13503/*
13504 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13505 * any interesting requests and then jump to the real instruction
13506 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13507 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13508 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13509 * bail to the real handler if breakFlags==0.
13510 */
13511    ldrb   r3, [rSELF, #offThread_breakFlags]
13512    adrl   lr, dvmAsmInstructionStart + (143 * 64)
13513    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13514    cmp    r3, #0
13515    bxeq   lr                   @ nothing to do - jump to real handler
13516    EXPORT_PC()
13517    mov    r0, rPC              @ arg0
13518    mov    r1, rFP              @ arg1
13519    mov    r2, rSELF            @ arg2
13520    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13521
13522/* ------------------------------ */
13523    .balign 64
13524.L_ALT_OP_ADD_INT: /* 0x90 */
13525/* File: armv5te/alt_stub.S */
13526/*
13527 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13528 * any interesting requests and then jump to the real instruction
13529 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13530 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13531 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13532 * bail to the real handler if breakFlags==0.
13533 */
13534    ldrb   r3, [rSELF, #offThread_breakFlags]
13535    adrl   lr, dvmAsmInstructionStart + (144 * 64)
13536    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13537    cmp    r3, #0
13538    bxeq   lr                   @ nothing to do - jump to real handler
13539    EXPORT_PC()
13540    mov    r0, rPC              @ arg0
13541    mov    r1, rFP              @ arg1
13542    mov    r2, rSELF            @ arg2
13543    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13544
13545/* ------------------------------ */
13546    .balign 64
13547.L_ALT_OP_SUB_INT: /* 0x91 */
13548/* File: armv5te/alt_stub.S */
13549/*
13550 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13551 * any interesting requests and then jump to the real instruction
13552 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13553 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13554 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13555 * bail to the real handler if breakFlags==0.
13556 */
13557    ldrb   r3, [rSELF, #offThread_breakFlags]
13558    adrl   lr, dvmAsmInstructionStart + (145 * 64)
13559    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13560    cmp    r3, #0
13561    bxeq   lr                   @ nothing to do - jump to real handler
13562    EXPORT_PC()
13563    mov    r0, rPC              @ arg0
13564    mov    r1, rFP              @ arg1
13565    mov    r2, rSELF            @ arg2
13566    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13567
13568/* ------------------------------ */
13569    .balign 64
13570.L_ALT_OP_MUL_INT: /* 0x92 */
13571/* File: armv5te/alt_stub.S */
13572/*
13573 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13574 * any interesting requests and then jump to the real instruction
13575 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13576 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13577 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13578 * bail to the real handler if breakFlags==0.
13579 */
13580    ldrb   r3, [rSELF, #offThread_breakFlags]
13581    adrl   lr, dvmAsmInstructionStart + (146 * 64)
13582    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13583    cmp    r3, #0
13584    bxeq   lr                   @ nothing to do - jump to real handler
13585    EXPORT_PC()
13586    mov    r0, rPC              @ arg0
13587    mov    r1, rFP              @ arg1
13588    mov    r2, rSELF            @ arg2
13589    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13590
13591/* ------------------------------ */
13592    .balign 64
13593.L_ALT_OP_DIV_INT: /* 0x93 */
13594/* File: armv5te/alt_stub.S */
13595/*
13596 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13597 * any interesting requests and then jump to the real instruction
13598 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13599 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13600 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13601 * bail to the real handler if breakFlags==0.
13602 */
13603    ldrb   r3, [rSELF, #offThread_breakFlags]
13604    adrl   lr, dvmAsmInstructionStart + (147 * 64)
13605    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13606    cmp    r3, #0
13607    bxeq   lr                   @ nothing to do - jump to real handler
13608    EXPORT_PC()
13609    mov    r0, rPC              @ arg0
13610    mov    r1, rFP              @ arg1
13611    mov    r2, rSELF            @ arg2
13612    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13613
13614/* ------------------------------ */
13615    .balign 64
13616.L_ALT_OP_REM_INT: /* 0x94 */
13617/* File: armv5te/alt_stub.S */
13618/*
13619 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13620 * any interesting requests and then jump to the real instruction
13621 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13622 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13623 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13624 * bail to the real handler if breakFlags==0.
13625 */
13626    ldrb   r3, [rSELF, #offThread_breakFlags]
13627    adrl   lr, dvmAsmInstructionStart + (148 * 64)
13628    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13629    cmp    r3, #0
13630    bxeq   lr                   @ nothing to do - jump to real handler
13631    EXPORT_PC()
13632    mov    r0, rPC              @ arg0
13633    mov    r1, rFP              @ arg1
13634    mov    r2, rSELF            @ arg2
13635    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13636
13637/* ------------------------------ */
13638    .balign 64
13639.L_ALT_OP_AND_INT: /* 0x95 */
13640/* File: armv5te/alt_stub.S */
13641/*
13642 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13643 * any interesting requests and then jump to the real instruction
13644 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13645 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13646 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13647 * bail to the real handler if breakFlags==0.
13648 */
13649    ldrb   r3, [rSELF, #offThread_breakFlags]
13650    adrl   lr, dvmAsmInstructionStart + (149 * 64)
13651    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13652    cmp    r3, #0
13653    bxeq   lr                   @ nothing to do - jump to real handler
13654    EXPORT_PC()
13655    mov    r0, rPC              @ arg0
13656    mov    r1, rFP              @ arg1
13657    mov    r2, rSELF            @ arg2
13658    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13659
13660/* ------------------------------ */
13661    .balign 64
13662.L_ALT_OP_OR_INT: /* 0x96 */
13663/* File: armv5te/alt_stub.S */
13664/*
13665 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13666 * any interesting requests and then jump to the real instruction
13667 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13668 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13669 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13670 * bail to the real handler if breakFlags==0.
13671 */
13672    ldrb   r3, [rSELF, #offThread_breakFlags]
13673    adrl   lr, dvmAsmInstructionStart + (150 * 64)
13674    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13675    cmp    r3, #0
13676    bxeq   lr                   @ nothing to do - jump to real handler
13677    EXPORT_PC()
13678    mov    r0, rPC              @ arg0
13679    mov    r1, rFP              @ arg1
13680    mov    r2, rSELF            @ arg2
13681    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13682
13683/* ------------------------------ */
13684    .balign 64
13685.L_ALT_OP_XOR_INT: /* 0x97 */
13686/* File: armv5te/alt_stub.S */
13687/*
13688 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13689 * any interesting requests and then jump to the real instruction
13690 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13691 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13692 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13693 * bail to the real handler if breakFlags==0.
13694 */
13695    ldrb   r3, [rSELF, #offThread_breakFlags]
13696    adrl   lr, dvmAsmInstructionStart + (151 * 64)
13697    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13698    cmp    r3, #0
13699    bxeq   lr                   @ nothing to do - jump to real handler
13700    EXPORT_PC()
13701    mov    r0, rPC              @ arg0
13702    mov    r1, rFP              @ arg1
13703    mov    r2, rSELF            @ arg2
13704    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13705
13706/* ------------------------------ */
13707    .balign 64
13708.L_ALT_OP_SHL_INT: /* 0x98 */
13709/* File: armv5te/alt_stub.S */
13710/*
13711 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13712 * any interesting requests and then jump to the real instruction
13713 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13714 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13715 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13716 * bail to the real handler if breakFlags==0.
13717 */
13718    ldrb   r3, [rSELF, #offThread_breakFlags]
13719    adrl   lr, dvmAsmInstructionStart + (152 * 64)
13720    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13721    cmp    r3, #0
13722    bxeq   lr                   @ nothing to do - jump to real handler
13723    EXPORT_PC()
13724    mov    r0, rPC              @ arg0
13725    mov    r1, rFP              @ arg1
13726    mov    r2, rSELF            @ arg2
13727    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13728
13729/* ------------------------------ */
13730    .balign 64
13731.L_ALT_OP_SHR_INT: /* 0x99 */
13732/* File: armv5te/alt_stub.S */
13733/*
13734 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13735 * any interesting requests and then jump to the real instruction
13736 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13737 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13738 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13739 * bail to the real handler if breakFlags==0.
13740 */
13741    ldrb   r3, [rSELF, #offThread_breakFlags]
13742    adrl   lr, dvmAsmInstructionStart + (153 * 64)
13743    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13744    cmp    r3, #0
13745    bxeq   lr                   @ nothing to do - jump to real handler
13746    EXPORT_PC()
13747    mov    r0, rPC              @ arg0
13748    mov    r1, rFP              @ arg1
13749    mov    r2, rSELF            @ arg2
13750    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13751
13752/* ------------------------------ */
13753    .balign 64
13754.L_ALT_OP_USHR_INT: /* 0x9a */
13755/* File: armv5te/alt_stub.S */
13756/*
13757 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13758 * any interesting requests and then jump to the real instruction
13759 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13760 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13761 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13762 * bail to the real handler if breakFlags==0.
13763 */
13764    ldrb   r3, [rSELF, #offThread_breakFlags]
13765    adrl   lr, dvmAsmInstructionStart + (154 * 64)
13766    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13767    cmp    r3, #0
13768    bxeq   lr                   @ nothing to do - jump to real handler
13769    EXPORT_PC()
13770    mov    r0, rPC              @ arg0
13771    mov    r1, rFP              @ arg1
13772    mov    r2, rSELF            @ arg2
13773    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13774
13775/* ------------------------------ */
13776    .balign 64
13777.L_ALT_OP_ADD_LONG: /* 0x9b */
13778/* File: armv5te/alt_stub.S */
13779/*
13780 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13781 * any interesting requests and then jump to the real instruction
13782 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13783 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13784 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13785 * bail to the real handler if breakFlags==0.
13786 */
13787    ldrb   r3, [rSELF, #offThread_breakFlags]
13788    adrl   lr, dvmAsmInstructionStart + (155 * 64)
13789    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13790    cmp    r3, #0
13791    bxeq   lr                   @ nothing to do - jump to real handler
13792    EXPORT_PC()
13793    mov    r0, rPC              @ arg0
13794    mov    r1, rFP              @ arg1
13795    mov    r2, rSELF            @ arg2
13796    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13797
13798/* ------------------------------ */
13799    .balign 64
13800.L_ALT_OP_SUB_LONG: /* 0x9c */
13801/* File: armv5te/alt_stub.S */
13802/*
13803 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13804 * any interesting requests and then jump to the real instruction
13805 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13806 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13807 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13808 * bail to the real handler if breakFlags==0.
13809 */
13810    ldrb   r3, [rSELF, #offThread_breakFlags]
13811    adrl   lr, dvmAsmInstructionStart + (156 * 64)
13812    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13813    cmp    r3, #0
13814    bxeq   lr                   @ nothing to do - jump to real handler
13815    EXPORT_PC()
13816    mov    r0, rPC              @ arg0
13817    mov    r1, rFP              @ arg1
13818    mov    r2, rSELF            @ arg2
13819    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13820
13821/* ------------------------------ */
13822    .balign 64
13823.L_ALT_OP_MUL_LONG: /* 0x9d */
13824/* File: armv5te/alt_stub.S */
13825/*
13826 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13827 * any interesting requests and then jump to the real instruction
13828 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13829 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13830 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13831 * bail to the real handler if breakFlags==0.
13832 */
13833    ldrb   r3, [rSELF, #offThread_breakFlags]
13834    adrl   lr, dvmAsmInstructionStart + (157 * 64)
13835    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13836    cmp    r3, #0
13837    bxeq   lr                   @ nothing to do - jump to real handler
13838    EXPORT_PC()
13839    mov    r0, rPC              @ arg0
13840    mov    r1, rFP              @ arg1
13841    mov    r2, rSELF            @ arg2
13842    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13843
13844/* ------------------------------ */
13845    .balign 64
13846.L_ALT_OP_DIV_LONG: /* 0x9e */
13847/* File: armv5te/alt_stub.S */
13848/*
13849 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13850 * any interesting requests and then jump to the real instruction
13851 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13852 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13853 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13854 * bail to the real handler if breakFlags==0.
13855 */
13856    ldrb   r3, [rSELF, #offThread_breakFlags]
13857    adrl   lr, dvmAsmInstructionStart + (158 * 64)
13858    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13859    cmp    r3, #0
13860    bxeq   lr                   @ nothing to do - jump to real handler
13861    EXPORT_PC()
13862    mov    r0, rPC              @ arg0
13863    mov    r1, rFP              @ arg1
13864    mov    r2, rSELF            @ arg2
13865    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13866
13867/* ------------------------------ */
13868    .balign 64
13869.L_ALT_OP_REM_LONG: /* 0x9f */
13870/* File: armv5te/alt_stub.S */
13871/*
13872 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13873 * any interesting requests and then jump to the real instruction
13874 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13875 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13876 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13877 * bail to the real handler if breakFlags==0.
13878 */
13879    ldrb   r3, [rSELF, #offThread_breakFlags]
13880    adrl   lr, dvmAsmInstructionStart + (159 * 64)
13881    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13882    cmp    r3, #0
13883    bxeq   lr                   @ nothing to do - jump to real handler
13884    EXPORT_PC()
13885    mov    r0, rPC              @ arg0
13886    mov    r1, rFP              @ arg1
13887    mov    r2, rSELF            @ arg2
13888    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13889
13890/* ------------------------------ */
13891    .balign 64
13892.L_ALT_OP_AND_LONG: /* 0xa0 */
13893/* File: armv5te/alt_stub.S */
13894/*
13895 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13896 * any interesting requests and then jump to the real instruction
13897 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13898 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13899 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13900 * bail to the real handler if breakFlags==0.
13901 */
13902    ldrb   r3, [rSELF, #offThread_breakFlags]
13903    adrl   lr, dvmAsmInstructionStart + (160 * 64)
13904    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13905    cmp    r3, #0
13906    bxeq   lr                   @ nothing to do - jump to real handler
13907    EXPORT_PC()
13908    mov    r0, rPC              @ arg0
13909    mov    r1, rFP              @ arg1
13910    mov    r2, rSELF            @ arg2
13911    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13912
13913/* ------------------------------ */
13914    .balign 64
13915.L_ALT_OP_OR_LONG: /* 0xa1 */
13916/* File: armv5te/alt_stub.S */
13917/*
13918 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13919 * any interesting requests and then jump to the real instruction
13920 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13921 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13922 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13923 * bail to the real handler if breakFlags==0.
13924 */
13925    ldrb   r3, [rSELF, #offThread_breakFlags]
13926    adrl   lr, dvmAsmInstructionStart + (161 * 64)
13927    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13928    cmp    r3, #0
13929    bxeq   lr                   @ nothing to do - jump to real handler
13930    EXPORT_PC()
13931    mov    r0, rPC              @ arg0
13932    mov    r1, rFP              @ arg1
13933    mov    r2, rSELF            @ arg2
13934    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13935
13936/* ------------------------------ */
13937    .balign 64
13938.L_ALT_OP_XOR_LONG: /* 0xa2 */
13939/* File: armv5te/alt_stub.S */
13940/*
13941 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13942 * any interesting requests and then jump to the real instruction
13943 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13944 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13945 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13946 * bail to the real handler if breakFlags==0.
13947 */
13948    ldrb   r3, [rSELF, #offThread_breakFlags]
13949    adrl   lr, dvmAsmInstructionStart + (162 * 64)
13950    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13951    cmp    r3, #0
13952    bxeq   lr                   @ nothing to do - jump to real handler
13953    EXPORT_PC()
13954    mov    r0, rPC              @ arg0
13955    mov    r1, rFP              @ arg1
13956    mov    r2, rSELF            @ arg2
13957    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13958
13959/* ------------------------------ */
13960    .balign 64
13961.L_ALT_OP_SHL_LONG: /* 0xa3 */
13962/* File: armv5te/alt_stub.S */
13963/*
13964 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13965 * any interesting requests and then jump to the real instruction
13966 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13967 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13968 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13969 * bail to the real handler if breakFlags==0.
13970 */
13971    ldrb   r3, [rSELF, #offThread_breakFlags]
13972    adrl   lr, dvmAsmInstructionStart + (163 * 64)
13973    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13974    cmp    r3, #0
13975    bxeq   lr                   @ nothing to do - jump to real handler
13976    EXPORT_PC()
13977    mov    r0, rPC              @ arg0
13978    mov    r1, rFP              @ arg1
13979    mov    r2, rSELF            @ arg2
13980    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
13981
13982/* ------------------------------ */
13983    .balign 64
13984.L_ALT_OP_SHR_LONG: /* 0xa4 */
13985/* File: armv5te/alt_stub.S */
13986/*
13987 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
13988 * any interesting requests and then jump to the real instruction
13989 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
13990 * rIBASE updates won't be seen until a refresh, and we can tell we have a
13991 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
13992 * bail to the real handler if breakFlags==0.
13993 */
13994    ldrb   r3, [rSELF, #offThread_breakFlags]
13995    adrl   lr, dvmAsmInstructionStart + (164 * 64)
13996    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
13997    cmp    r3, #0
13998    bxeq   lr                   @ nothing to do - jump to real handler
13999    EXPORT_PC()
14000    mov    r0, rPC              @ arg0
14001    mov    r1, rFP              @ arg1
14002    mov    r2, rSELF            @ arg2
14003    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14004
14005/* ------------------------------ */
14006    .balign 64
14007.L_ALT_OP_USHR_LONG: /* 0xa5 */
14008/* File: armv5te/alt_stub.S */
14009/*
14010 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14011 * any interesting requests and then jump to the real instruction
14012 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14013 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14014 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14015 * bail to the real handler if breakFlags==0.
14016 */
14017    ldrb   r3, [rSELF, #offThread_breakFlags]
14018    adrl   lr, dvmAsmInstructionStart + (165 * 64)
14019    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14020    cmp    r3, #0
14021    bxeq   lr                   @ nothing to do - jump to real handler
14022    EXPORT_PC()
14023    mov    r0, rPC              @ arg0
14024    mov    r1, rFP              @ arg1
14025    mov    r2, rSELF            @ arg2
14026    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14027
14028/* ------------------------------ */
14029    .balign 64
14030.L_ALT_OP_ADD_FLOAT: /* 0xa6 */
14031/* File: armv5te/alt_stub.S */
14032/*
14033 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14034 * any interesting requests and then jump to the real instruction
14035 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14036 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14037 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14038 * bail to the real handler if breakFlags==0.
14039 */
14040    ldrb   r3, [rSELF, #offThread_breakFlags]
14041    adrl   lr, dvmAsmInstructionStart + (166 * 64)
14042    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14043    cmp    r3, #0
14044    bxeq   lr                   @ nothing to do - jump to real handler
14045    EXPORT_PC()
14046    mov    r0, rPC              @ arg0
14047    mov    r1, rFP              @ arg1
14048    mov    r2, rSELF            @ arg2
14049    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14050
14051/* ------------------------------ */
14052    .balign 64
14053.L_ALT_OP_SUB_FLOAT: /* 0xa7 */
14054/* File: armv5te/alt_stub.S */
14055/*
14056 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14057 * any interesting requests and then jump to the real instruction
14058 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14059 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14060 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14061 * bail to the real handler if breakFlags==0.
14062 */
14063    ldrb   r3, [rSELF, #offThread_breakFlags]
14064    adrl   lr, dvmAsmInstructionStart + (167 * 64)
14065    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14066    cmp    r3, #0
14067    bxeq   lr                   @ nothing to do - jump to real handler
14068    EXPORT_PC()
14069    mov    r0, rPC              @ arg0
14070    mov    r1, rFP              @ arg1
14071    mov    r2, rSELF            @ arg2
14072    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14073
14074/* ------------------------------ */
14075    .balign 64
14076.L_ALT_OP_MUL_FLOAT: /* 0xa8 */
14077/* File: armv5te/alt_stub.S */
14078/*
14079 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14080 * any interesting requests and then jump to the real instruction
14081 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14082 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14083 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14084 * bail to the real handler if breakFlags==0.
14085 */
14086    ldrb   r3, [rSELF, #offThread_breakFlags]
14087    adrl   lr, dvmAsmInstructionStart + (168 * 64)
14088    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14089    cmp    r3, #0
14090    bxeq   lr                   @ nothing to do - jump to real handler
14091    EXPORT_PC()
14092    mov    r0, rPC              @ arg0
14093    mov    r1, rFP              @ arg1
14094    mov    r2, rSELF            @ arg2
14095    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14096
14097/* ------------------------------ */
14098    .balign 64
14099.L_ALT_OP_DIV_FLOAT: /* 0xa9 */
14100/* File: armv5te/alt_stub.S */
14101/*
14102 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14103 * any interesting requests and then jump to the real instruction
14104 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14105 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14106 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14107 * bail to the real handler if breakFlags==0.
14108 */
14109    ldrb   r3, [rSELF, #offThread_breakFlags]
14110    adrl   lr, dvmAsmInstructionStart + (169 * 64)
14111    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14112    cmp    r3, #0
14113    bxeq   lr                   @ nothing to do - jump to real handler
14114    EXPORT_PC()
14115    mov    r0, rPC              @ arg0
14116    mov    r1, rFP              @ arg1
14117    mov    r2, rSELF            @ arg2
14118    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14119
14120/* ------------------------------ */
14121    .balign 64
14122.L_ALT_OP_REM_FLOAT: /* 0xaa */
14123/* File: armv5te/alt_stub.S */
14124/*
14125 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14126 * any interesting requests and then jump to the real instruction
14127 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14128 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14129 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14130 * bail to the real handler if breakFlags==0.
14131 */
14132    ldrb   r3, [rSELF, #offThread_breakFlags]
14133    adrl   lr, dvmAsmInstructionStart + (170 * 64)
14134    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14135    cmp    r3, #0
14136    bxeq   lr                   @ nothing to do - jump to real handler
14137    EXPORT_PC()
14138    mov    r0, rPC              @ arg0
14139    mov    r1, rFP              @ arg1
14140    mov    r2, rSELF            @ arg2
14141    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14142
14143/* ------------------------------ */
14144    .balign 64
14145.L_ALT_OP_ADD_DOUBLE: /* 0xab */
14146/* File: armv5te/alt_stub.S */
14147/*
14148 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14149 * any interesting requests and then jump to the real instruction
14150 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14151 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14152 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14153 * bail to the real handler if breakFlags==0.
14154 */
14155    ldrb   r3, [rSELF, #offThread_breakFlags]
14156    adrl   lr, dvmAsmInstructionStart + (171 * 64)
14157    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14158    cmp    r3, #0
14159    bxeq   lr                   @ nothing to do - jump to real handler
14160    EXPORT_PC()
14161    mov    r0, rPC              @ arg0
14162    mov    r1, rFP              @ arg1
14163    mov    r2, rSELF            @ arg2
14164    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14165
14166/* ------------------------------ */
14167    .balign 64
14168.L_ALT_OP_SUB_DOUBLE: /* 0xac */
14169/* File: armv5te/alt_stub.S */
14170/*
14171 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14172 * any interesting requests and then jump to the real instruction
14173 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14174 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14175 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14176 * bail to the real handler if breakFlags==0.
14177 */
14178    ldrb   r3, [rSELF, #offThread_breakFlags]
14179    adrl   lr, dvmAsmInstructionStart + (172 * 64)
14180    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14181    cmp    r3, #0
14182    bxeq   lr                   @ nothing to do - jump to real handler
14183    EXPORT_PC()
14184    mov    r0, rPC              @ arg0
14185    mov    r1, rFP              @ arg1
14186    mov    r2, rSELF            @ arg2
14187    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14188
14189/* ------------------------------ */
14190    .balign 64
14191.L_ALT_OP_MUL_DOUBLE: /* 0xad */
14192/* File: armv5te/alt_stub.S */
14193/*
14194 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14195 * any interesting requests and then jump to the real instruction
14196 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14197 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14198 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14199 * bail to the real handler if breakFlags==0.
14200 */
14201    ldrb   r3, [rSELF, #offThread_breakFlags]
14202    adrl   lr, dvmAsmInstructionStart + (173 * 64)
14203    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14204    cmp    r3, #0
14205    bxeq   lr                   @ nothing to do - jump to real handler
14206    EXPORT_PC()
14207    mov    r0, rPC              @ arg0
14208    mov    r1, rFP              @ arg1
14209    mov    r2, rSELF            @ arg2
14210    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14211
14212/* ------------------------------ */
14213    .balign 64
14214.L_ALT_OP_DIV_DOUBLE: /* 0xae */
14215/* File: armv5te/alt_stub.S */
14216/*
14217 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14218 * any interesting requests and then jump to the real instruction
14219 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14220 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14221 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14222 * bail to the real handler if breakFlags==0.
14223 */
14224    ldrb   r3, [rSELF, #offThread_breakFlags]
14225    adrl   lr, dvmAsmInstructionStart + (174 * 64)
14226    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14227    cmp    r3, #0
14228    bxeq   lr                   @ nothing to do - jump to real handler
14229    EXPORT_PC()
14230    mov    r0, rPC              @ arg0
14231    mov    r1, rFP              @ arg1
14232    mov    r2, rSELF            @ arg2
14233    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14234
14235/* ------------------------------ */
14236    .balign 64
14237.L_ALT_OP_REM_DOUBLE: /* 0xaf */
14238/* File: armv5te/alt_stub.S */
14239/*
14240 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14241 * any interesting requests and then jump to the real instruction
14242 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14243 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14244 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14245 * bail to the real handler if breakFlags==0.
14246 */
14247    ldrb   r3, [rSELF, #offThread_breakFlags]
14248    adrl   lr, dvmAsmInstructionStart + (175 * 64)
14249    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14250    cmp    r3, #0
14251    bxeq   lr                   @ nothing to do - jump to real handler
14252    EXPORT_PC()
14253    mov    r0, rPC              @ arg0
14254    mov    r1, rFP              @ arg1
14255    mov    r2, rSELF            @ arg2
14256    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14257
14258/* ------------------------------ */
14259    .balign 64
14260.L_ALT_OP_ADD_INT_2ADDR: /* 0xb0 */
14261/* File: armv5te/alt_stub.S */
14262/*
14263 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14264 * any interesting requests and then jump to the real instruction
14265 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14266 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14267 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14268 * bail to the real handler if breakFlags==0.
14269 */
14270    ldrb   r3, [rSELF, #offThread_breakFlags]
14271    adrl   lr, dvmAsmInstructionStart + (176 * 64)
14272    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14273    cmp    r3, #0
14274    bxeq   lr                   @ nothing to do - jump to real handler
14275    EXPORT_PC()
14276    mov    r0, rPC              @ arg0
14277    mov    r1, rFP              @ arg1
14278    mov    r2, rSELF            @ arg2
14279    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14280
14281/* ------------------------------ */
14282    .balign 64
14283.L_ALT_OP_SUB_INT_2ADDR: /* 0xb1 */
14284/* File: armv5te/alt_stub.S */
14285/*
14286 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14287 * any interesting requests and then jump to the real instruction
14288 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14289 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14290 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14291 * bail to the real handler if breakFlags==0.
14292 */
14293    ldrb   r3, [rSELF, #offThread_breakFlags]
14294    adrl   lr, dvmAsmInstructionStart + (177 * 64)
14295    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14296    cmp    r3, #0
14297    bxeq   lr                   @ nothing to do - jump to real handler
14298    EXPORT_PC()
14299    mov    r0, rPC              @ arg0
14300    mov    r1, rFP              @ arg1
14301    mov    r2, rSELF            @ arg2
14302    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14303
14304/* ------------------------------ */
14305    .balign 64
14306.L_ALT_OP_MUL_INT_2ADDR: /* 0xb2 */
14307/* File: armv5te/alt_stub.S */
14308/*
14309 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14310 * any interesting requests and then jump to the real instruction
14311 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14312 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14313 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14314 * bail to the real handler if breakFlags==0.
14315 */
14316    ldrb   r3, [rSELF, #offThread_breakFlags]
14317    adrl   lr, dvmAsmInstructionStart + (178 * 64)
14318    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14319    cmp    r3, #0
14320    bxeq   lr                   @ nothing to do - jump to real handler
14321    EXPORT_PC()
14322    mov    r0, rPC              @ arg0
14323    mov    r1, rFP              @ arg1
14324    mov    r2, rSELF            @ arg2
14325    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14326
14327/* ------------------------------ */
14328    .balign 64
14329.L_ALT_OP_DIV_INT_2ADDR: /* 0xb3 */
14330/* File: armv5te/alt_stub.S */
14331/*
14332 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14333 * any interesting requests and then jump to the real instruction
14334 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14335 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14336 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14337 * bail to the real handler if breakFlags==0.
14338 */
14339    ldrb   r3, [rSELF, #offThread_breakFlags]
14340    adrl   lr, dvmAsmInstructionStart + (179 * 64)
14341    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14342    cmp    r3, #0
14343    bxeq   lr                   @ nothing to do - jump to real handler
14344    EXPORT_PC()
14345    mov    r0, rPC              @ arg0
14346    mov    r1, rFP              @ arg1
14347    mov    r2, rSELF            @ arg2
14348    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14349
14350/* ------------------------------ */
14351    .balign 64
14352.L_ALT_OP_REM_INT_2ADDR: /* 0xb4 */
14353/* File: armv5te/alt_stub.S */
14354/*
14355 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14356 * any interesting requests and then jump to the real instruction
14357 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14358 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14359 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14360 * bail to the real handler if breakFlags==0.
14361 */
14362    ldrb   r3, [rSELF, #offThread_breakFlags]
14363    adrl   lr, dvmAsmInstructionStart + (180 * 64)
14364    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14365    cmp    r3, #0
14366    bxeq   lr                   @ nothing to do - jump to real handler
14367    EXPORT_PC()
14368    mov    r0, rPC              @ arg0
14369    mov    r1, rFP              @ arg1
14370    mov    r2, rSELF            @ arg2
14371    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14372
14373/* ------------------------------ */
14374    .balign 64
14375.L_ALT_OP_AND_INT_2ADDR: /* 0xb5 */
14376/* File: armv5te/alt_stub.S */
14377/*
14378 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14379 * any interesting requests and then jump to the real instruction
14380 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14381 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14382 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14383 * bail to the real handler if breakFlags==0.
14384 */
14385    ldrb   r3, [rSELF, #offThread_breakFlags]
14386    adrl   lr, dvmAsmInstructionStart + (181 * 64)
14387    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14388    cmp    r3, #0
14389    bxeq   lr                   @ nothing to do - jump to real handler
14390    EXPORT_PC()
14391    mov    r0, rPC              @ arg0
14392    mov    r1, rFP              @ arg1
14393    mov    r2, rSELF            @ arg2
14394    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14395
14396/* ------------------------------ */
14397    .balign 64
14398.L_ALT_OP_OR_INT_2ADDR: /* 0xb6 */
14399/* File: armv5te/alt_stub.S */
14400/*
14401 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14402 * any interesting requests and then jump to the real instruction
14403 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14404 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14405 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14406 * bail to the real handler if breakFlags==0.
14407 */
14408    ldrb   r3, [rSELF, #offThread_breakFlags]
14409    adrl   lr, dvmAsmInstructionStart + (182 * 64)
14410    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14411    cmp    r3, #0
14412    bxeq   lr                   @ nothing to do - jump to real handler
14413    EXPORT_PC()
14414    mov    r0, rPC              @ arg0
14415    mov    r1, rFP              @ arg1
14416    mov    r2, rSELF            @ arg2
14417    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14418
14419/* ------------------------------ */
14420    .balign 64
14421.L_ALT_OP_XOR_INT_2ADDR: /* 0xb7 */
14422/* File: armv5te/alt_stub.S */
14423/*
14424 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14425 * any interesting requests and then jump to the real instruction
14426 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14427 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14428 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14429 * bail to the real handler if breakFlags==0.
14430 */
14431    ldrb   r3, [rSELF, #offThread_breakFlags]
14432    adrl   lr, dvmAsmInstructionStart + (183 * 64)
14433    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14434    cmp    r3, #0
14435    bxeq   lr                   @ nothing to do - jump to real handler
14436    EXPORT_PC()
14437    mov    r0, rPC              @ arg0
14438    mov    r1, rFP              @ arg1
14439    mov    r2, rSELF            @ arg2
14440    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14441
14442/* ------------------------------ */
14443    .balign 64
14444.L_ALT_OP_SHL_INT_2ADDR: /* 0xb8 */
14445/* File: armv5te/alt_stub.S */
14446/*
14447 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14448 * any interesting requests and then jump to the real instruction
14449 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14450 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14451 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14452 * bail to the real handler if breakFlags==0.
14453 */
14454    ldrb   r3, [rSELF, #offThread_breakFlags]
14455    adrl   lr, dvmAsmInstructionStart + (184 * 64)
14456    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14457    cmp    r3, #0
14458    bxeq   lr                   @ nothing to do - jump to real handler
14459    EXPORT_PC()
14460    mov    r0, rPC              @ arg0
14461    mov    r1, rFP              @ arg1
14462    mov    r2, rSELF            @ arg2
14463    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14464
14465/* ------------------------------ */
14466    .balign 64
14467.L_ALT_OP_SHR_INT_2ADDR: /* 0xb9 */
14468/* File: armv5te/alt_stub.S */
14469/*
14470 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14471 * any interesting requests and then jump to the real instruction
14472 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14473 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14474 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14475 * bail to the real handler if breakFlags==0.
14476 */
14477    ldrb   r3, [rSELF, #offThread_breakFlags]
14478    adrl   lr, dvmAsmInstructionStart + (185 * 64)
14479    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14480    cmp    r3, #0
14481    bxeq   lr                   @ nothing to do - jump to real handler
14482    EXPORT_PC()
14483    mov    r0, rPC              @ arg0
14484    mov    r1, rFP              @ arg1
14485    mov    r2, rSELF            @ arg2
14486    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14487
14488/* ------------------------------ */
14489    .balign 64
14490.L_ALT_OP_USHR_INT_2ADDR: /* 0xba */
14491/* File: armv5te/alt_stub.S */
14492/*
14493 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14494 * any interesting requests and then jump to the real instruction
14495 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14496 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14497 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14498 * bail to the real handler if breakFlags==0.
14499 */
14500    ldrb   r3, [rSELF, #offThread_breakFlags]
14501    adrl   lr, dvmAsmInstructionStart + (186 * 64)
14502    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14503    cmp    r3, #0
14504    bxeq   lr                   @ nothing to do - jump to real handler
14505    EXPORT_PC()
14506    mov    r0, rPC              @ arg0
14507    mov    r1, rFP              @ arg1
14508    mov    r2, rSELF            @ arg2
14509    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14510
14511/* ------------------------------ */
14512    .balign 64
14513.L_ALT_OP_ADD_LONG_2ADDR: /* 0xbb */
14514/* File: armv5te/alt_stub.S */
14515/*
14516 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14517 * any interesting requests and then jump to the real instruction
14518 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14519 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14520 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14521 * bail to the real handler if breakFlags==0.
14522 */
14523    ldrb   r3, [rSELF, #offThread_breakFlags]
14524    adrl   lr, dvmAsmInstructionStart + (187 * 64)
14525    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14526    cmp    r3, #0
14527    bxeq   lr                   @ nothing to do - jump to real handler
14528    EXPORT_PC()
14529    mov    r0, rPC              @ arg0
14530    mov    r1, rFP              @ arg1
14531    mov    r2, rSELF            @ arg2
14532    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14533
14534/* ------------------------------ */
14535    .balign 64
14536.L_ALT_OP_SUB_LONG_2ADDR: /* 0xbc */
14537/* File: armv5te/alt_stub.S */
14538/*
14539 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14540 * any interesting requests and then jump to the real instruction
14541 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14542 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14543 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14544 * bail to the real handler if breakFlags==0.
14545 */
14546    ldrb   r3, [rSELF, #offThread_breakFlags]
14547    adrl   lr, dvmAsmInstructionStart + (188 * 64)
14548    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14549    cmp    r3, #0
14550    bxeq   lr                   @ nothing to do - jump to real handler
14551    EXPORT_PC()
14552    mov    r0, rPC              @ arg0
14553    mov    r1, rFP              @ arg1
14554    mov    r2, rSELF            @ arg2
14555    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14556
14557/* ------------------------------ */
14558    .balign 64
14559.L_ALT_OP_MUL_LONG_2ADDR: /* 0xbd */
14560/* File: armv5te/alt_stub.S */
14561/*
14562 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14563 * any interesting requests and then jump to the real instruction
14564 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14565 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14566 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14567 * bail to the real handler if breakFlags==0.
14568 */
14569    ldrb   r3, [rSELF, #offThread_breakFlags]
14570    adrl   lr, dvmAsmInstructionStart + (189 * 64)
14571    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14572    cmp    r3, #0
14573    bxeq   lr                   @ nothing to do - jump to real handler
14574    EXPORT_PC()
14575    mov    r0, rPC              @ arg0
14576    mov    r1, rFP              @ arg1
14577    mov    r2, rSELF            @ arg2
14578    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14579
14580/* ------------------------------ */
14581    .balign 64
14582.L_ALT_OP_DIV_LONG_2ADDR: /* 0xbe */
14583/* File: armv5te/alt_stub.S */
14584/*
14585 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14586 * any interesting requests and then jump to the real instruction
14587 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14588 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14589 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14590 * bail to the real handler if breakFlags==0.
14591 */
14592    ldrb   r3, [rSELF, #offThread_breakFlags]
14593    adrl   lr, dvmAsmInstructionStart + (190 * 64)
14594    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14595    cmp    r3, #0
14596    bxeq   lr                   @ nothing to do - jump to real handler
14597    EXPORT_PC()
14598    mov    r0, rPC              @ arg0
14599    mov    r1, rFP              @ arg1
14600    mov    r2, rSELF            @ arg2
14601    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14602
14603/* ------------------------------ */
14604    .balign 64
14605.L_ALT_OP_REM_LONG_2ADDR: /* 0xbf */
14606/* File: armv5te/alt_stub.S */
14607/*
14608 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14609 * any interesting requests and then jump to the real instruction
14610 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14611 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14612 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14613 * bail to the real handler if breakFlags==0.
14614 */
14615    ldrb   r3, [rSELF, #offThread_breakFlags]
14616    adrl   lr, dvmAsmInstructionStart + (191 * 64)
14617    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14618    cmp    r3, #0
14619    bxeq   lr                   @ nothing to do - jump to real handler
14620    EXPORT_PC()
14621    mov    r0, rPC              @ arg0
14622    mov    r1, rFP              @ arg1
14623    mov    r2, rSELF            @ arg2
14624    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14625
14626/* ------------------------------ */
14627    .balign 64
14628.L_ALT_OP_AND_LONG_2ADDR: /* 0xc0 */
14629/* File: armv5te/alt_stub.S */
14630/*
14631 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14632 * any interesting requests and then jump to the real instruction
14633 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14634 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14635 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14636 * bail to the real handler if breakFlags==0.
14637 */
14638    ldrb   r3, [rSELF, #offThread_breakFlags]
14639    adrl   lr, dvmAsmInstructionStart + (192 * 64)
14640    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14641    cmp    r3, #0
14642    bxeq   lr                   @ nothing to do - jump to real handler
14643    EXPORT_PC()
14644    mov    r0, rPC              @ arg0
14645    mov    r1, rFP              @ arg1
14646    mov    r2, rSELF            @ arg2
14647    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14648
14649/* ------------------------------ */
14650    .balign 64
14651.L_ALT_OP_OR_LONG_2ADDR: /* 0xc1 */
14652/* File: armv5te/alt_stub.S */
14653/*
14654 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14655 * any interesting requests and then jump to the real instruction
14656 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14657 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14658 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14659 * bail to the real handler if breakFlags==0.
14660 */
14661    ldrb   r3, [rSELF, #offThread_breakFlags]
14662    adrl   lr, dvmAsmInstructionStart + (193 * 64)
14663    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14664    cmp    r3, #0
14665    bxeq   lr                   @ nothing to do - jump to real handler
14666    EXPORT_PC()
14667    mov    r0, rPC              @ arg0
14668    mov    r1, rFP              @ arg1
14669    mov    r2, rSELF            @ arg2
14670    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14671
14672/* ------------------------------ */
14673    .balign 64
14674.L_ALT_OP_XOR_LONG_2ADDR: /* 0xc2 */
14675/* File: armv5te/alt_stub.S */
14676/*
14677 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14678 * any interesting requests and then jump to the real instruction
14679 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14680 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14681 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14682 * bail to the real handler if breakFlags==0.
14683 */
14684    ldrb   r3, [rSELF, #offThread_breakFlags]
14685    adrl   lr, dvmAsmInstructionStart + (194 * 64)
14686    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14687    cmp    r3, #0
14688    bxeq   lr                   @ nothing to do - jump to real handler
14689    EXPORT_PC()
14690    mov    r0, rPC              @ arg0
14691    mov    r1, rFP              @ arg1
14692    mov    r2, rSELF            @ arg2
14693    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14694
14695/* ------------------------------ */
14696    .balign 64
14697.L_ALT_OP_SHL_LONG_2ADDR: /* 0xc3 */
14698/* File: armv5te/alt_stub.S */
14699/*
14700 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14701 * any interesting requests and then jump to the real instruction
14702 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14703 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14704 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14705 * bail to the real handler if breakFlags==0.
14706 */
14707    ldrb   r3, [rSELF, #offThread_breakFlags]
14708    adrl   lr, dvmAsmInstructionStart + (195 * 64)
14709    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14710    cmp    r3, #0
14711    bxeq   lr                   @ nothing to do - jump to real handler
14712    EXPORT_PC()
14713    mov    r0, rPC              @ arg0
14714    mov    r1, rFP              @ arg1
14715    mov    r2, rSELF            @ arg2
14716    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14717
14718/* ------------------------------ */
14719    .balign 64
14720.L_ALT_OP_SHR_LONG_2ADDR: /* 0xc4 */
14721/* File: armv5te/alt_stub.S */
14722/*
14723 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14724 * any interesting requests and then jump to the real instruction
14725 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14726 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14727 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14728 * bail to the real handler if breakFlags==0.
14729 */
14730    ldrb   r3, [rSELF, #offThread_breakFlags]
14731    adrl   lr, dvmAsmInstructionStart + (196 * 64)
14732    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14733    cmp    r3, #0
14734    bxeq   lr                   @ nothing to do - jump to real handler
14735    EXPORT_PC()
14736    mov    r0, rPC              @ arg0
14737    mov    r1, rFP              @ arg1
14738    mov    r2, rSELF            @ arg2
14739    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14740
14741/* ------------------------------ */
14742    .balign 64
14743.L_ALT_OP_USHR_LONG_2ADDR: /* 0xc5 */
14744/* File: armv5te/alt_stub.S */
14745/*
14746 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14747 * any interesting requests and then jump to the real instruction
14748 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14749 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14750 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14751 * bail to the real handler if breakFlags==0.
14752 */
14753    ldrb   r3, [rSELF, #offThread_breakFlags]
14754    adrl   lr, dvmAsmInstructionStart + (197 * 64)
14755    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14756    cmp    r3, #0
14757    bxeq   lr                   @ nothing to do - jump to real handler
14758    EXPORT_PC()
14759    mov    r0, rPC              @ arg0
14760    mov    r1, rFP              @ arg1
14761    mov    r2, rSELF            @ arg2
14762    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14763
14764/* ------------------------------ */
14765    .balign 64
14766.L_ALT_OP_ADD_FLOAT_2ADDR: /* 0xc6 */
14767/* File: armv5te/alt_stub.S */
14768/*
14769 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14770 * any interesting requests and then jump to the real instruction
14771 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14772 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14773 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14774 * bail to the real handler if breakFlags==0.
14775 */
14776    ldrb   r3, [rSELF, #offThread_breakFlags]
14777    adrl   lr, dvmAsmInstructionStart + (198 * 64)
14778    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14779    cmp    r3, #0
14780    bxeq   lr                   @ nothing to do - jump to real handler
14781    EXPORT_PC()
14782    mov    r0, rPC              @ arg0
14783    mov    r1, rFP              @ arg1
14784    mov    r2, rSELF            @ arg2
14785    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14786
14787/* ------------------------------ */
14788    .balign 64
14789.L_ALT_OP_SUB_FLOAT_2ADDR: /* 0xc7 */
14790/* File: armv5te/alt_stub.S */
14791/*
14792 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14793 * any interesting requests and then jump to the real instruction
14794 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14795 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14796 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14797 * bail to the real handler if breakFlags==0.
14798 */
14799    ldrb   r3, [rSELF, #offThread_breakFlags]
14800    adrl   lr, dvmAsmInstructionStart + (199 * 64)
14801    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14802    cmp    r3, #0
14803    bxeq   lr                   @ nothing to do - jump to real handler
14804    EXPORT_PC()
14805    mov    r0, rPC              @ arg0
14806    mov    r1, rFP              @ arg1
14807    mov    r2, rSELF            @ arg2
14808    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14809
14810/* ------------------------------ */
14811    .balign 64
14812.L_ALT_OP_MUL_FLOAT_2ADDR: /* 0xc8 */
14813/* File: armv5te/alt_stub.S */
14814/*
14815 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14816 * any interesting requests and then jump to the real instruction
14817 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14818 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14819 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14820 * bail to the real handler if breakFlags==0.
14821 */
14822    ldrb   r3, [rSELF, #offThread_breakFlags]
14823    adrl   lr, dvmAsmInstructionStart + (200 * 64)
14824    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14825    cmp    r3, #0
14826    bxeq   lr                   @ nothing to do - jump to real handler
14827    EXPORT_PC()
14828    mov    r0, rPC              @ arg0
14829    mov    r1, rFP              @ arg1
14830    mov    r2, rSELF            @ arg2
14831    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14832
14833/* ------------------------------ */
14834    .balign 64
14835.L_ALT_OP_DIV_FLOAT_2ADDR: /* 0xc9 */
14836/* File: armv5te/alt_stub.S */
14837/*
14838 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14839 * any interesting requests and then jump to the real instruction
14840 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14841 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14842 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14843 * bail to the real handler if breakFlags==0.
14844 */
14845    ldrb   r3, [rSELF, #offThread_breakFlags]
14846    adrl   lr, dvmAsmInstructionStart + (201 * 64)
14847    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14848    cmp    r3, #0
14849    bxeq   lr                   @ nothing to do - jump to real handler
14850    EXPORT_PC()
14851    mov    r0, rPC              @ arg0
14852    mov    r1, rFP              @ arg1
14853    mov    r2, rSELF            @ arg2
14854    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14855
14856/* ------------------------------ */
14857    .balign 64
14858.L_ALT_OP_REM_FLOAT_2ADDR: /* 0xca */
14859/* File: armv5te/alt_stub.S */
14860/*
14861 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14862 * any interesting requests and then jump to the real instruction
14863 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14864 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14865 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14866 * bail to the real handler if breakFlags==0.
14867 */
14868    ldrb   r3, [rSELF, #offThread_breakFlags]
14869    adrl   lr, dvmAsmInstructionStart + (202 * 64)
14870    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14871    cmp    r3, #0
14872    bxeq   lr                   @ nothing to do - jump to real handler
14873    EXPORT_PC()
14874    mov    r0, rPC              @ arg0
14875    mov    r1, rFP              @ arg1
14876    mov    r2, rSELF            @ arg2
14877    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14878
14879/* ------------------------------ */
14880    .balign 64
14881.L_ALT_OP_ADD_DOUBLE_2ADDR: /* 0xcb */
14882/* File: armv5te/alt_stub.S */
14883/*
14884 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14885 * any interesting requests and then jump to the real instruction
14886 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14887 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14888 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14889 * bail to the real handler if breakFlags==0.
14890 */
14891    ldrb   r3, [rSELF, #offThread_breakFlags]
14892    adrl   lr, dvmAsmInstructionStart + (203 * 64)
14893    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14894    cmp    r3, #0
14895    bxeq   lr                   @ nothing to do - jump to real handler
14896    EXPORT_PC()
14897    mov    r0, rPC              @ arg0
14898    mov    r1, rFP              @ arg1
14899    mov    r2, rSELF            @ arg2
14900    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14901
14902/* ------------------------------ */
14903    .balign 64
14904.L_ALT_OP_SUB_DOUBLE_2ADDR: /* 0xcc */
14905/* File: armv5te/alt_stub.S */
14906/*
14907 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14908 * any interesting requests and then jump to the real instruction
14909 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14910 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14911 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14912 * bail to the real handler if breakFlags==0.
14913 */
14914    ldrb   r3, [rSELF, #offThread_breakFlags]
14915    adrl   lr, dvmAsmInstructionStart + (204 * 64)
14916    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14917    cmp    r3, #0
14918    bxeq   lr                   @ nothing to do - jump to real handler
14919    EXPORT_PC()
14920    mov    r0, rPC              @ arg0
14921    mov    r1, rFP              @ arg1
14922    mov    r2, rSELF            @ arg2
14923    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14924
14925/* ------------------------------ */
14926    .balign 64
14927.L_ALT_OP_MUL_DOUBLE_2ADDR: /* 0xcd */
14928/* File: armv5te/alt_stub.S */
14929/*
14930 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14931 * any interesting requests and then jump to the real instruction
14932 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14933 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14934 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14935 * bail to the real handler if breakFlags==0.
14936 */
14937    ldrb   r3, [rSELF, #offThread_breakFlags]
14938    adrl   lr, dvmAsmInstructionStart + (205 * 64)
14939    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14940    cmp    r3, #0
14941    bxeq   lr                   @ nothing to do - jump to real handler
14942    EXPORT_PC()
14943    mov    r0, rPC              @ arg0
14944    mov    r1, rFP              @ arg1
14945    mov    r2, rSELF            @ arg2
14946    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14947
14948/* ------------------------------ */
14949    .balign 64
14950.L_ALT_OP_DIV_DOUBLE_2ADDR: /* 0xce */
14951/* File: armv5te/alt_stub.S */
14952/*
14953 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14954 * any interesting requests and then jump to the real instruction
14955 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14956 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14957 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14958 * bail to the real handler if breakFlags==0.
14959 */
14960    ldrb   r3, [rSELF, #offThread_breakFlags]
14961    adrl   lr, dvmAsmInstructionStart + (206 * 64)
14962    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14963    cmp    r3, #0
14964    bxeq   lr                   @ nothing to do - jump to real handler
14965    EXPORT_PC()
14966    mov    r0, rPC              @ arg0
14967    mov    r1, rFP              @ arg1
14968    mov    r2, rSELF            @ arg2
14969    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14970
14971/* ------------------------------ */
14972    .balign 64
14973.L_ALT_OP_REM_DOUBLE_2ADDR: /* 0xcf */
14974/* File: armv5te/alt_stub.S */
14975/*
14976 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
14977 * any interesting requests and then jump to the real instruction
14978 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
14979 * rIBASE updates won't be seen until a refresh, and we can tell we have a
14980 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
14981 * bail to the real handler if breakFlags==0.
14982 */
14983    ldrb   r3, [rSELF, #offThread_breakFlags]
14984    adrl   lr, dvmAsmInstructionStart + (207 * 64)
14985    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
14986    cmp    r3, #0
14987    bxeq   lr                   @ nothing to do - jump to real handler
14988    EXPORT_PC()
14989    mov    r0, rPC              @ arg0
14990    mov    r1, rFP              @ arg1
14991    mov    r2, rSELF            @ arg2
14992    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
14993
14994/* ------------------------------ */
14995    .balign 64
14996.L_ALT_OP_ADD_INT_LIT16: /* 0xd0 */
14997/* File: armv5te/alt_stub.S */
14998/*
14999 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15000 * any interesting requests and then jump to the real instruction
15001 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15002 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15003 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15004 * bail to the real handler if breakFlags==0.
15005 */
15006    ldrb   r3, [rSELF, #offThread_breakFlags]
15007    adrl   lr, dvmAsmInstructionStart + (208 * 64)
15008    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15009    cmp    r3, #0
15010    bxeq   lr                   @ nothing to do - jump to real handler
15011    EXPORT_PC()
15012    mov    r0, rPC              @ arg0
15013    mov    r1, rFP              @ arg1
15014    mov    r2, rSELF            @ arg2
15015    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15016
15017/* ------------------------------ */
15018    .balign 64
15019.L_ALT_OP_RSUB_INT: /* 0xd1 */
15020/* File: armv5te/alt_stub.S */
15021/*
15022 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15023 * any interesting requests and then jump to the real instruction
15024 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15025 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15026 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15027 * bail to the real handler if breakFlags==0.
15028 */
15029    ldrb   r3, [rSELF, #offThread_breakFlags]
15030    adrl   lr, dvmAsmInstructionStart + (209 * 64)
15031    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15032    cmp    r3, #0
15033    bxeq   lr                   @ nothing to do - jump to real handler
15034    EXPORT_PC()
15035    mov    r0, rPC              @ arg0
15036    mov    r1, rFP              @ arg1
15037    mov    r2, rSELF            @ arg2
15038    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15039
15040/* ------------------------------ */
15041    .balign 64
15042.L_ALT_OP_MUL_INT_LIT16: /* 0xd2 */
15043/* File: armv5te/alt_stub.S */
15044/*
15045 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15046 * any interesting requests and then jump to the real instruction
15047 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15048 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15049 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15050 * bail to the real handler if breakFlags==0.
15051 */
15052    ldrb   r3, [rSELF, #offThread_breakFlags]
15053    adrl   lr, dvmAsmInstructionStart + (210 * 64)
15054    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15055    cmp    r3, #0
15056    bxeq   lr                   @ nothing to do - jump to real handler
15057    EXPORT_PC()
15058    mov    r0, rPC              @ arg0
15059    mov    r1, rFP              @ arg1
15060    mov    r2, rSELF            @ arg2
15061    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15062
15063/* ------------------------------ */
15064    .balign 64
15065.L_ALT_OP_DIV_INT_LIT16: /* 0xd3 */
15066/* File: armv5te/alt_stub.S */
15067/*
15068 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15069 * any interesting requests and then jump to the real instruction
15070 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15071 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15072 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15073 * bail to the real handler if breakFlags==0.
15074 */
15075    ldrb   r3, [rSELF, #offThread_breakFlags]
15076    adrl   lr, dvmAsmInstructionStart + (211 * 64)
15077    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15078    cmp    r3, #0
15079    bxeq   lr                   @ nothing to do - jump to real handler
15080    EXPORT_PC()
15081    mov    r0, rPC              @ arg0
15082    mov    r1, rFP              @ arg1
15083    mov    r2, rSELF            @ arg2
15084    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15085
15086/* ------------------------------ */
15087    .balign 64
15088.L_ALT_OP_REM_INT_LIT16: /* 0xd4 */
15089/* File: armv5te/alt_stub.S */
15090/*
15091 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15092 * any interesting requests and then jump to the real instruction
15093 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15094 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15095 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15096 * bail to the real handler if breakFlags==0.
15097 */
15098    ldrb   r3, [rSELF, #offThread_breakFlags]
15099    adrl   lr, dvmAsmInstructionStart + (212 * 64)
15100    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15101    cmp    r3, #0
15102    bxeq   lr                   @ nothing to do - jump to real handler
15103    EXPORT_PC()
15104    mov    r0, rPC              @ arg0
15105    mov    r1, rFP              @ arg1
15106    mov    r2, rSELF            @ arg2
15107    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15108
15109/* ------------------------------ */
15110    .balign 64
15111.L_ALT_OP_AND_INT_LIT16: /* 0xd5 */
15112/* File: armv5te/alt_stub.S */
15113/*
15114 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15115 * any interesting requests and then jump to the real instruction
15116 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15117 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15118 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15119 * bail to the real handler if breakFlags==0.
15120 */
15121    ldrb   r3, [rSELF, #offThread_breakFlags]
15122    adrl   lr, dvmAsmInstructionStart + (213 * 64)
15123    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15124    cmp    r3, #0
15125    bxeq   lr                   @ nothing to do - jump to real handler
15126    EXPORT_PC()
15127    mov    r0, rPC              @ arg0
15128    mov    r1, rFP              @ arg1
15129    mov    r2, rSELF            @ arg2
15130    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15131
15132/* ------------------------------ */
15133    .balign 64
15134.L_ALT_OP_OR_INT_LIT16: /* 0xd6 */
15135/* File: armv5te/alt_stub.S */
15136/*
15137 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15138 * any interesting requests and then jump to the real instruction
15139 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15140 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15141 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15142 * bail to the real handler if breakFlags==0.
15143 */
15144    ldrb   r3, [rSELF, #offThread_breakFlags]
15145    adrl   lr, dvmAsmInstructionStart + (214 * 64)
15146    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15147    cmp    r3, #0
15148    bxeq   lr                   @ nothing to do - jump to real handler
15149    EXPORT_PC()
15150    mov    r0, rPC              @ arg0
15151    mov    r1, rFP              @ arg1
15152    mov    r2, rSELF            @ arg2
15153    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15154
15155/* ------------------------------ */
15156    .balign 64
15157.L_ALT_OP_XOR_INT_LIT16: /* 0xd7 */
15158/* File: armv5te/alt_stub.S */
15159/*
15160 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15161 * any interesting requests and then jump to the real instruction
15162 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15163 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15164 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15165 * bail to the real handler if breakFlags==0.
15166 */
15167    ldrb   r3, [rSELF, #offThread_breakFlags]
15168    adrl   lr, dvmAsmInstructionStart + (215 * 64)
15169    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15170    cmp    r3, #0
15171    bxeq   lr                   @ nothing to do - jump to real handler
15172    EXPORT_PC()
15173    mov    r0, rPC              @ arg0
15174    mov    r1, rFP              @ arg1
15175    mov    r2, rSELF            @ arg2
15176    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15177
15178/* ------------------------------ */
15179    .balign 64
15180.L_ALT_OP_ADD_INT_LIT8: /* 0xd8 */
15181/* File: armv5te/alt_stub.S */
15182/*
15183 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15184 * any interesting requests and then jump to the real instruction
15185 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15186 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15187 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15188 * bail to the real handler if breakFlags==0.
15189 */
15190    ldrb   r3, [rSELF, #offThread_breakFlags]
15191    adrl   lr, dvmAsmInstructionStart + (216 * 64)
15192    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15193    cmp    r3, #0
15194    bxeq   lr                   @ nothing to do - jump to real handler
15195    EXPORT_PC()
15196    mov    r0, rPC              @ arg0
15197    mov    r1, rFP              @ arg1
15198    mov    r2, rSELF            @ arg2
15199    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15200
15201/* ------------------------------ */
15202    .balign 64
15203.L_ALT_OP_RSUB_INT_LIT8: /* 0xd9 */
15204/* File: armv5te/alt_stub.S */
15205/*
15206 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15207 * any interesting requests and then jump to the real instruction
15208 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15209 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15210 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15211 * bail to the real handler if breakFlags==0.
15212 */
15213    ldrb   r3, [rSELF, #offThread_breakFlags]
15214    adrl   lr, dvmAsmInstructionStart + (217 * 64)
15215    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15216    cmp    r3, #0
15217    bxeq   lr                   @ nothing to do - jump to real handler
15218    EXPORT_PC()
15219    mov    r0, rPC              @ arg0
15220    mov    r1, rFP              @ arg1
15221    mov    r2, rSELF            @ arg2
15222    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15223
15224/* ------------------------------ */
15225    .balign 64
15226.L_ALT_OP_MUL_INT_LIT8: /* 0xda */
15227/* File: armv5te/alt_stub.S */
15228/*
15229 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15230 * any interesting requests and then jump to the real instruction
15231 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15232 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15233 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15234 * bail to the real handler if breakFlags==0.
15235 */
15236    ldrb   r3, [rSELF, #offThread_breakFlags]
15237    adrl   lr, dvmAsmInstructionStart + (218 * 64)
15238    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15239    cmp    r3, #0
15240    bxeq   lr                   @ nothing to do - jump to real handler
15241    EXPORT_PC()
15242    mov    r0, rPC              @ arg0
15243    mov    r1, rFP              @ arg1
15244    mov    r2, rSELF            @ arg2
15245    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15246
15247/* ------------------------------ */
15248    .balign 64
15249.L_ALT_OP_DIV_INT_LIT8: /* 0xdb */
15250/* File: armv5te/alt_stub.S */
15251/*
15252 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15253 * any interesting requests and then jump to the real instruction
15254 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15255 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15256 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15257 * bail to the real handler if breakFlags==0.
15258 */
15259    ldrb   r3, [rSELF, #offThread_breakFlags]
15260    adrl   lr, dvmAsmInstructionStart + (219 * 64)
15261    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15262    cmp    r3, #0
15263    bxeq   lr                   @ nothing to do - jump to real handler
15264    EXPORT_PC()
15265    mov    r0, rPC              @ arg0
15266    mov    r1, rFP              @ arg1
15267    mov    r2, rSELF            @ arg2
15268    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15269
15270/* ------------------------------ */
15271    .balign 64
15272.L_ALT_OP_REM_INT_LIT8: /* 0xdc */
15273/* File: armv5te/alt_stub.S */
15274/*
15275 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15276 * any interesting requests and then jump to the real instruction
15277 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15278 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15279 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15280 * bail to the real handler if breakFlags==0.
15281 */
15282    ldrb   r3, [rSELF, #offThread_breakFlags]
15283    adrl   lr, dvmAsmInstructionStart + (220 * 64)
15284    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15285    cmp    r3, #0
15286    bxeq   lr                   @ nothing to do - jump to real handler
15287    EXPORT_PC()
15288    mov    r0, rPC              @ arg0
15289    mov    r1, rFP              @ arg1
15290    mov    r2, rSELF            @ arg2
15291    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15292
15293/* ------------------------------ */
15294    .balign 64
15295.L_ALT_OP_AND_INT_LIT8: /* 0xdd */
15296/* File: armv5te/alt_stub.S */
15297/*
15298 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15299 * any interesting requests and then jump to the real instruction
15300 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15301 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15302 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15303 * bail to the real handler if breakFlags==0.
15304 */
15305    ldrb   r3, [rSELF, #offThread_breakFlags]
15306    adrl   lr, dvmAsmInstructionStart + (221 * 64)
15307    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15308    cmp    r3, #0
15309    bxeq   lr                   @ nothing to do - jump to real handler
15310    EXPORT_PC()
15311    mov    r0, rPC              @ arg0
15312    mov    r1, rFP              @ arg1
15313    mov    r2, rSELF            @ arg2
15314    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15315
15316/* ------------------------------ */
15317    .balign 64
15318.L_ALT_OP_OR_INT_LIT8: /* 0xde */
15319/* File: armv5te/alt_stub.S */
15320/*
15321 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15322 * any interesting requests and then jump to the real instruction
15323 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15324 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15325 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15326 * bail to the real handler if breakFlags==0.
15327 */
15328    ldrb   r3, [rSELF, #offThread_breakFlags]
15329    adrl   lr, dvmAsmInstructionStart + (222 * 64)
15330    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15331    cmp    r3, #0
15332    bxeq   lr                   @ nothing to do - jump to real handler
15333    EXPORT_PC()
15334    mov    r0, rPC              @ arg0
15335    mov    r1, rFP              @ arg1
15336    mov    r2, rSELF            @ arg2
15337    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15338
15339/* ------------------------------ */
15340    .balign 64
15341.L_ALT_OP_XOR_INT_LIT8: /* 0xdf */
15342/* File: armv5te/alt_stub.S */
15343/*
15344 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15345 * any interesting requests and then jump to the real instruction
15346 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15347 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15348 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15349 * bail to the real handler if breakFlags==0.
15350 */
15351    ldrb   r3, [rSELF, #offThread_breakFlags]
15352    adrl   lr, dvmAsmInstructionStart + (223 * 64)
15353    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15354    cmp    r3, #0
15355    bxeq   lr                   @ nothing to do - jump to real handler
15356    EXPORT_PC()
15357    mov    r0, rPC              @ arg0
15358    mov    r1, rFP              @ arg1
15359    mov    r2, rSELF            @ arg2
15360    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15361
15362/* ------------------------------ */
15363    .balign 64
15364.L_ALT_OP_SHL_INT_LIT8: /* 0xe0 */
15365/* File: armv5te/alt_stub.S */
15366/*
15367 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15368 * any interesting requests and then jump to the real instruction
15369 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15370 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15371 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15372 * bail to the real handler if breakFlags==0.
15373 */
15374    ldrb   r3, [rSELF, #offThread_breakFlags]
15375    adrl   lr, dvmAsmInstructionStart + (224 * 64)
15376    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15377    cmp    r3, #0
15378    bxeq   lr                   @ nothing to do - jump to real handler
15379    EXPORT_PC()
15380    mov    r0, rPC              @ arg0
15381    mov    r1, rFP              @ arg1
15382    mov    r2, rSELF            @ arg2
15383    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15384
15385/* ------------------------------ */
15386    .balign 64
15387.L_ALT_OP_SHR_INT_LIT8: /* 0xe1 */
15388/* File: armv5te/alt_stub.S */
15389/*
15390 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15391 * any interesting requests and then jump to the real instruction
15392 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15393 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15394 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15395 * bail to the real handler if breakFlags==0.
15396 */
15397    ldrb   r3, [rSELF, #offThread_breakFlags]
15398    adrl   lr, dvmAsmInstructionStart + (225 * 64)
15399    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15400    cmp    r3, #0
15401    bxeq   lr                   @ nothing to do - jump to real handler
15402    EXPORT_PC()
15403    mov    r0, rPC              @ arg0
15404    mov    r1, rFP              @ arg1
15405    mov    r2, rSELF            @ arg2
15406    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15407
15408/* ------------------------------ */
15409    .balign 64
15410.L_ALT_OP_USHR_INT_LIT8: /* 0xe2 */
15411/* File: armv5te/alt_stub.S */
15412/*
15413 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15414 * any interesting requests and then jump to the real instruction
15415 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15416 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15417 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15418 * bail to the real handler if breakFlags==0.
15419 */
15420    ldrb   r3, [rSELF, #offThread_breakFlags]
15421    adrl   lr, dvmAsmInstructionStart + (226 * 64)
15422    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15423    cmp    r3, #0
15424    bxeq   lr                   @ nothing to do - jump to real handler
15425    EXPORT_PC()
15426    mov    r0, rPC              @ arg0
15427    mov    r1, rFP              @ arg1
15428    mov    r2, rSELF            @ arg2
15429    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15430
15431/* ------------------------------ */
15432    .balign 64
15433.L_ALT_OP_IGET_VOLATILE: /* 0xe3 */
15434/* File: armv5te/alt_stub.S */
15435/*
15436 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15437 * any interesting requests and then jump to the real instruction
15438 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15439 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15440 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15441 * bail to the real handler if breakFlags==0.
15442 */
15443    ldrb   r3, [rSELF, #offThread_breakFlags]
15444    adrl   lr, dvmAsmInstructionStart + (227 * 64)
15445    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15446    cmp    r3, #0
15447    bxeq   lr                   @ nothing to do - jump to real handler
15448    EXPORT_PC()
15449    mov    r0, rPC              @ arg0
15450    mov    r1, rFP              @ arg1
15451    mov    r2, rSELF            @ arg2
15452    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15453
15454/* ------------------------------ */
15455    .balign 64
15456.L_ALT_OP_IPUT_VOLATILE: /* 0xe4 */
15457/* File: armv5te/alt_stub.S */
15458/*
15459 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15460 * any interesting requests and then jump to the real instruction
15461 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15462 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15463 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15464 * bail to the real handler if breakFlags==0.
15465 */
15466    ldrb   r3, [rSELF, #offThread_breakFlags]
15467    adrl   lr, dvmAsmInstructionStart + (228 * 64)
15468    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15469    cmp    r3, #0
15470    bxeq   lr                   @ nothing to do - jump to real handler
15471    EXPORT_PC()
15472    mov    r0, rPC              @ arg0
15473    mov    r1, rFP              @ arg1
15474    mov    r2, rSELF            @ arg2
15475    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15476
15477/* ------------------------------ */
15478    .balign 64
15479.L_ALT_OP_SGET_VOLATILE: /* 0xe5 */
15480/* File: armv5te/alt_stub.S */
15481/*
15482 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15483 * any interesting requests and then jump to the real instruction
15484 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15485 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15486 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15487 * bail to the real handler if breakFlags==0.
15488 */
15489    ldrb   r3, [rSELF, #offThread_breakFlags]
15490    adrl   lr, dvmAsmInstructionStart + (229 * 64)
15491    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15492    cmp    r3, #0
15493    bxeq   lr                   @ nothing to do - jump to real handler
15494    EXPORT_PC()
15495    mov    r0, rPC              @ arg0
15496    mov    r1, rFP              @ arg1
15497    mov    r2, rSELF            @ arg2
15498    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15499
15500/* ------------------------------ */
15501    .balign 64
15502.L_ALT_OP_SPUT_VOLATILE: /* 0xe6 */
15503/* File: armv5te/alt_stub.S */
15504/*
15505 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15506 * any interesting requests and then jump to the real instruction
15507 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15508 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15509 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15510 * bail to the real handler if breakFlags==0.
15511 */
15512    ldrb   r3, [rSELF, #offThread_breakFlags]
15513    adrl   lr, dvmAsmInstructionStart + (230 * 64)
15514    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15515    cmp    r3, #0
15516    bxeq   lr                   @ nothing to do - jump to real handler
15517    EXPORT_PC()
15518    mov    r0, rPC              @ arg0
15519    mov    r1, rFP              @ arg1
15520    mov    r2, rSELF            @ arg2
15521    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15522
15523/* ------------------------------ */
15524    .balign 64
15525.L_ALT_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
15526/* File: armv5te/alt_stub.S */
15527/*
15528 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15529 * any interesting requests and then jump to the real instruction
15530 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15531 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15532 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15533 * bail to the real handler if breakFlags==0.
15534 */
15535    ldrb   r3, [rSELF, #offThread_breakFlags]
15536    adrl   lr, dvmAsmInstructionStart + (231 * 64)
15537    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15538    cmp    r3, #0
15539    bxeq   lr                   @ nothing to do - jump to real handler
15540    EXPORT_PC()
15541    mov    r0, rPC              @ arg0
15542    mov    r1, rFP              @ arg1
15543    mov    r2, rSELF            @ arg2
15544    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15545
15546/* ------------------------------ */
15547    .balign 64
15548.L_ALT_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
15549/* File: armv5te/alt_stub.S */
15550/*
15551 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15552 * any interesting requests and then jump to the real instruction
15553 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15554 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15555 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15556 * bail to the real handler if breakFlags==0.
15557 */
15558    ldrb   r3, [rSELF, #offThread_breakFlags]
15559    adrl   lr, dvmAsmInstructionStart + (232 * 64)
15560    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15561    cmp    r3, #0
15562    bxeq   lr                   @ nothing to do - jump to real handler
15563    EXPORT_PC()
15564    mov    r0, rPC              @ arg0
15565    mov    r1, rFP              @ arg1
15566    mov    r2, rSELF            @ arg2
15567    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15568
15569/* ------------------------------ */
15570    .balign 64
15571.L_ALT_OP_IPUT_WIDE_VOLATILE: /* 0xe9 */
15572/* File: armv5te/alt_stub.S */
15573/*
15574 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15575 * any interesting requests and then jump to the real instruction
15576 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15577 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15578 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15579 * bail to the real handler if breakFlags==0.
15580 */
15581    ldrb   r3, [rSELF, #offThread_breakFlags]
15582    adrl   lr, dvmAsmInstructionStart + (233 * 64)
15583    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15584    cmp    r3, #0
15585    bxeq   lr                   @ nothing to do - jump to real handler
15586    EXPORT_PC()
15587    mov    r0, rPC              @ arg0
15588    mov    r1, rFP              @ arg1
15589    mov    r2, rSELF            @ arg2
15590    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15591
15592/* ------------------------------ */
15593    .balign 64
15594.L_ALT_OP_SGET_WIDE_VOLATILE: /* 0xea */
15595/* File: armv5te/alt_stub.S */
15596/*
15597 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15598 * any interesting requests and then jump to the real instruction
15599 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15600 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15601 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15602 * bail to the real handler if breakFlags==0.
15603 */
15604    ldrb   r3, [rSELF, #offThread_breakFlags]
15605    adrl   lr, dvmAsmInstructionStart + (234 * 64)
15606    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15607    cmp    r3, #0
15608    bxeq   lr                   @ nothing to do - jump to real handler
15609    EXPORT_PC()
15610    mov    r0, rPC              @ arg0
15611    mov    r1, rFP              @ arg1
15612    mov    r2, rSELF            @ arg2
15613    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15614
15615/* ------------------------------ */
15616    .balign 64
15617.L_ALT_OP_SPUT_WIDE_VOLATILE: /* 0xeb */
15618/* File: armv5te/alt_stub.S */
15619/*
15620 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15621 * any interesting requests and then jump to the real instruction
15622 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15623 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15624 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15625 * bail to the real handler if breakFlags==0.
15626 */
15627    ldrb   r3, [rSELF, #offThread_breakFlags]
15628    adrl   lr, dvmAsmInstructionStart + (235 * 64)
15629    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15630    cmp    r3, #0
15631    bxeq   lr                   @ nothing to do - jump to real handler
15632    EXPORT_PC()
15633    mov    r0, rPC              @ arg0
15634    mov    r1, rFP              @ arg1
15635    mov    r2, rSELF            @ arg2
15636    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15637
15638/* ------------------------------ */
15639    .balign 64
15640.L_ALT_OP_BREAKPOINT: /* 0xec */
15641/* File: armv5te/alt_stub.S */
15642/*
15643 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15644 * any interesting requests and then jump to the real instruction
15645 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15646 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15647 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15648 * bail to the real handler if breakFlags==0.
15649 */
15650    ldrb   r3, [rSELF, #offThread_breakFlags]
15651    adrl   lr, dvmAsmInstructionStart + (236 * 64)
15652    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15653    cmp    r3, #0
15654    bxeq   lr                   @ nothing to do - jump to real handler
15655    EXPORT_PC()
15656    mov    r0, rPC              @ arg0
15657    mov    r1, rFP              @ arg1
15658    mov    r2, rSELF            @ arg2
15659    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15660
15661/* ------------------------------ */
15662    .balign 64
15663.L_ALT_OP_THROW_VERIFICATION_ERROR: /* 0xed */
15664/* File: armv5te/alt_stub.S */
15665/*
15666 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15667 * any interesting requests and then jump to the real instruction
15668 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15669 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15670 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15671 * bail to the real handler if breakFlags==0.
15672 */
15673    ldrb   r3, [rSELF, #offThread_breakFlags]
15674    adrl   lr, dvmAsmInstructionStart + (237 * 64)
15675    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15676    cmp    r3, #0
15677    bxeq   lr                   @ nothing to do - jump to real handler
15678    EXPORT_PC()
15679    mov    r0, rPC              @ arg0
15680    mov    r1, rFP              @ arg1
15681    mov    r2, rSELF            @ arg2
15682    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15683
15684/* ------------------------------ */
15685    .balign 64
15686.L_ALT_OP_EXECUTE_INLINE: /* 0xee */
15687/* File: armv5te/alt_stub.S */
15688/*
15689 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15690 * any interesting requests and then jump to the real instruction
15691 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15692 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15693 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15694 * bail to the real handler if breakFlags==0.
15695 */
15696    ldrb   r3, [rSELF, #offThread_breakFlags]
15697    adrl   lr, dvmAsmInstructionStart + (238 * 64)
15698    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15699    cmp    r3, #0
15700    bxeq   lr                   @ nothing to do - jump to real handler
15701    EXPORT_PC()
15702    mov    r0, rPC              @ arg0
15703    mov    r1, rFP              @ arg1
15704    mov    r2, rSELF            @ arg2
15705    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15706
15707/* ------------------------------ */
15708    .balign 64
15709.L_ALT_OP_EXECUTE_INLINE_RANGE: /* 0xef */
15710/* File: armv5te/alt_stub.S */
15711/*
15712 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15713 * any interesting requests and then jump to the real instruction
15714 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15715 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15716 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15717 * bail to the real handler if breakFlags==0.
15718 */
15719    ldrb   r3, [rSELF, #offThread_breakFlags]
15720    adrl   lr, dvmAsmInstructionStart + (239 * 64)
15721    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15722    cmp    r3, #0
15723    bxeq   lr                   @ nothing to do - jump to real handler
15724    EXPORT_PC()
15725    mov    r0, rPC              @ arg0
15726    mov    r1, rFP              @ arg1
15727    mov    r2, rSELF            @ arg2
15728    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15729
15730/* ------------------------------ */
15731    .balign 64
15732.L_ALT_OP_INVOKE_OBJECT_INIT_RANGE: /* 0xf0 */
15733/* File: armv5te/alt_stub.S */
15734/*
15735 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15736 * any interesting requests and then jump to the real instruction
15737 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15738 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15739 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15740 * bail to the real handler if breakFlags==0.
15741 */
15742    ldrb   r3, [rSELF, #offThread_breakFlags]
15743    adrl   lr, dvmAsmInstructionStart + (240 * 64)
15744    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15745    cmp    r3, #0
15746    bxeq   lr                   @ nothing to do - jump to real handler
15747    EXPORT_PC()
15748    mov    r0, rPC              @ arg0
15749    mov    r1, rFP              @ arg1
15750    mov    r2, rSELF            @ arg2
15751    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15752
15753/* ------------------------------ */
15754    .balign 64
15755.L_ALT_OP_RETURN_VOID_BARRIER: /* 0xf1 */
15756/* File: armv5te/alt_stub.S */
15757/*
15758 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15759 * any interesting requests and then jump to the real instruction
15760 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15761 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15762 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15763 * bail to the real handler if breakFlags==0.
15764 */
15765    ldrb   r3, [rSELF, #offThread_breakFlags]
15766    adrl   lr, dvmAsmInstructionStart + (241 * 64)
15767    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15768    cmp    r3, #0
15769    bxeq   lr                   @ nothing to do - jump to real handler
15770    EXPORT_PC()
15771    mov    r0, rPC              @ arg0
15772    mov    r1, rFP              @ arg1
15773    mov    r2, rSELF            @ arg2
15774    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15775
15776/* ------------------------------ */
15777    .balign 64
15778.L_ALT_OP_IGET_QUICK: /* 0xf2 */
15779/* File: armv5te/alt_stub.S */
15780/*
15781 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15782 * any interesting requests and then jump to the real instruction
15783 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15784 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15785 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15786 * bail to the real handler if breakFlags==0.
15787 */
15788    ldrb   r3, [rSELF, #offThread_breakFlags]
15789    adrl   lr, dvmAsmInstructionStart + (242 * 64)
15790    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15791    cmp    r3, #0
15792    bxeq   lr                   @ nothing to do - jump to real handler
15793    EXPORT_PC()
15794    mov    r0, rPC              @ arg0
15795    mov    r1, rFP              @ arg1
15796    mov    r2, rSELF            @ arg2
15797    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15798
15799/* ------------------------------ */
15800    .balign 64
15801.L_ALT_OP_IGET_WIDE_QUICK: /* 0xf3 */
15802/* File: armv5te/alt_stub.S */
15803/*
15804 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15805 * any interesting requests and then jump to the real instruction
15806 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15807 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15808 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15809 * bail to the real handler if breakFlags==0.
15810 */
15811    ldrb   r3, [rSELF, #offThread_breakFlags]
15812    adrl   lr, dvmAsmInstructionStart + (243 * 64)
15813    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15814    cmp    r3, #0
15815    bxeq   lr                   @ nothing to do - jump to real handler
15816    EXPORT_PC()
15817    mov    r0, rPC              @ arg0
15818    mov    r1, rFP              @ arg1
15819    mov    r2, rSELF            @ arg2
15820    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15821
15822/* ------------------------------ */
15823    .balign 64
15824.L_ALT_OP_IGET_OBJECT_QUICK: /* 0xf4 */
15825/* File: armv5te/alt_stub.S */
15826/*
15827 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15828 * any interesting requests and then jump to the real instruction
15829 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15830 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15831 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15832 * bail to the real handler if breakFlags==0.
15833 */
15834    ldrb   r3, [rSELF, #offThread_breakFlags]
15835    adrl   lr, dvmAsmInstructionStart + (244 * 64)
15836    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15837    cmp    r3, #0
15838    bxeq   lr                   @ nothing to do - jump to real handler
15839    EXPORT_PC()
15840    mov    r0, rPC              @ arg0
15841    mov    r1, rFP              @ arg1
15842    mov    r2, rSELF            @ arg2
15843    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15844
15845/* ------------------------------ */
15846    .balign 64
15847.L_ALT_OP_IPUT_QUICK: /* 0xf5 */
15848/* File: armv5te/alt_stub.S */
15849/*
15850 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15851 * any interesting requests and then jump to the real instruction
15852 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15853 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15854 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15855 * bail to the real handler if breakFlags==0.
15856 */
15857    ldrb   r3, [rSELF, #offThread_breakFlags]
15858    adrl   lr, dvmAsmInstructionStart + (245 * 64)
15859    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15860    cmp    r3, #0
15861    bxeq   lr                   @ nothing to do - jump to real handler
15862    EXPORT_PC()
15863    mov    r0, rPC              @ arg0
15864    mov    r1, rFP              @ arg1
15865    mov    r2, rSELF            @ arg2
15866    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15867
15868/* ------------------------------ */
15869    .balign 64
15870.L_ALT_OP_IPUT_WIDE_QUICK: /* 0xf6 */
15871/* File: armv5te/alt_stub.S */
15872/*
15873 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15874 * any interesting requests and then jump to the real instruction
15875 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15876 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15877 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15878 * bail to the real handler if breakFlags==0.
15879 */
15880    ldrb   r3, [rSELF, #offThread_breakFlags]
15881    adrl   lr, dvmAsmInstructionStart + (246 * 64)
15882    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15883    cmp    r3, #0
15884    bxeq   lr                   @ nothing to do - jump to real handler
15885    EXPORT_PC()
15886    mov    r0, rPC              @ arg0
15887    mov    r1, rFP              @ arg1
15888    mov    r2, rSELF            @ arg2
15889    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15890
15891/* ------------------------------ */
15892    .balign 64
15893.L_ALT_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
15894/* File: armv5te/alt_stub.S */
15895/*
15896 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15897 * any interesting requests and then jump to the real instruction
15898 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15899 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15900 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15901 * bail to the real handler if breakFlags==0.
15902 */
15903    ldrb   r3, [rSELF, #offThread_breakFlags]
15904    adrl   lr, dvmAsmInstructionStart + (247 * 64)
15905    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15906    cmp    r3, #0
15907    bxeq   lr                   @ nothing to do - jump to real handler
15908    EXPORT_PC()
15909    mov    r0, rPC              @ arg0
15910    mov    r1, rFP              @ arg1
15911    mov    r2, rSELF            @ arg2
15912    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15913
15914/* ------------------------------ */
15915    .balign 64
15916.L_ALT_OP_INVOKE_VIRTUAL_QUICK: /* 0xf8 */
15917/* File: armv5te/alt_stub.S */
15918/*
15919 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15920 * any interesting requests and then jump to the real instruction
15921 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15922 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15923 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15924 * bail to the real handler if breakFlags==0.
15925 */
15926    ldrb   r3, [rSELF, #offThread_breakFlags]
15927    adrl   lr, dvmAsmInstructionStart + (248 * 64)
15928    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15929    cmp    r3, #0
15930    bxeq   lr                   @ nothing to do - jump to real handler
15931    EXPORT_PC()
15932    mov    r0, rPC              @ arg0
15933    mov    r1, rFP              @ arg1
15934    mov    r2, rSELF            @ arg2
15935    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15936
15937/* ------------------------------ */
15938    .balign 64
15939.L_ALT_OP_INVOKE_VIRTUAL_QUICK_RANGE: /* 0xf9 */
15940/* File: armv5te/alt_stub.S */
15941/*
15942 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15943 * any interesting requests and then jump to the real instruction
15944 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15945 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15946 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15947 * bail to the real handler if breakFlags==0.
15948 */
15949    ldrb   r3, [rSELF, #offThread_breakFlags]
15950    adrl   lr, dvmAsmInstructionStart + (249 * 64)
15951    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15952    cmp    r3, #0
15953    bxeq   lr                   @ nothing to do - jump to real handler
15954    EXPORT_PC()
15955    mov    r0, rPC              @ arg0
15956    mov    r1, rFP              @ arg1
15957    mov    r2, rSELF            @ arg2
15958    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15959
15960/* ------------------------------ */
15961    .balign 64
15962.L_ALT_OP_INVOKE_SUPER_QUICK: /* 0xfa */
15963/* File: armv5te/alt_stub.S */
15964/*
15965 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15966 * any interesting requests and then jump to the real instruction
15967 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15968 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15969 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15970 * bail to the real handler if breakFlags==0.
15971 */
15972    ldrb   r3, [rSELF, #offThread_breakFlags]
15973    adrl   lr, dvmAsmInstructionStart + (250 * 64)
15974    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15975    cmp    r3, #0
15976    bxeq   lr                   @ nothing to do - jump to real handler
15977    EXPORT_PC()
15978    mov    r0, rPC              @ arg0
15979    mov    r1, rFP              @ arg1
15980    mov    r2, rSELF            @ arg2
15981    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
15982
15983/* ------------------------------ */
15984    .balign 64
15985.L_ALT_OP_INVOKE_SUPER_QUICK_RANGE: /* 0xfb */
15986/* File: armv5te/alt_stub.S */
15987/*
15988 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
15989 * any interesting requests and then jump to the real instruction
15990 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
15991 * rIBASE updates won't be seen until a refresh, and we can tell we have a
15992 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
15993 * bail to the real handler if breakFlags==0.
15994 */
15995    ldrb   r3, [rSELF, #offThread_breakFlags]
15996    adrl   lr, dvmAsmInstructionStart + (251 * 64)
15997    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
15998    cmp    r3, #0
15999    bxeq   lr                   @ nothing to do - jump to real handler
16000    EXPORT_PC()
16001    mov    r0, rPC              @ arg0
16002    mov    r1, rFP              @ arg1
16003    mov    r2, rSELF            @ arg2
16004    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
16005
16006/* ------------------------------ */
16007    .balign 64
16008.L_ALT_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
16009/* File: armv5te/alt_stub.S */
16010/*
16011 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
16012 * any interesting requests and then jump to the real instruction
16013 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
16014 * rIBASE updates won't be seen until a refresh, and we can tell we have a
16015 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
16016 * bail to the real handler if breakFlags==0.
16017 */
16018    ldrb   r3, [rSELF, #offThread_breakFlags]
16019    adrl   lr, dvmAsmInstructionStart + (252 * 64)
16020    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
16021    cmp    r3, #0
16022    bxeq   lr                   @ nothing to do - jump to real handler
16023    EXPORT_PC()
16024    mov    r0, rPC              @ arg0
16025    mov    r1, rFP              @ arg1
16026    mov    r2, rSELF            @ arg2
16027    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
16028
16029/* ------------------------------ */
16030    .balign 64
16031.L_ALT_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
16032/* File: armv5te/alt_stub.S */
16033/*
16034 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
16035 * any interesting requests and then jump to the real instruction
16036 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
16037 * rIBASE updates won't be seen until a refresh, and we can tell we have a
16038 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
16039 * bail to the real handler if breakFlags==0.
16040 */
16041    ldrb   r3, [rSELF, #offThread_breakFlags]
16042    adrl   lr, dvmAsmInstructionStart + (253 * 64)
16043    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
16044    cmp    r3, #0
16045    bxeq   lr                   @ nothing to do - jump to real handler
16046    EXPORT_PC()
16047    mov    r0, rPC              @ arg0
16048    mov    r1, rFP              @ arg1
16049    mov    r2, rSELF            @ arg2
16050    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
16051
16052/* ------------------------------ */
16053    .balign 64
16054.L_ALT_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
16055/* File: armv5te/alt_stub.S */
16056/*
16057 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
16058 * any interesting requests and then jump to the real instruction
16059 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
16060 * rIBASE updates won't be seen until a refresh, and we can tell we have a
16061 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
16062 * bail to the real handler if breakFlags==0.
16063 */
16064    ldrb   r3, [rSELF, #offThread_breakFlags]
16065    adrl   lr, dvmAsmInstructionStart + (254 * 64)
16066    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
16067    cmp    r3, #0
16068    bxeq   lr                   @ nothing to do - jump to real handler
16069    EXPORT_PC()
16070    mov    r0, rPC              @ arg0
16071    mov    r1, rFP              @ arg1
16072    mov    r2, rSELF            @ arg2
16073    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
16074
16075/* ------------------------------ */
16076    .balign 64
16077.L_ALT_OP_UNUSED_FF: /* 0xff */
16078/* File: armv5te/alt_stub.S */
16079/*
16080 * Inter-instruction transfer stub.  Call out to dvmCheckBefore to handle
16081 * any interesting requests and then jump to the real instruction
16082 * handler.    Note that the call to dvmCheckBefore is done as a tail call.
16083 * rIBASE updates won't be seen until a refresh, and we can tell we have a
16084 * stale rIBASE if breakFlags==0.  Always refresh rIBASE here, and then
16085 * bail to the real handler if breakFlags==0.
16086 */
16087    ldrb   r3, [rSELF, #offThread_breakFlags]
16088    adrl   lr, dvmAsmInstructionStart + (255 * 64)
16089    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
16090    cmp    r3, #0
16091    bxeq   lr                   @ nothing to do - jump to real handler
16092    EXPORT_PC()
16093    mov    r0, rPC              @ arg0
16094    mov    r1, rFP              @ arg1
16095    mov    r2, rSELF            @ arg2
16096    b      dvmCheckBefore       @ (dPC,dFP,self) tail call
16097
16098    .balign 64
16099    .size   dvmAsmAltInstructionStart, .-dvmAsmAltInstructionStart
16100    .global dvmAsmAltInstructionEnd
16101dvmAsmAltInstructionEnd:
16102/* File: armv5te/footer.S */
16103/*
16104 * ===========================================================================
16105 *  Common subroutines and data
16106 * ===========================================================================
16107 */
16108
16109    .text
16110    .align  2
16111
16112#if defined(WITH_JIT)
16113
16114#if defined(WITH_SELF_VERIFICATION)
16115/*
16116 * "longjmp" to a translation after single-stepping.  Before returning
16117 * to translation, must save state for self-verification.
16118 */
16119    .global dvmJitResumeTranslation              @ (Thread* self, u4* dFP)
16120dvmJitResumeTranslation:
16121    mov    rSELF, r0                             @ restore self
16122    mov    rPC, r1                               @ restore Dalvik pc
16123    mov    rFP, r2                               @ restore Dalvik fp
16124    ldr    r10, [rSELF,#offThread_jitResumeNPC]  @ resume address
16125    mov    r2, #0
16126    str    r2, [rSELF,#offThread_jitResumeNPC]   @ reset resume address
16127    ldr    sp, [rSELF,#offThread_jitResumeNSP]   @ cut back native stack
16128    b      jitSVShadowRunStart                   @ resume as if cache hit
16129                                                 @ expects resume addr in r10
16130
16131    .global dvmJitToInterpPunt
16132dvmJitToInterpPunt:
16133    mov    r2,#kSVSPunt                 @ r2<- interpreter entry point
16134    mov    r3, #0
16135    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
16136    b      jitSVShadowRunEnd            @ doesn't return
16137
16138    .global dvmJitToInterpSingleStep
16139dvmJitToInterpSingleStep:
16140    mov    rPC, r0              @ set up dalvik pc
16141    EXPORT_PC()
16142    str    lr, [rSELF,#offThread_jitResumeNPC]
16143    str    sp, [rSELF,#offThread_jitResumeNSP]
16144    str    r1, [rSELF,#offThread_jitResumeDPC]
16145    mov    r2,#kSVSSingleStep           @ r2<- interpreter entry point
16146    b      jitSVShadowRunEnd            @ doesn't return
16147
16148
16149    .global dvmJitToInterpNoChainNoProfile
16150dvmJitToInterpNoChainNoProfile:
16151    mov    r0,rPC                       @ pass our target PC
16152    mov    r2,#kSVSNoProfile            @ r2<- interpreter entry point
16153    mov    r3, #0                       @ 0 means !inJitCodeCache
16154    str    r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land
16155    b      jitSVShadowRunEnd            @ doesn't return
16156
16157    .global dvmJitToInterpTraceSelectNoChain
16158dvmJitToInterpTraceSelectNoChain:
16159    mov    r0,rPC                       @ pass our target PC
16160    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
16161    mov    r3, #0                       @ 0 means !inJitCodeCache
16162    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
16163    b      jitSVShadowRunEnd            @ doesn't return
16164
16165    .global dvmJitToInterpTraceSelect
16166dvmJitToInterpTraceSelect:
16167    ldr    r0,[lr, #-1]                 @ pass our target PC
16168    mov    r2,#kSVSTraceSelect          @ r2<- interpreter entry point
16169    mov    r3, #0                       @ 0 means !inJitCodeCache
16170    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
16171    b      jitSVShadowRunEnd            @ doesn't return
16172
16173    .global dvmJitToInterpBackwardBranch
16174dvmJitToInterpBackwardBranch:
16175    ldr    r0,[lr, #-1]                 @ pass our target PC
16176    mov    r2,#kSVSBackwardBranch       @ r2<- interpreter entry point
16177    mov    r3, #0                       @ 0 means !inJitCodeCache
16178    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
16179    b      jitSVShadowRunEnd            @ doesn't return
16180
16181    .global dvmJitToInterpNormal
16182dvmJitToInterpNormal:
16183    ldr    r0,[lr, #-1]                 @ pass our target PC
16184    mov    r2,#kSVSNormal               @ r2<- interpreter entry point
16185    mov    r3, #0                       @ 0 means !inJitCodeCache
16186    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
16187    b      jitSVShadowRunEnd            @ doesn't return
16188
16189    .global dvmJitToInterpNoChain
16190dvmJitToInterpNoChain:
16191    mov    r0,rPC                       @ pass our target PC
16192    mov    r2,#kSVSNoChain              @ r2<- interpreter entry point
16193    mov    r3, #0                       @ 0 means !inJitCodeCache
16194    str    r3, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
16195    b      jitSVShadowRunEnd            @ doesn't return
16196#else
16197
16198/*
16199 * "longjmp" to a translation after single-stepping.
16200 */
16201    .global dvmJitResumeTranslation              @ (Thread* self, u4* dFP)
16202dvmJitResumeTranslation:
16203    mov    rSELF, r0                             @ restore self
16204    mov    rPC, r1                               @ restore Dalvik pc
16205    mov    rFP, r2                               @ restore Dalvik fp
16206    ldr    r0, [rSELF,#offThread_jitResumeNPC]
16207    mov    r2, #0
16208    str    r2, [rSELF,#offThread_jitResumeNPC]   @ reset resume address
16209    ldr    sp, [rSELF,#offThread_jitResumeNSP]   @ cut back native stack
16210    bx     r0                                    @ resume translation
16211
16212/*
16213 * Return from the translation cache to the interpreter when the compiler is
16214 * having issues translating/executing a Dalvik instruction. We have to skip
16215 * the code cache lookup otherwise it is possible to indefinitely bouce
16216 * between the interpreter and the code cache if the instruction that fails
16217 * to be compiled happens to be at a trace start.
16218 */
16219    .global dvmJitToInterpPunt
16220dvmJitToInterpPunt:
16221    mov    rPC, r0
16222#if defined(WITH_JIT_TUNING)
16223    mov    r0,lr
16224    bl     dvmBumpPunt;
16225#endif
16226    EXPORT_PC()
16227    mov    r0, #0
16228    str    r0, [rSELF, #offThread_inJitCodeCache] @ Back to the interp land
16229    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
16230    FETCH_INST()
16231    GET_INST_OPCODE(ip)
16232    GOTO_OPCODE(ip)
16233
16234/*
16235 * Return to the interpreter to handle a single instruction.
16236 * We'll use the normal single-stepping mechanism via interpBreak,
16237 * but also save the native pc of the resume point in the translation
16238 * and the native sp so that we can later do the equivalent of a
16239 * longjmp() to resume.
16240 * On entry:
16241 *    dPC <= Dalvik PC of instrucion to interpret
16242 *    lr <= resume point in translation
16243 *    r1 <= Dalvik PC of next instruction
16244 */
16245    .global dvmJitToInterpSingleStep
16246dvmJitToInterpSingleStep:
16247    mov    rPC, r0              @ set up dalvik pc
16248    EXPORT_PC()
16249    str    lr, [rSELF,#offThread_jitResumeNPC]
16250    str    sp, [rSELF,#offThread_jitResumeNSP]
16251    str    r1, [rSELF,#offThread_jitResumeDPC]
16252    mov    r1, #1
16253    str    r1, [rSELF,#offThread_singleStepCount]  @ just step once
16254    mov    r0, rSELF
16255    mov    r1, #kSubModeCountedStep
16256    bl     dvmEnableSubMode     @ (self, newMode)
16257    ldr    rIBASE, [rSELF,#offThread_curHandlerTable]
16258    FETCH_INST()
16259    GET_INST_OPCODE(ip)
16260    GOTO_OPCODE(ip)
16261
16262/*
16263 * Return from the translation cache and immediately request
16264 * a translation for the exit target.  Commonly used for callees.
16265 */
16266    .global dvmJitToInterpTraceSelectNoChain
16267dvmJitToInterpTraceSelectNoChain:
16268#if defined(WITH_JIT_TUNING)
16269    bl     dvmBumpNoChain
16270#endif
16271    mov    r0,rPC
16272    mov    r1,rSELF
16273    bl     dvmJitGetTraceAddrThread @ (pc, self)
16274    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
16275    mov    r1, rPC                  @ arg1 of translation may need this
16276    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
16277    cmp    r0,#0                    @ !0 means translation exists
16278    bxne   r0                       @ continue native execution if so
16279    b      2f                       @ branch over to use the interpreter
16280
16281/*
16282 * Return from the translation cache and immediately request
16283 * a translation for the exit target.  Commonly used following
16284 * invokes.
16285 */
16286    .global dvmJitToInterpTraceSelect
16287dvmJitToInterpTraceSelect:
16288    ldr    rPC,[lr, #-1]           @ get our target PC
16289    add    rINST,lr,#-5            @ save start of chain branch
16290    add    rINST, #-4              @  .. which is 9 bytes back
16291    mov    r0,rPC
16292    mov    r1,rSELF
16293    bl     dvmJitGetTraceAddrThread @ (pc, self)
16294    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
16295    cmp    r0,#0
16296    beq    2f
16297    mov    r1,rINST
16298    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
16299    mov    r1, rPC                  @ arg1 of translation may need this
16300    mov    lr, #0                   @ in case target is HANDLER_INTERPRET
16301    cmp    r0,#0                    @ successful chain?
16302    bxne   r0                       @ continue native execution
16303    b      toInterpreter            @ didn't chain - resume with interpreter
16304
16305/* No translation, so request one if profiling isn't disabled*/
163062:
16307    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
16308    ldr    r0, [rSELF, #offThread_pJitProfTable]
16309    FETCH_INST()
16310    cmp    r0, #0
16311    movne  r2,#kJitTSelectRequestHot   @ ask for trace selection
16312    bne    common_selectTrace
16313    GET_INST_OPCODE(ip)
16314    GOTO_OPCODE(ip)
16315
16316/*
16317 * Return from the translation cache to the interpreter.
16318 * The return was done with a BLX from thumb mode, and
16319 * the following 32-bit word contains the target rPC value.
16320 * Note that lr (r14) will have its low-order bit set to denote
16321 * its thumb-mode origin.
16322 *
16323 * We'll need to stash our lr origin away, recover the new
16324 * target and then check to see if there is a translation available
16325 * for our new target.  If so, we do a translation chain and
16326 * go back to native execution.  Otherwise, it's back to the
16327 * interpreter (after treating this entry as a potential
16328 * trace start).
16329 */
16330    .global dvmJitToInterpNormal
16331dvmJitToInterpNormal:
16332    ldr    rPC,[lr, #-1]           @ get our target PC
16333    add    rINST,lr,#-5            @ save start of chain branch
16334    add    rINST,#-4               @ .. which is 9 bytes back
16335#if defined(WITH_JIT_TUNING)
16336    bl     dvmBumpNormal
16337#endif
16338    mov    r0,rPC
16339    mov    r1,rSELF
16340    bl     dvmJitGetTraceAddrThread @ (pc, self)
16341    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
16342    cmp    r0,#0
16343    beq    toInterpreter            @ go if not, otherwise do chain
16344    mov    r1,rINST
16345    bl     dvmJitChain              @ r0<- dvmJitChain(codeAddr,chainAddr)
16346    mov    r1, rPC                  @ arg1 of translation may need this
16347    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
16348    cmp    r0,#0                    @ successful chain?
16349    bxne   r0                       @ continue native execution
16350    b      toInterpreter            @ didn't chain - resume with interpreter
16351
16352/*
16353 * Return from the translation cache to the interpreter to do method invocation.
16354 * Check if translation exists for the callee, but don't chain to it.
16355 */
16356    .global dvmJitToInterpNoChainNoProfile
16357dvmJitToInterpNoChainNoProfile:
16358#if defined(WITH_JIT_TUNING)
16359    bl     dvmBumpNoChain
16360#endif
16361    mov    r0,rPC
16362    mov    r1,rSELF
16363    bl     dvmJitGetTraceAddrThread @ (pc, self)
16364    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
16365    mov    r1, rPC                  @ arg1 of translation may need this
16366    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
16367    cmp    r0,#0
16368    bxne   r0                       @ continue native execution if so
16369    EXPORT_PC()
16370    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
16371    FETCH_INST()
16372    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
16373    GOTO_OPCODE(ip)                     @ jump to next instruction
16374
16375/*
16376 * Return from the translation cache to the interpreter to do method invocation.
16377 * Check if translation exists for the callee, but don't chain to it.
16378 */
16379    .global dvmJitToInterpNoChain
16380dvmJitToInterpNoChain:
16381#if defined(WITH_JIT_TUNING)
16382    bl     dvmBumpNoChain
16383#endif
16384    mov    r0,rPC
16385    mov    r1,rSELF
16386    bl     dvmJitGetTraceAddrThread @ (pc, self)
16387    str    r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
16388    mov    r1, rPC                  @ arg1 of translation may need this
16389    mov    lr, #0                   @  in case target is HANDLER_INTERPRET
16390    cmp    r0,#0
16391    bxne   r0                       @ continue native execution if so
16392#endif
16393
16394/*
16395 * No translation, restore interpreter regs and start interpreting.
16396 * rSELF & rFP were preserved in the translated code, and rPC has
16397 * already been restored by the time we get here.  We'll need to set
16398 * up rIBASE & rINST, and load the address of the JitTable into r0.
16399 */
16400toInterpreter:
16401    EXPORT_PC()
16402    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
16403    FETCH_INST()
16404    ldr    r0, [rSELF, #offThread_pJitProfTable]
16405    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
16406    @ NOTE: intended fallthrough
16407
16408/*
16409 * Similar to common_updateProfile, but tests for null pJitProfTable
16410 * r0 holds pJifProfTAble, rINST is loaded, rPC is current and
16411 * rIBASE has been recently refreshed.
16412 */
16413common_testUpdateProfile:
16414    cmp     r0, #0               @ JIT switched off?
16415    beq     4f                   @ return to interp if so
16416
16417/*
16418 * Common code to update potential trace start counter, and initiate
16419 * a trace-build if appropriate.
16420 * On entry here:
16421 *    r0    <= pJitProfTable (verified non-NULL)
16422 *    rPC   <= Dalvik PC
16423 *    rINST <= next instruction
16424 */
16425common_updateProfile:
16426    eor     r3,rPC,rPC,lsr #12 @ cheap, but fast hash function
16427    lsl     r3,r3,#(32 - JIT_PROF_SIZE_LOG_2)          @ shift out excess bits
16428    ldrb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ get counter
16429    GET_INST_OPCODE(ip)
16430    subs    r1,r1,#1           @ decrement counter
16431    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ and store it
16432    GOTO_OPCODE_IFNE(ip)       @ if not threshold, fallthrough otherwise */
16433
16434    /* Looks good, reset the counter */
16435    ldr     r1, [rSELF, #offThread_jitThreshold]
16436    strb    r1,[r0,r3,lsr #(32 - JIT_PROF_SIZE_LOG_2)] @ reset counter
16437    EXPORT_PC()
16438    mov     r0,rPC
16439    mov     r1,rSELF
16440    bl      dvmJitGetTraceAddrThread    @ (pc, self)
16441    str     r0, [rSELF, #offThread_inJitCodeCache] @ set the inJitCodeCache flag
16442    mov     r1, rPC                     @ arg1 of translation may need this
16443    mov     lr, #0                      @  in case target is HANDLER_INTERPRET
16444    cmp     r0,#0
16445#if !defined(WITH_SELF_VERIFICATION)
16446    bxne    r0                          @ jump to the translation
16447    mov     r2,#kJitTSelectRequest      @ ask for trace selection
16448    @ fall-through to common_selectTrace
16449#else
16450    moveq   r2,#kJitTSelectRequest      @ ask for trace selection
16451    beq     common_selectTrace
16452    /*
16453     * At this point, we have a target translation.  However, if
16454     * that translation is actually the interpret-only pseudo-translation
16455     * we want to treat it the same as no translation.
16456     */
16457    mov     r10, r0                     @ save target
16458    bl      dvmCompilerGetInterpretTemplate
16459    cmp     r0, r10                     @ special case?
16460    bne     jitSVShadowRunStart         @ set up self verification shadow space
16461    @ Need to clear the inJitCodeCache flag
16462    mov    r3, #0                       @ 0 means not in the JIT code cache
16463    str    r3, [rSELF, #offThread_inJitCodeCache] @ back to the interp land
16464    GET_INST_OPCODE(ip)
16465    GOTO_OPCODE(ip)
16466    /* no return */
16467#endif
16468
16469/*
16470 * On entry:
16471 *  r2 is jit state.
16472 */
16473common_selectTrace:
16474    ldrh    r0,[rSELF,#offThread_subMode]
16475    ands    r0, #(kSubModeJitTraceBuild | kSubModeJitSV)
16476    bne     3f                         @ already doing JIT work, continue
16477    str     r2,[rSELF,#offThread_jitState]
16478    mov     r0, rSELF
16479/*
16480 * Call out to validate trace-building request.  If successful,
16481 * rIBASE will be swapped to to send us into single-stepping trace
16482 * building mode, so we need to refresh before we continue.
16483 */
16484    EXPORT_PC()
16485    SAVE_PC_FP_TO_SELF()                 @ copy of pc/fp to Thread
16486    bl      dvmJitCheckTraceRequest
164873:
16488    FETCH_INST()
16489    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
164904:
16491    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
16492    GOTO_OPCODE(ip)
16493    /* no return */
16494#endif
16495
16496#if defined(WITH_SELF_VERIFICATION)
16497/*
16498 * Save PC and registers to shadow memory for self verification mode
16499 * before jumping to native translation.
16500 * On entry:
16501 *    rPC, rFP, rSELF: the values that they should contain
16502 *    r10: the address of the target translation.
16503 */
16504jitSVShadowRunStart:
16505    mov     r0,rPC                      @ r0<- program counter
16506    mov     r1,rFP                      @ r1<- frame pointer
16507    mov     r2,rSELF                    @ r2<- self (Thread) pointer
16508    mov     r3,r10                      @ r3<- target translation
16509    bl      dvmSelfVerificationSaveState @ save registers to shadow space
16510    ldr     rFP,[r0,#offShadowSpace_shadowFP] @ rFP<- fp in shadow space
16511    bx      r10                         @ jump to the translation
16512
16513/*
16514 * Restore PC, registers, and interpreter state to original values
16515 * before jumping back to the interpreter.
16516 * On entry:
16517 *   r0:  dPC
16518 *   r2:  self verification state
16519 */
16520jitSVShadowRunEnd:
16521    mov    r1,rFP                        @ pass ending fp
16522    mov    r3,rSELF                      @ pass self ptr for convenience
16523    bl     dvmSelfVerificationRestoreState @ restore pc and fp values
16524    LOAD_PC_FP_FROM_SELF()               @ restore pc, fp
16525    ldr    r1,[r0,#offShadowSpace_svState] @ get self verification state
16526    cmp    r1,#0                         @ check for punt condition
16527    beq    1f
16528    @ Set up SV single-stepping
16529    mov    r0, rSELF
16530    mov    r1, #kSubModeJitSV
16531    bl     dvmEnableSubMode              @ (self, subMode)
16532    mov    r2,#kJitSelfVerification      @ ask for self verification
16533    str    r2,[rSELF,#offThread_jitState]
16534    @ intentional fallthrough
165351:                                       @ exit to interpreter without check
16536    EXPORT_PC()
16537    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]
16538    FETCH_INST()
16539    GET_INST_OPCODE(ip)
16540    GOTO_OPCODE(ip)
16541#endif
16542
16543/*
16544 * The equivalent of "goto bail", this calls through the "bail handler".
16545 * It will end this interpreter activation, and return to the caller
16546 * of dvmMterpStdRun.
16547 *
16548 * State registers will be saved to the "thread" area before bailing
16549 * debugging purposes
16550 */
16551common_gotoBail:
16552    SAVE_PC_FP_TO_SELF()                @ export state to "thread"
16553    mov     r0, rSELF                   @ r0<- self ptr
16554    b       dvmMterpStdBail             @ call(self, changeInterp)
16555
16556/*
16557 * The JIT's invoke method needs to remember the callsite class and
16558 * target pair.  Save them here so that they are available to
16559 * dvmCheckJit following the interpretation of this invoke.
16560 */
16561#if defined(WITH_JIT)
16562save_callsiteinfo:
16563    cmp     r9, #0
16564    ldrne   r9, [r9, #offObject_clazz]
16565    str     r0, [rSELF, #offThread_methodToCall]
16566    str     r9, [rSELF, #offThread_callsiteClass]
16567    bx      lr
16568#endif
16569
16570/*
16571 * Common code for method invocation with range.
16572 *
16573 * On entry:
16574 *  r0 is "Method* methodToCall", r9 is "this"
16575 */
16576common_invokeMethodRange:
16577.LinvokeNewRange:
16578#if defined(WITH_JIT)
16579    ldrh    r1, [rSELF, #offThread_subMode]
16580    ands    r1, #kSubModeJitTraceBuild
16581    blne    save_callsiteinfo
16582#endif
16583    @ prepare to copy args to "outs" area of current frame
16584    movs    r2, rINST, lsr #8           @ r2<- AA (arg count) -- test for zero
16585    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
16586    beq     .LinvokeArgsDone            @ if no args, skip the rest
16587    FETCH(r1, 2)                        @ r1<- CCCC
16588
16589.LinvokeRangeArgs:
16590    @ r0=methodToCall, r1=CCCC, r2=count, r10=outs
16591    @ (very few methods have > 10 args; could unroll for common cases)
16592    add     r3, rFP, r1, lsl #2         @ r3<- &fp[CCCC]
16593    sub     r10, r10, r2, lsl #2        @ r10<- "outs" area, for call args
165941:  ldr     r1, [r3], #4                @ val = *fp++
16595    subs    r2, r2, #1                  @ count--
16596    str     r1, [r10], #4               @ *outs++ = val
16597    bne     1b                          @ ...while count != 0
16598    b       .LinvokeArgsDone
16599
16600/*
16601 * Common code for method invocation without range.
16602 *
16603 * On entry:
16604 *  r0 is "Method* methodToCall", r9 is "this"
16605 */
16606common_invokeMethodNoRange:
16607.LinvokeNewNoRange:
16608#if defined(WITH_JIT)
16609    ldrh    r1, [rSELF, #offThread_subMode]
16610    ands    r1, #kSubModeJitTraceBuild
16611    blne    save_callsiteinfo
16612#endif
16613    @ prepare to copy args to "outs" area of current frame
16614    movs    r2, rINST, lsr #12          @ r2<- B (arg count) -- test for zero
16615    SAVEAREA_FROM_FP(r10, rFP)          @ r10<- stack save area
16616    FETCH(r1, 2)                        @ r1<- GFED (load here to hide latency)
16617    beq     .LinvokeArgsDone
16618
16619    @ r0=methodToCall, r1=GFED, r2=count, r10=outs
16620.LinvokeNonRange:
16621    rsb     r2, r2, #5                  @ r2<- 5-r2
16622    add     pc, pc, r2, lsl #4          @ computed goto, 4 instrs each
16623    bl      common_abort                @ (skipped due to ARM prefetch)
166245:  and     ip, rINST, #0x0f00          @ isolate A
16625    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vA (shift right 8, left 2)
16626    mov     r0, r0                      @ nop
16627    str     r2, [r10, #-4]!             @ *--outs = vA
166284:  and     ip, r1, #0xf000             @ isolate G
16629    ldr     r2, [rFP, ip, lsr #10]      @ r2<- vG (shift right 12, left 2)
16630    mov     r0, r0                      @ nop
16631    str     r2, [r10, #-4]!             @ *--outs = vG
166323:  and     ip, r1, #0x0f00             @ isolate F
16633    ldr     r2, [rFP, ip, lsr #6]       @ r2<- vF
16634    mov     r0, r0                      @ nop
16635    str     r2, [r10, #-4]!             @ *--outs = vF
166362:  and     ip, r1, #0x00f0             @ isolate E
16637    ldr     r2, [rFP, ip, lsr #2]       @ r2<- vE
16638    mov     r0, r0                      @ nop
16639    str     r2, [r10, #-4]!             @ *--outs = vE
166401:  and     ip, r1, #0x000f             @ isolate D
16641    ldr     r2, [rFP, ip, lsl #2]       @ r2<- vD
16642    mov     r0, r0                      @ nop
16643    str     r2, [r10, #-4]!             @ *--outs = vD
166440:  @ fall through to .LinvokeArgsDone
16645
16646.LinvokeArgsDone: @ r0=methodToCall
16647    ldrh    r9, [r0, #offMethod_registersSize]  @ r9<- methodToCall->regsSize
16648    ldrh    r3, [r0, #offMethod_outsSize]  @ r3<- methodToCall->outsSize
16649    ldr     r2, [r0, #offMethod_insns]  @ r2<- method->insns
16650    ldr     rINST, [r0, #offMethod_clazz]  @ rINST<- method->clazz
16651    @ find space for the new stack frame, check for overflow
16652    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- stack save area
16653    sub     r1, r1, r9, lsl #2          @ r1<- newFp (old savearea - regsSize)
16654    SAVEAREA_FROM_FP(r10, r1)           @ r10<- newSaveArea
16655@    bl      common_dumpRegs
16656    ldr     r9, [rSELF, #offThread_interpStackEnd]    @ r9<- interpStackEnd
16657    sub     r3, r10, r3, lsl #2         @ r3<- bottom (newsave - outsSize)
16658    cmp     r3, r9                      @ bottom < interpStackEnd?
16659    ldrh    lr, [rSELF, #offThread_subMode]
16660    ldr     r3, [r0, #offMethod_accessFlags] @ r3<- methodToCall->accessFlags
16661    blo     .LstackOverflow             @ yes, this frame will overflow stack
16662
16663    @ set up newSaveArea
16664#ifdef EASY_GDB
16665    SAVEAREA_FROM_FP(ip, rFP)           @ ip<- stack save area
16666    str     ip, [r10, #offStackSaveArea_prevSave]
16667#endif
16668    str     rFP, [r10, #offStackSaveArea_prevFrame]
16669    str     rPC, [r10, #offStackSaveArea_savedPc]
16670#if defined(WITH_JIT)
16671    mov     r9, #0
16672    str     r9, [r10, #offStackSaveArea_returnAddr]
16673#endif
16674    str     r0, [r10, #offStackSaveArea_method]
16675
16676    @ Profiling?
16677    cmp     lr, #0                      @ any special modes happening?
16678    bne     2f                          @ go if so
166791:
16680    tst     r3, #ACC_NATIVE
16681    bne     .LinvokeNative
16682
16683    /*
16684    stmfd   sp!, {r0-r3}
16685    bl      common_printNewline
16686    mov     r0, rFP
16687    mov     r1, #0
16688    bl      dvmDumpFp
16689    ldmfd   sp!, {r0-r3}
16690    stmfd   sp!, {r0-r3}
16691    mov     r0, r1
16692    mov     r1, r10
16693    bl      dvmDumpFp
16694    bl      common_printNewline
16695    ldmfd   sp!, {r0-r3}
16696    */
16697
16698    ldrh    r9, [r2]                        @ r9 <- load INST from new PC
16699    ldr     r3, [rINST, #offClassObject_pDvmDex] @ r3<- method->clazz->pDvmDex
16700    mov     rPC, r2                         @ publish new rPC
16701
16702    @ Update state values for the new method
16703    @ r0=methodToCall, r1=newFp, r3=newMethodClass, r9=newINST
16704    str     r0, [rSELF, #offThread_method]    @ self->method = methodToCall
16705    str     r3, [rSELF, #offThread_methodClassDex] @ self->methodClassDex = ...
16706    mov     r2, #1
16707    str     r2, [rSELF, #offThread_debugIsMethodEntry]
16708#if defined(WITH_JIT)
16709    ldr     r0, [rSELF, #offThread_pJitProfTable]
16710    mov     rFP, r1                         @ fp = newFp
16711    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
16712    mov     rINST, r9                       @ publish new rINST
16713    str     r1, [rSELF, #offThread_curFrame]   @ curFrame = newFp
16714    cmp     r0,#0
16715    bne     common_updateProfile
16716    GOTO_OPCODE(ip)                         @ jump to next instruction
16717#else
16718    mov     rFP, r1                         @ fp = newFp
16719    GET_PREFETCHED_OPCODE(ip, r9)           @ extract prefetched opcode from r9
16720    mov     rINST, r9                       @ publish new rINST
16721    str     r1, [rSELF, #offThread_curFrame]   @ curFrame = newFp
16722    GOTO_OPCODE(ip)                         @ jump to next instruction
16723#endif
16724
167252:
16726    @ Profiling - record method entry.  r0: methodToCall
16727    stmfd   sp!, {r0-r3}                @ preserve r0-r3
16728    str     rPC, [rSELF, #offThread_pc] @ update interpSave.pc
16729    mov     r1, r0
16730    mov     r0, rSELF
16731    bl      dvmReportInvoke             @ (self, method)
16732    ldmfd   sp!, {r0-r3}                @ restore r0-r3
16733    b       1b
16734
16735.LinvokeNative:
16736    @ Prep for the native call
16737    @ r0=methodToCall, r1=newFp, r10=newSaveArea
16738    ldrh    lr, [rSELF, #offThread_subMode]
16739    ldr     r9, [rSELF, #offThread_jniLocal_topCookie]@r9<-thread->localRef->...
16740    str     r1, [rSELF, #offThread_curFrame]   @ curFrame = newFp
16741    str     r9, [r10, #offStackSaveArea_localRefCookie] @newFp->localRefCookie=top
16742    mov     r2, r0                      @ r2<- methodToCall
16743    mov     r0, r1                      @ r0<- newFp (points to args)
16744    add     r1, rSELF, #offThread_retval  @ r1<- &retval
16745    mov     r3, rSELF                   @ arg3<- self
16746
16747#ifdef ASSIST_DEBUGGER
16748    /* insert fake function header to help gdb find the stack frame */
16749    b       .Lskip
16750    .type   dalvik_mterp, %function
16751dalvik_mterp:
16752    .fnstart
16753    MTERP_ENTRY1
16754    MTERP_ENTRY2
16755.Lskip:
16756#endif
16757
16758    cmp     lr, #0                      @ any special SubModes active?
16759    bne     11f                         @ go handle them if so
16760    ldr     ip, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
16761    blx     ip
167627:
16763
16764    @ native return; r10=newSaveArea
16765    @ equivalent to dvmPopJniLocals
16766    ldr     r0, [r10, #offStackSaveArea_localRefCookie] @ r0<- saved top
16767    ldr     r1, [rSELF, #offThread_exception] @ check for exception
16768    str     rFP, [rSELF, #offThread_curFrame]  @ curFrame = fp
16769    cmp     r1, #0                      @ null?
16770    str     r0, [rSELF, #offThread_jniLocal_topCookie] @ new top <- old top
16771    bne     common_exceptionThrown      @ no, handle exception
16772
16773    FETCH_ADVANCE_INST(3)               @ advance rPC, load rINST
16774    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
16775    GOTO_OPCODE(ip)                     @ jump to next instruction
16776
1677711:
16778    @ r0=newFp, r1=&retval, r2=methodToCall, r3=self, lr=subModes
16779    stmfd   sp!, {r0-r3}                @ save all but subModes
16780    mov     r0, r2                      @ r0<- methodToCall
16781    mov     r1, rSELF
16782    mov     r2, rFP
16783    bl      dvmReportPreNativeInvoke    @ (methodToCall, self, fp)
16784    ldmfd   sp, {r0-r3}                 @ refresh.  NOTE: no sp autoincrement
16785
16786    @ Call the native method
16787    ldr     ip, [r2, #offMethod_nativeFunc] @ pc<- methodToCall->nativeFunc
16788    blx     ip
16789
16790    @ Restore the pre-call arguments
16791    ldmfd   sp!, {r0-r3}                @ r2<- methodToCall (others unneeded)
16792
16793    @ Finish up any post-invoke subMode requirements
16794    mov     r0, r2                      @ r0<- methodToCall
16795    mov     r1, rSELF
16796    mov     r2, rFP
16797    bl      dvmReportPostNativeInvoke   @ (methodToCall, self, fp)
16798    b       7b                          @ resume
16799
16800.LstackOverflow:    @ r0=methodToCall
16801    mov     r1, r0                      @ r1<- methodToCall
16802    mov     r0, rSELF                   @ r0<- self
16803    bl      dvmHandleStackOverflow
16804    b       common_exceptionThrown
16805#ifdef ASSIST_DEBUGGER
16806    .fnend
16807    .size   dalvik_mterp, .-dalvik_mterp
16808#endif
16809
16810
16811    /*
16812     * Common code for method invocation, calling through "glue code".
16813     *
16814     * TODO: now that we have range and non-range invoke handlers, this
16815     *       needs to be split into two.  Maybe just create entry points
16816     *       that set r9 and jump here?
16817     *
16818     * On entry:
16819     *  r0 is "Method* methodToCall", the method we're trying to call
16820     *  r9 is "bool methodCallRange", indicating if this is a /range variant
16821     */
16822     .if    0
16823.LinvokeOld:
16824    sub     sp, sp, #8                  @ space for args + pad
16825    FETCH(ip, 2)                        @ ip<- FEDC or CCCC
16826    mov     r2, r0                      @ A2<- methodToCall
16827    mov     r0, rSELF                   @ A0<- self
16828    SAVE_PC_FP_TO_SELF()                @ export state to "self"
16829    mov     r1, r9                      @ A1<- methodCallRange
16830    mov     r3, rINST, lsr #8           @ A3<- AA
16831    str     ip, [sp, #0]                @ A4<- ip
16832    bl      dvmMterp_invokeMethod       @ call the C invokeMethod
16833    add     sp, sp, #8                  @ remove arg area
16834    b       common_resumeAfterGlueCall  @ continue to next instruction
16835    .endif
16836
16837
16838
16839/*
16840 * Common code for handling a return instruction.
16841 *
16842 * This does not return.
16843 */
16844common_returnFromMethod:
16845.LreturnNew:
16846    ldrh    lr, [rSELF, #offThread_subMode]
16847    SAVEAREA_FROM_FP(r0, rFP)
16848    ldr     r9, [r0, #offStackSaveArea_savedPc] @ r9 = saveArea->savedPc
16849    cmp     lr, #0                      @ any special subMode handling needed?
16850    bne     19f
1685114:
16852    ldr     rFP, [r0, #offStackSaveArea_prevFrame] @ fp = saveArea->prevFrame
16853    ldr     r2, [rFP, #(offStackSaveArea_method - sizeofStackSaveArea)]
16854                                        @ r2<- method we're returning to
16855    cmp     r2, #0                      @ is this a break frame?
16856#if defined(WORKAROUND_CORTEX_A9_745320)
16857    /* Don't use conditional loads if the HW defect exists */
16858    beq     15f
16859    ldr     r10, [r2, #offMethod_clazz] @ r10<- method->clazz
1686015:
16861#else
16862    ldrne   r10, [r2, #offMethod_clazz] @ r10<- method->clazz
16863#endif
16864    beq     common_gotoBail             @ break frame, bail out completely
16865
16866    ldr     rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
16867    PREFETCH_ADVANCE_INST(rINST, r9, 3) @ advance r9, update new rINST
16868    str     r2, [rSELF, #offThread_method]@ self->method = newSave->method
16869    ldr     r1, [r10, #offClassObject_pDvmDex]   @ r1<- method->clazz->pDvmDex
16870    str     rFP, [rSELF, #offThread_curFrame]  @ curFrame = fp
16871#if defined(WITH_JIT)
16872    ldr     r10, [r0, #offStackSaveArea_returnAddr] @ r10 = saveArea->returnAddr
16873    mov     rPC, r9                     @ publish new rPC
16874    str     r1, [rSELF, #offThread_methodClassDex]
16875    str     r10, [rSELF, #offThread_inJitCodeCache]  @ may return to JIT'ed land
16876    cmp     r10, #0                      @ caller is compiled code
16877    blxne   r10
16878    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
16879    GOTO_OPCODE(ip)                     @ jump to next instruction
16880#else
16881    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
16882    mov     rPC, r9                     @ publish new rPC
16883    str     r1, [rSELF, #offThread_methodClassDex]
16884    GOTO_OPCODE(ip)                     @ jump to next instruction
16885#endif
16886
1688719:
16888    @ Handle special actions
16889    @ On entry, r0: StackSaveArea
16890    ldr     r1, [r0, #offStackSaveArea_prevFrame]  @ r2<- prevFP
16891    str     rPC, [rSELF, #offThread_pc] @ update interpSave.pc
16892    str     r1, [rSELF, #offThread_curFrame]   @ update interpSave.curFrame
16893    mov     r0, rSELF
16894    bl      dvmReportReturn             @ (self)
16895    SAVEAREA_FROM_FP(r0, rFP)           @ restore StackSaveArea
16896    b       14b                         @ continue
16897
16898    /*
16899     * Return handling, calls through "glue code".
16900     */
16901     .if    0
16902.LreturnOld:
16903    SAVE_PC_FP_TO_SELF()                @ export state
16904    mov     r0, rSELF                   @ arg to function
16905    bl      dvmMterp_returnFromMethod
16906    b       common_resumeAfterGlueCall
16907    .endif
16908
16909
16910/*
16911 * Somebody has thrown an exception.  Handle it.
16912 *
16913 * If the exception processing code returns to us (instead of falling
16914 * out of the interpreter), continue with whatever the next instruction
16915 * now happens to be.
16916 *
16917 * This does not return.
16918 */
16919     .global dvmMterpCommonExceptionThrown
16920dvmMterpCommonExceptionThrown:
16921common_exceptionThrown:
16922.LexceptionNew:
16923
16924    EXPORT_PC()
16925
16926    mov     r0, rSELF
16927    bl      dvmCheckSuspendPending
16928
16929    ldr     r9, [rSELF, #offThread_exception] @ r9<- self->exception
16930    mov     r1, rSELF                   @ r1<- self
16931    mov     r0, r9                      @ r0<- exception
16932    bl      dvmAddTrackedAlloc          @ don't let the exception be GCed
16933    ldrh    r2, [rSELF, #offThread_subMode]  @ get subMode flags
16934    mov     r3, #0                      @ r3<- NULL
16935    str     r3, [rSELF, #offThread_exception] @ self->exception = NULL
16936
16937    @ Special subMode?
16938    cmp     r2, #0                      @ any special subMode handling needed?
16939    bne     7f                          @ go if so
169408:
16941    /* set up args and a local for "&fp" */
16942    /* (str sp, [sp, #-4]!  would be perfect here, but is discouraged) */
16943    str     rFP, [sp, #-4]!             @ *--sp = fp
16944    mov     ip, sp                      @ ip<- &fp
16945    mov     r3, #0                      @ r3<- false
16946    str     ip, [sp, #-4]!              @ *--sp = &fp
16947    ldr     r1, [rSELF, #offThread_method] @ r1<- self->method
16948    mov     r0, rSELF                   @ r0<- self
16949    ldr     r1, [r1, #offMethod_insns]  @ r1<- method->insns
16950    ldrh    lr, [rSELF, #offThread_subMode]  @ lr<- subMode flags
16951    mov     r2, r9                      @ r2<- exception
16952    sub     r1, rPC, r1                 @ r1<- pc - method->insns
16953    mov     r1, r1, asr #1              @ r1<- offset in code units
16954
16955    /* call, r0 gets catchRelPc (a code-unit offset) */
16956    bl      dvmFindCatchBlock           @ call(self, relPc, exc, scan?, &fp)
16957
16958    /* fix earlier stack overflow if necessary; may trash rFP */
16959    ldrb    r1, [rSELF, #offThread_stackOverflowed]
16960    cmp     r1, #0                      @ did we overflow earlier?
16961    beq     1f                          @ no, skip ahead
16962    mov     rFP, r0                     @ save relPc result in rFP
16963    mov     r0, rSELF                   @ r0<- self
16964    mov     r1, r9                      @ r1<- exception
16965    bl      dvmCleanupStackOverflow     @ call(self)
16966    mov     r0, rFP                     @ restore result
169671:
16968
16969    /* update frame pointer and check result from dvmFindCatchBlock */
16970    ldr     rFP, [sp, #4]               @ retrieve the updated rFP
16971    cmp     r0, #0                      @ is catchRelPc < 0?
16972    add     sp, sp, #8                  @ restore stack
16973    bmi     .LnotCaughtLocally
16974
16975    /* adjust locals to match self->interpSave.curFrame and updated PC */
16976    SAVEAREA_FROM_FP(r1, rFP)           @ r1<- new save area
16977    ldr     r1, [r1, #offStackSaveArea_method] @ r1<- new method
16978    str     r1, [rSELF, #offThread_method]  @ self->method = new method
16979    ldr     r2, [r1, #offMethod_clazz]      @ r2<- method->clazz
16980    ldr     r3, [r1, #offMethod_insns]      @ r3<- method->insns
16981    ldr     r2, [r2, #offClassObject_pDvmDex] @ r2<- method->clazz->pDvmDex
16982    add     rPC, r3, r0, asl #1             @ rPC<- method->insns + catchRelPc
16983    str     r2, [rSELF, #offThread_methodClassDex] @ self->pDvmDex = meth...
16984
16985    /* release the tracked alloc on the exception */
16986    mov     r0, r9                      @ r0<- exception
16987    mov     r1, rSELF                   @ r1<- self
16988    bl      dvmReleaseTrackedAlloc      @ release the exception
16989
16990    /* restore the exception if the handler wants it */
16991    ldr    rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh rIBASE
16992    FETCH_INST()                        @ load rINST from rPC
16993    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
16994    cmp     ip, #OP_MOVE_EXCEPTION      @ is it "move-exception"?
16995    streq   r9, [rSELF, #offThread_exception] @ yes, restore the exception
16996    GOTO_OPCODE(ip)                     @ jump to next instruction
16997
16998    @ Manage debugger bookkeeping
169997:
17000    str     rPC, [rSELF, #offThread_pc]     @ update interpSave.pc
17001    str     rFP, [rSELF, #offThread_curFrame]     @ update interpSave.curFrame
17002    mov     r0, rSELF                       @ arg0<- self
17003    mov     r1, r9                          @ arg1<- exception
17004    bl      dvmReportExceptionThrow         @ (self, exception)
17005    b       8b                              @ resume with normal handling
17006
17007.LnotCaughtLocally: @ r9=exception
17008    /* fix stack overflow if necessary */
17009    ldrb    r1, [rSELF, #offThread_stackOverflowed]
17010    cmp     r1, #0                      @ did we overflow earlier?
17011    movne   r0, rSELF                   @ if yes: r0<- self
17012    movne   r1, r9                      @ if yes: r1<- exception
17013    blne    dvmCleanupStackOverflow     @ if yes: call(self)
17014
17015    @ may want to show "not caught locally" debug messages here
17016#if DVM_SHOW_EXCEPTION >= 2
17017    /* call __android_log_print(prio, tag, format, ...) */
17018    /* "Exception %s from %s:%d not caught locally" */
17019    @ dvmLineNumFromPC(method, pc - method->insns)
17020    ldr     r0, [rSELF, #offThread_method]
17021    ldr     r1, [r0, #offMethod_insns]
17022    sub     r1, rPC, r1
17023    asr     r1, r1, #1
17024    bl      dvmLineNumFromPC
17025    str     r0, [sp, #-4]!
17026    @ dvmGetMethodSourceFile(method)
17027    ldr     r0, [rSELF, #offThread_method]
17028    bl      dvmGetMethodSourceFile
17029    str     r0, [sp, #-4]!
17030    @ exception->clazz->descriptor
17031    ldr     r3, [r9, #offObject_clazz]
17032    ldr     r3, [r3, #offClassObject_descriptor]
17033    @
17034    ldr     r2, strExceptionNotCaughtLocally
170350:  add     r2, pc
17036    ldr     r1, strLogTag
170371:  add     r1, pc
17038    mov     r0, #3                      @ LOG_DEBUG
17039    bl      __android_log_print
17040#endif
17041    str     r9, [rSELF, #offThread_exception] @ restore exception
17042    mov     r0, r9                      @ r0<- exception
17043    mov     r1, rSELF                   @ r1<- self
17044    bl      dvmReleaseTrackedAlloc      @ release the exception
17045    b       common_gotoBail             @ bail out
17046
17047strExceptionNotCaughtLocally:
17048    .word   PCREL_REF(.LstrExceptionNotCaughtLocally,0b)
17049strLogTag:
17050    .word   PCREL_REF(.LstrLogTag,1b)
17051
17052    /*
17053     * Exception handling, calls through "glue code".
17054     */
17055    .if     0
17056.LexceptionOld:
17057    SAVE_PC_FP_TO_SELF()                @ export state
17058    mov     r0, rSELF                   @ arg to function
17059    bl      dvmMterp_exceptionThrown
17060    b       common_resumeAfterGlueCall
17061    .endif
17062
17063#if defined(WITH_JIT)
17064    /*
17065     * If the JIT is actively building a trace we need to make sure
17066     * that the field is fully resolved before including the current
17067     * instruction.
17068     *
17069     * On entry:
17070     *     r10: &dvmDex->pResFields[field]
17071     *     r0:  field pointer (must preserve)
17072     */
17073common_verifyField:
17074    ldrh    r3, [rSELF, #offThread_subMode]  @ r3 <- submode byte
17075    ands    r3, #kSubModeJitTraceBuild
17076    bxeq    lr                          @ Not building trace, continue
17077    ldr     r1, [r10]                   @ r1<- reload resolved StaticField ptr
17078    cmp     r1, #0                      @ resolution complete?
17079    bxne    lr                          @ yes, continue
17080    stmfd   sp!, {r0-r2,lr}             @ save regs
17081    mov     r0, rSELF
17082    mov     r1, rPC
17083    bl      dvmJitEndTraceSelect        @ (self,pc) end trace before this inst
17084    ldmfd   sp!, {r0-r2, lr}
17085    bx      lr                          @ return
17086#endif
17087
17088/*
17089 * After returning from a "glued" function, pull out the updated
17090 * values and start executing at the next instruction.
17091 */
17092common_resumeAfterGlueCall:
17093    LOAD_PC_FP_FROM_SELF()              @ pull rPC and rFP out of thread
17094    ldr     rIBASE, [rSELF, #offThread_curHandlerTable]  @ refresh
17095    FETCH_INST()                        @ load rINST from rPC
17096    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
17097    GOTO_OPCODE(ip)                     @ jump to next instruction
17098
17099/*
17100 * Invalid array index. Note that our calling convention is strange; we use r1
17101 * and r3 because those just happen to be the registers all our callers are
17102 * using. We move r3 before calling the C function, but r1 happens to match.
17103 * r1: index
17104 * r3: size
17105 */
17106common_errArrayIndex:
17107    EXPORT_PC()
17108    mov     r0, r3
17109    bl      dvmThrowArrayIndexOutOfBoundsException
17110    b       common_exceptionThrown
17111
17112/*
17113 * Integer divide or mod by zero.
17114 */
17115common_errDivideByZero:
17116    EXPORT_PC()
17117    ldr     r0, strDivideByZero
171180:  add     r0, pc
17119    bl      dvmThrowArithmeticException
17120    b       common_exceptionThrown
17121
17122strDivideByZero:
17123    .word   PCREL_REF(.LstrDivideByZero,0b)
17124
17125/*
17126 * Attempt to allocate an array with a negative size.
17127 * On entry: length in r1
17128 */
17129common_errNegativeArraySize:
17130    EXPORT_PC()
17131    mov     r0, r1                                @ arg0 <- len
17132    bl      dvmThrowNegativeArraySizeException    @ (len)
17133    b       common_exceptionThrown
17134
17135/*
17136 * Invocation of a non-existent method.
17137 * On entry: method name in r1
17138 */
17139common_errNoSuchMethod:
17140    EXPORT_PC()
17141    mov     r0, r1
17142    bl      dvmThrowNoSuchMethodError
17143    b       common_exceptionThrown
17144
17145/*
17146 * We encountered a null object when we weren't expecting one.  We
17147 * export the PC, throw a NullPointerException, and goto the exception
17148 * processing code.
17149 */
17150common_errNullObject:
17151    EXPORT_PC()
17152    mov     r0, #0
17153    bl      dvmThrowNullPointerException
17154    b       common_exceptionThrown
17155
17156/*
17157 * For debugging, cause an immediate fault.  The source address will
17158 * be in lr (use a bl instruction to jump here).
17159 */
17160common_abort:
17161    ldr     pc, .LdeadFood
17162.LdeadFood:
17163    .word   0xdeadf00d
17164
17165/*
17166 * Spit out a "we were here", preserving all registers.  (The attempt
17167 * to save ip won't work, but we need to save an even number of
17168 * registers for EABI 64-bit stack alignment.)
17169 */
17170    .macro  SQUEAK num
17171common_squeak\num:
17172    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
17173    ldr     r0, strSqueak\num
171740:  add     r0, pc
17175    mov     r1, #\num
17176    bl      printf
17177    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
17178    bx      lr
17179
17180strSqueak\num:
17181    .word   PCREL_REF(.LstrSqueak,0b)
17182    .endm
17183
17184    SQUEAK  0
17185    SQUEAK  1
17186    SQUEAK  2
17187    SQUEAK  3
17188    SQUEAK  4
17189    SQUEAK  5
17190
17191/*
17192 * Spit out the number in r0, preserving registers.
17193 */
17194common_printNum:
17195    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
17196    mov     r1, r0
17197    ldr     r0, strSqueak
171980:  add     r0, pc
17199    bl      printf
17200    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
17201    bx      lr
17202
17203strSqueak:
17204    .word   PCREL_REF(.LstrSqueak,0b)
17205
17206/*
17207 * Print a newline, preserving registers.
17208 */
17209common_printNewline:
17210    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
17211    ldr     r0, strNewline
172120:  add     r0, pc
17213    bl      printf
17214    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
17215    bx      lr
17216
17217strNewline:
17218    .word   PCREL_REF(.LstrNewline,0b)
17219
17220    /*
17221     * Print the 32-bit quantity in r0 as a hex value, preserving registers.
17222     */
17223common_printHex:
17224    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
17225    mov     r1, r0
17226    ldr     r0, strPrintHex
172270:  add     r0, pc
17228    bl      printf
17229    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
17230    bx      lr
17231
17232strPrintHex:
17233    .word   PCREL_REF(.LstrPrintHex,0b)
17234
17235/*
17236 * Print the 64-bit quantity in r0-r1, preserving registers.
17237 */
17238common_printLong:
17239    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
17240    mov     r3, r1
17241    mov     r2, r0
17242    ldr     r0, strPrintLong
172430:  add     r0, pc
17244    bl      printf
17245    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
17246    bx      lr
17247
17248strPrintLong:
17249    .word   PCREL_REF(.LstrPrintLong,0b)
17250
17251/*
17252 * Print full method info.  Pass the Method* in r0.  Preserves regs.
17253 */
17254common_printMethod:
17255    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
17256    bl      dvmMterpPrintMethod
17257    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
17258    bx      lr
17259
17260/*
17261 * Call a C helper function that dumps regs and possibly some
17262 * additional info.  Requires the C function to be compiled in.
17263 */
17264    .if     0
17265common_dumpRegs:
17266    stmfd   sp!, {r0, r1, r2, r3, ip, lr}
17267    bl      dvmMterpDumpArmRegs
17268    ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
17269    bx      lr
17270    .endif
17271
17272#if 0
17273/*
17274 * Experiment on VFP mode.
17275 *
17276 * uint32_t setFPSCR(uint32_t val, uint32_t mask)
17277 *
17278 * Updates the bits specified by "mask", setting them to the values in "val".
17279 */
17280setFPSCR:
17281    and     r0, r0, r1                  @ make sure no stray bits are set
17282    fmrx    r2, fpscr                   @ get VFP reg
17283    mvn     r1, r1                      @ bit-invert mask
17284    and     r2, r2, r1                  @ clear masked bits
17285    orr     r2, r2, r0                  @ set specified bits
17286    fmxr    fpscr, r2                   @ set VFP reg
17287    mov     r0, r2                      @ return new value
17288    bx      lr
17289
17290    .align  2
17291    .global dvmConfigureFP
17292    .type   dvmConfigureFP, %function
17293dvmConfigureFP:
17294    stmfd   sp!, {ip, lr}
17295    /* 0x03000000 sets DN/FZ */
17296    /* 0x00009f00 clears the six exception enable flags */
17297    bl      common_squeak0
17298    mov     r0, #0x03000000             @ r0<- 0x03000000
17299    add     r1, r0, #0x9f00             @ r1<- 0x03009f00
17300    bl      setFPSCR
17301    ldmfd   sp!, {ip, pc}
17302#endif
17303
17304
17305
17306/*
17307 * Zero-terminated ASCII string data.
17308 *
17309 * On ARM we have two choices: do like gcc does, and LDR from a .word
17310 * with the address, or use an ADR pseudo-op to get the address
17311 * directly.  ADR saves 4 bytes and an indirection, but it's using a
17312 * PC-relative addressing mode and hence has a limited range, which
17313 * makes it not work well with mergeable string sections.
17314 */
17315    .section .rodata.str1.4,"aMS",%progbits,1
17316
17317.LstrBadEntryPoint:
17318    .asciz  "Bad entry point %d\n"
17319.LstrFilledNewArrayNotImpl:
17320    .asciz  "filled-new-array only implemented for objects and 'int'"
17321.LstrDivideByZero:
17322    .asciz  "divide by zero"
17323.LstrLogTag:
17324    .asciz  "mterp"
17325.LstrExceptionNotCaughtLocally:
17326    .asciz  "Exception %s from %s:%d not caught locally\n"
17327
17328.LstrNewline:
17329    .asciz  "\n"
17330.LstrSqueak:
17331    .asciz  "<%d>"
17332.LstrPrintHex:
17333    .asciz  "<%#x>"
17334.LstrPrintLong:
17335    .asciz  "<%lld>"
17336
17337