1%def unused():
2    brk 42
3
4%def op_const():
5    /* const vAA, #+BBBBbbbb */
6    lsr     w3, wINST, #8               // w3<- AA
7    FETCH w0, 1                         // w0<- bbbb (low)
8    FETCH w1, 2                         // w1<- BBBB (high)
9    FETCH_ADVANCE_INST 3                // advance rPC, load wINST
10    orr     w0, w0, w1, lsl #16         // w0<- BBBBbbbb
11    GET_INST_OPCODE ip                  // extract opcode from wINST
12    SET_VREG w0, w3                     // vAA<- w0
13    GOTO_OPCODE ip                      // jump to next instruction
14
15%def op_const_16():
16    /* const/16 vAA, #+BBBB */
17    FETCH_S w0, 1                       // w0<- ssssBBBB (sign-extended)
18    lsr     w3, wINST, #8               // w3<- AA
19    FETCH_ADVANCE_INST 2                // advance xPC, load wINST
20    SET_VREG w0, w3                     // vAA<- w0
21    GET_INST_OPCODE ip                  // extract opcode from wINST
22    GOTO_OPCODE ip                      // jump to next instruction
23
24%def op_const_4():
25    /* const/4 vA, #+B */
26    sbfx    w1, wINST, #12, #4          // w1<- sssssssB
27    ubfx    w0, wINST, #8, #4           // w0<- A
28    FETCH_ADVANCE_INST 1                // advance xPC, load wINST
29    GET_INST_OPCODE ip                  // ip<- opcode from xINST
30    SET_VREG w1, w0                     // fp[A]<- w1
31    GOTO_OPCODE ip                      // execute next instruction
32
33%def op_const_high16():
34    /* const/high16 vAA, #+BBBB0000 */
35    FETCH   w0, 1                       // r0<- 0000BBBB (zero-extended)
36    lsr     w3, wINST, #8               // r3<- AA
37    lsl     w0, w0, #16                 // r0<- BBBB0000
38    FETCH_ADVANCE_INST 2                // advance rPC, load rINST
39    SET_VREG w0, w3                     // vAA<- r0
40    GET_INST_OPCODE ip                  // extract opcode from rINST
41    GOTO_OPCODE ip                      // jump to next instruction
42
43%def op_const_object(jumbo="0", helper="nterp_load_object"):
44   // Fast-path which gets the object from thread-local cache.
45   FETCH_FROM_THREAD_CACHE x0, 2f
46   cbnz wMR, 3f
471:
48   lsr     w1, wINST, #8               // w1<- AA
49   .if $jumbo
50   FETCH_ADVANCE_INST 3                // advance rPC, load wINST
51   .else
52   FETCH_ADVANCE_INST 2                // advance rPC, load wINST
53   .endif
54   GET_INST_OPCODE ip                  // extract opcode from wINST
55   SET_VREG_OBJECT w0, w1              // vAA <- value
56   GOTO_OPCODE ip                      // jump to next instruction
572:
58   EXPORT_PC
59   mov x0, xSELF
60   ldr x1, [sp]
61   mov x2, xPC
62   bl $helper
63   b 1b
643:
65   bl art_quick_read_barrier_mark_reg00
66   b 1b
67
68%def op_const_class():
69%  op_const_object(jumbo="0", helper="nterp_get_class_or_allocate_object")
70
71%def op_const_method_handle():
72%  op_const_object(jumbo="0")
73
74%def op_const_method_type():
75%  op_const_object(jumbo="0")
76
77%def op_const_string():
78   /* const/string vAA, String@BBBB */
79%  op_const_object(jumbo="0")
80
81%def op_const_string_jumbo():
82   /* const/string vAA, String@BBBBBBBB */
83%  op_const_object(jumbo="1")
84
85%def op_const_wide():
86    /* const-wide vAA, #+HHHHhhhhBBBBbbbb */
87    FETCH w0, 1                         // w0<- bbbb (low)
88    FETCH w1, 2                         // w1<- BBBB (low middle)
89    FETCH w2, 3                         // w2<- hhhh (high middle)
90    FETCH w3, 4                         // w3<- HHHH (high)
91    lsr     w4, wINST, #8               // r4<- AA
92    FETCH_ADVANCE_INST 5                // advance rPC, load wINST
93    GET_INST_OPCODE ip                  // extract opcode from wINST
94    orr     w0, w0, w1, lsl #16         // w0<-         BBBBbbbb
95    orr     x0, x0, x2, lsl #32         // w0<-     hhhhBBBBbbbb
96    orr     x0, x0, x3, lsl #48         // w0<- HHHHhhhhBBBBbbbb
97    SET_VREG_WIDE x0, w4
98    GOTO_OPCODE ip                      // jump to next instruction
99
100%def op_const_wide_16():
101    /* const-wide/16 vAA, #+BBBB */
102    FETCH_S x0, 1                       // x0<- ssssssssssssBBBB (sign-extended)
103    lsr     w3, wINST, #8               // w3<- AA
104    FETCH_ADVANCE_INST 2                // advance rPC, load rINST
105    GET_INST_OPCODE ip                  // extract opcode from rINST
106    SET_VREG_WIDE x0, w3
107    GOTO_OPCODE ip                      // jump to next instruction
108
109%def op_const_wide_32():
110    /* const-wide/32 vAA, #+BBBBbbbb */
111    FETCH   w0, 1                       // x0<- 000000000000bbbb (low)
112    lsr     w3, wINST, #8               // w3<- AA
113    FETCH_S x2, 2                       // x2<- ssssssssssssBBBB (high)
114    FETCH_ADVANCE_INST 3                // advance rPC, load wINST
115    GET_INST_OPCODE ip                  // extract opcode from wINST
116    orr     x0, x0, x2, lsl #16         // x0<- ssssssssBBBBbbbb
117    SET_VREG_WIDE x0, w3
118    GOTO_OPCODE ip                      // jump to next instruction
119
120%def op_const_wide_high16():
121    /* const-wide/high16 vAA, #+BBBB000000000000 */
122    FETCH w0, 1                         // w0<- 0000BBBB (zero-extended)
123    lsr     w1, wINST, #8               // w1<- AA
124    FETCH_ADVANCE_INST 2                // advance rPC, load wINST
125    lsl     x0, x0, #48
126    SET_VREG_WIDE x0, w1
127    GET_INST_OPCODE ip                  // extract opcode from wINST
128    GOTO_OPCODE ip                      // jump to next instruction
129
130%def op_monitor_enter():
131/*
132 * Synchronize on an object.
133 */
134    /* monitor-enter vAA */
135    EXPORT_PC
136    lsr      w2, wINST, #8               // w2<- AA
137    GET_VREG w0, w2
138    bl art_quick_lock_object
139    FETCH_ADVANCE_INST 1
140    GET_INST_OPCODE ip                   // extract opcode from rINST
141    GOTO_OPCODE ip                       // jump to next instruction
142
143%def op_monitor_exit():
144/*
145 * Unlock an object.
146 *
147 * Exceptions that occur when unlocking a monitor need to appear as
148 * if they happened at the following instruction.  See the Dalvik
149 * instruction spec.
150 */
151    /* monitor-exit vAA */
152    EXPORT_PC
153    lsr      w2, wINST, #8               // w2<- AA
154    GET_VREG w0, w2
155    bl art_quick_unlock_object
156    FETCH_ADVANCE_INST 1
157    GET_INST_OPCODE ip                   // extract opcode from rINST
158    GOTO_OPCODE ip                       // jump to next instruction
159
160%def op_move(is_object="0"):
161    /* for move, move-object, long-to-int */
162    /* op vA, vB */
163    lsr     w1, wINST, #12              // x1<- B from 15:12
164    ubfx    w0, wINST, #8, #4           // x0<- A from 11:8
165    FETCH_ADVANCE_INST 1                // advance rPC, load wINST
166    GET_VREG w2, w1                     // x2<- fp[B]
167    GET_INST_OPCODE ip                  // ip<- opcode from wINST
168    .if $is_object
169    SET_VREG_OBJECT w2, w0              // fp[A]<- x2
170    .else
171    SET_VREG w2, w0                     // fp[A]<- x2
172    .endif
173    GOTO_OPCODE ip                      // execute next instruction
174
175%def op_move_16(is_object="0"):
176    /* for: move/16, move-object/16 */
177    /* op vAAAA, vBBBB */
178    FETCH w1, 2                         // w1<- BBBB
179    FETCH w0, 1                         // w0<- AAAA
180    FETCH_ADVANCE_INST 3                // advance xPC, load xINST
181    GET_VREG w2, w1                     // w2<- fp[BBBB]
182    GET_INST_OPCODE ip                  // extract opcode from xINST
183    .if $is_object
184    SET_VREG_OBJECT w2, w0              // fp[AAAA]<- w2
185    .else
186    SET_VREG w2, w0                     // fp[AAAA]<- w2
187    .endif
188    GOTO_OPCODE ip                      // jump to next instruction
189
190%def op_move_exception():
191    /* move-exception vAA */
192    lsr     w2, wINST, #8               // w2<- AA
193    ldr     x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
194    FETCH_ADVANCE_INST 1                // advance rPC, load rINST
195    SET_VREG_OBJECT w3, w2              // fp[AA]<- exception obj
196    GET_INST_OPCODE ip                  // extract opcode from rINST
197    str     xzr, [xSELF, #THREAD_EXCEPTION_OFFSET]  // clear exception
198    GOTO_OPCODE ip                      // jump to next instruction
199
200%def op_move_from16(is_object="0"):
201    /* for: move/from16, move-object/from16 */
202    /* op vAA, vBBBB */
203    FETCH w1, 1                         // r1<- BBBB
204    lsr     w0, wINST, #8               // r0<- AA
205    FETCH_ADVANCE_INST 2                // advance rPC, load wINST
206    GET_VREG w2, w1                     // r2<- fp[BBBB]
207    GET_INST_OPCODE ip                  // extract opcode from wINST
208    .if $is_object
209    SET_VREG_OBJECT w2, w0              // fp[AA]<- r2
210    .else
211    SET_VREG w2, w0                     // fp[AA]<- r2
212    .endif
213    GOTO_OPCODE ip                      // jump to next instruction
214
215%def op_move_object():
216%  op_move(is_object="1")
217
218%def op_move_object_16():
219%  op_move_16(is_object="1")
220
221%def op_move_object_from16():
222%  op_move_from16(is_object="1")
223
224%def op_move_result(is_object="0"):
225    /* for: move-result, move-result-object */
226    /* op vAA */
227    lsr     w2, wINST, #8               // r2<- AA
228    FETCH_ADVANCE_INST 1                // advance rPC, load wINST
229    GET_INST_OPCODE ip                  // extract opcode from wINST
230    .if $is_object
231    SET_VREG_OBJECT w0, w2, w1          // fp[AA]<- r0
232    .else
233    SET_VREG w0, w2                     // fp[AA]<- r0
234    .endif
235    GOTO_OPCODE ip                      // jump to next instruction
236
237%def op_move_result_object():
238%  op_move_result(is_object="1")
239
240%def op_move_result_wide():
241    /* for: move-result-wide */
242    /* op vAA */
243    lsr     w2, wINST, #8               // r2<- AA
244    FETCH_ADVANCE_INST 1                // advance rPC, load wINST
245    GET_INST_OPCODE ip                  // extract opcode from wINST
246    SET_VREG_WIDE x0, w2                // fp[AA]<- r0
247    GOTO_OPCODE ip                      // jump to next instruction
248
249%def op_move_wide():
250    /* move-wide vA, vB */
251    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
252    lsr     w3, wINST, #12              // w3<- B
253    ubfx    w2, wINST, #8, #4           // w2<- A
254    GET_VREG_WIDE  x3, w3
255    FETCH_ADVANCE_INST 1                // advance rPC, load wINST
256    GET_INST_OPCODE ip                  // extract opcode from wINST
257    SET_VREG_WIDE  x3, w2
258    GOTO_OPCODE ip                      // jump to next instruction
259
260%def op_move_wide_16():
261    /* move-wide/16 vAAAA, vBBBB */
262    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
263    FETCH w3, 2                         // w3<- BBBB
264    FETCH w2, 1                         // w2<- AAAA
265    GET_VREG_WIDE x3, w3
266    FETCH_ADVANCE_INST 3                // advance rPC, load rINST
267    SET_VREG_WIDE x3, w2
268    GET_INST_OPCODE ip                  // extract opcode from rINST
269    GOTO_OPCODE ip                      // jump to next instruction
270
271%def op_move_wide_from16():
272    /* move-wide/from16 vAA, vBBBB */
273    /* NOTE: regs can overlap, e.g. "move v6,v7" or "move v7,v6" */
274    FETCH w3, 1                         // w3<- BBBB
275    lsr     w2, wINST, #8               // w2<- AA
276    GET_VREG_WIDE x3, w3
277    FETCH_ADVANCE_INST 2                // advance rPC, load wINST
278    GET_INST_OPCODE ip                  // extract opcode from wINST
279    SET_VREG_WIDE x3, w2
280    GOTO_OPCODE ip                      // jump to next instruction
281
282%def op_nop():
283    FETCH_ADVANCE_INST 1                // advance to next instr, load rINST
284    GET_INST_OPCODE ip                  // ip<- opcode from rINST
285    GOTO_OPCODE ip                      // execute it
286
287%def op_unused_3e():
288%  unused()
289
290%def op_unused_3f():
291%  unused()
292
293%def op_unused_40():
294%  unused()
295
296%def op_unused_41():
297%  unused()
298
299%def op_unused_42():
300%  unused()
301
302%def op_unused_43():
303%  unused()
304
305%def op_unused_79():
306%  unused()
307
308%def op_unused_7a():
309%  unused()
310
311%def op_unused_f3():
312%  unused()
313
314%def op_unused_f4():
315%  unused()
316
317%def op_unused_f5():
318%  unused()
319
320%def op_unused_f6():
321%  unused()
322
323%def op_unused_f7():
324%  unused()
325
326%def op_unused_f8():
327%  unused()
328
329%def op_unused_f9():
330%  unused()
331
332%def op_unused_fc():
333%  unused()
334
335%def op_unused_fd():
336%  unused()
337