• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1%def op_check_cast():
2   // Fast-path which gets the class from thread-local cache.
3   EXPORT_PC
4   FETCH_FROM_THREAD_CACHE x1, 3f
5   cbnz    wMR, 4f
61:
7   lsr     w2, wINST, #8               // w2<- A
8   GET_VREG w0, w2                     // w0<- vA (object)
9   cbz     w0, 2f
10   bl      art_quick_check_instance_of
112:
12   FETCH_ADVANCE_INST 2
13   GET_INST_OPCODE ip
14   GOTO_OPCODE ip
153:
16   mov     x0, xSELF
17   ldr     x1, [sp]
18   mov     x2, xPC
19   bl      nterp_get_class_or_allocate_object
20   mov     x1, x0
21   b       1b
224:
23   bl      art_quick_read_barrier_mark_reg01
24   b       1b
25
26%def op_instance_of():
27   /* instance-of vA, vB, class@CCCC */
28   // Fast-path which gets the class from thread-local cache.
29   EXPORT_PC
30   FETCH_FROM_THREAD_CACHE x1, 3f
31   cbnz    wMR, 4f
321:
33   lsr     w2, wINST, #12              // w2<- B
34   GET_VREG w0, w2                     // w0<- vB (object)
35   cbz     w0, 2f
36   bl      artInstanceOfFromCode
372:
38   ubfx    w1, wINST, #8, #4           // w1<- A
39   SET_VREG w0, w1
40   FETCH_ADVANCE_INST 2
41   GET_INST_OPCODE ip
42   GOTO_OPCODE ip
433:
44   mov     x0, xSELF
45   ldr     x1, [sp]
46   mov     x2, xPC
47   bl      nterp_get_class_or_allocate_object
48   mov     x1, x0
49   b       1b
504:
51   bl      art_quick_read_barrier_mark_reg01
52   b       1b
53
54%def op_iget_boolean():
55%  op_iget(load="ldrb", volatile_load="ldarb", maybe_extend="", wide="0", is_object="0")
56
57%def op_iget_byte():
58%  op_iget(load="ldrsb", volatile_load="ldarb", maybe_extend="sxtb w0, w0", wide="0", is_object="0")
59
60%def op_iget_char():
61%  op_iget(load="ldrh", volatile_load="ldarh", maybe_extend="", wide="0", is_object="0")
62
63%def op_iget_short():
64%  op_iget(load="ldrsh", volatile_load="ldarh", maybe_extend="sxth w0, w0", wide="0", is_object="0")
65
66%def op_iget(load="ldr", volatile_load="ldar", maybe_extend="", wide="0", is_object="0"):
67%  slow_path = add_helper(lambda: op_iget_slow_path(volatile_load, maybe_extend, wide, is_object))
68   // Fast-path which gets the field from thread-local cache.
69   FETCH_FROM_THREAD_CACHE x0, ${slow_path}
70.L${opcode}_resume:
71   lsr     w2, wINST, #12              // w2<- B
72   GET_VREG w3, w2                     // w3<- object we're operating on
73   ubfx    w2, wINST, #8, #4           // w2<- A
74   cbz     w3, common_errNullObject    // object was null
75   .if $wide
76   $load   x0, [x3, x0]
77   SET_VREG_WIDE x0, w2                // fp[A] <- value
78   .elseif $is_object
79   $load   w0, [x3, x0]
80   cbnz    wMR, .L${opcode}_read_barrier
81.L${opcode}_resume_after_read_barrier:
82   SET_VREG_OBJECT w0, w2              // fp[A] <- value
83   .else
84   $load   w0, [x3, x0]
85   SET_VREG w0, w2                     // fp[A] <- value
86   .endif
87   FETCH_ADVANCE_INST 2
88   GET_INST_OPCODE ip
89   GOTO_OPCODE ip
90   .if $is_object
91.L${opcode}_read_barrier:
92   bl      art_quick_read_barrier_mark_reg00
93   b       .L${opcode}_resume_after_read_barrier
94   .endif
95
96%def op_iget_slow_path(volatile_load, maybe_extend, wide, is_object):
97   mov     x0, xSELF
98   ldr     x1, [sp]
99   mov     x2, xPC
100   mov     x3, #0
101   EXPORT_PC
102   bl      nterp_get_instance_field_offset
103   tbz     w0, #31, .L${opcode}_resume
104   CLEAR_INSTANCE_VOLATILE_MARKER w0
105   lsr     w2, wINST, #12              // w2<- B
106   GET_VREG w3, w2                     // w3<- object we're operating on
107   ubfx    w2, wINST, #8, #4           // w2<- A
108   cbz     w3, common_errNullObject    // object was null
109   add     x3, x3, x0
110   .if $wide
111   $volatile_load x0, [x3]
112   SET_VREG_WIDE x0, w2                // fp[A] <- value
113   .elseif $is_object
114   $volatile_load w0, [x3]
115   cbnz wMR, .L${opcode}_read_barrier
116   SET_VREG_OBJECT w0, w2              // fp[A] <- value
117   .else
118   $volatile_load w0, [x3]
119   $maybe_extend
120   SET_VREG w0, w2                     // fp[A] <- value
121   .endif
122   FETCH_ADVANCE_INST 2
123   GET_INST_OPCODE ip
124   GOTO_OPCODE ip
125
126%def op_iget_wide():
127%  op_iget(load="ldr", volatile_load="ldar", maybe_extend="", wide="1", is_object="0")
128
129%def op_iget_object():
130%  op_iget(load="ldr", volatile_load="ldar", maybe_extend="", wide="0", is_object="1")
131
132%def op_iput_boolean():
133%  op_iput(store="strb", volatile_store="stlrb", wide="0", is_object="0")
134
135%def op_iput_byte():
136%  op_iput(store="strb", volatile_store="stlrb", wide="0", is_object="0")
137
138%def op_iput_char():
139%  op_iput(store="strh", volatile_store="stlrh", wide="0", is_object="0")
140
141%def op_iput_short():
142%  op_iput(store="strh", volatile_store="stlrh", wide="0", is_object="0")
143
144%def op_iput(store="str", volatile_store="stlr", wide="0", is_object="0"):
145   // Share slow paths for boolean and byte (strb) and slow paths for char and short (strh).
146   // It does not matter to which `.L${opcode}_resume` the slow path returns.
147%  slow_path = "nterp_op_iput_helper_" + store + wide + is_object
148%  add_helper(lambda: op_iput_slow_path(volatile_store, wide, is_object), slow_path)
149   ubfx    w1, wINST, #8, #4           // w1<- A
150   .if $wide
151   GET_VREG_WIDE x26, w1               // x26<- fp[A]/fp[A+1]
152   .else
153   GET_VREG w26, w1                    // w26 <- v[A]
154   .endif
155   // Fast-path which gets the field from thread-local cache.
156   FETCH_FROM_THREAD_CACHE x0, ${slow_path}
157.L${opcode}_resume:
158   lsr     w2, wINST, #12              // w2<- B
159   GET_VREG w2, w2                     // vB (object we're operating on)
160   cbz w2, common_errNullObject
161   .if $wide
162   $store  x26, [x2, x0]
163   .else
164   $store  w26, [x2, x0]
165   WRITE_BARRIER_IF_OBJECT $is_object, w26, w2, .L${opcode}_skip_write_barrier
166   .endif
167   FETCH_ADVANCE_INST 2
168   GET_INST_OPCODE ip
169   GOTO_OPCODE ip
170
171%def op_iput_slow_path(volatile_store, wide, is_object):
172   mov     x0, xSELF
173   ldr     x1, [sp]
174   mov     x2, xPC
175   .if $is_object
176   mov     x3, x26
177   .else
178   mov     x3, #0
179   .endif
180   EXPORT_PC
181   bl      nterp_get_instance_field_offset
182   .if $is_object
183   // Reload the value as it may have moved.
184   ubfx    w1, wINST, #8, #4           // w1<- A
185   GET_VREG w26, w1                    // w26 <- v[A]
186   .endif
187   tbz     w0, #31, .L${opcode}_resume
188   CLEAR_INSTANCE_VOLATILE_MARKER w0
189   lsr     w2, wINST, #12              // w2<- B
190   GET_VREG w2, w2                     // vB (object we're operating on)
191   cbz     w2, common_errNullObject
192   add     x3, x2, x0
193   .if $wide
194   $volatile_store x26, [x3]
195   .else
196   $volatile_store w26, [x3]
197   WRITE_BARRIER_IF_OBJECT $is_object, w26, w2, .L${opcode}_slow_path_skip_write_barrier
198   .endif
199   FETCH_ADVANCE_INST 2
200   GET_INST_OPCODE ip
201   GOTO_OPCODE ip
202
203%def op_iput_wide():
204%  op_iput(store="str", volatile_store="stlr", wide="1", is_object="0")
205
206%def op_iput_object():
207%  op_iput(store="str", volatile_store="stlr", wide="0", is_object="1")
208
209%def op_sget_boolean():
210%  op_sget(load="ldrb", volatile_load="ldarb", maybe_extend="", wide="0", is_object="0")
211
212%def op_sget_byte():
213%  op_sget(load="ldrsb", volatile_load="ldarb", maybe_extend="sxtb w0, w0", wide="0", is_object="0")
214
215%def op_sget_char():
216%  op_sget(load="ldrh", volatile_load="ldarh", maybe_extend="", wide="0", is_object="0")
217
218%def op_sget_short():
219%  op_sget(load="ldrsh", volatile_load="ldarh", maybe_extend="sxth w0, w0", wide="0", is_object="0")
220
221%def op_sget(load="ldr", volatile_load="ldar", maybe_extend="", wide="0", is_object="0"):
222%  slow_path = add_helper(lambda: op_sget_slow_path(volatile_load, maybe_extend, wide, is_object))
223   // Fast-path which gets the field from thread-local cache.
224   FETCH_FROM_THREAD_CACHE x0, ${slow_path}
225.L${opcode}_resume:
226   ldr     w1, [x0, #ART_FIELD_OFFSET_OFFSET]
227   lsr     w2, wINST, #8               // w2 <- A
228   ldr     w0, [x0, #ART_FIELD_DECLARING_CLASS_OFFSET]
229   cbnz    wMR, .L${opcode}_read_barrier
230.L${opcode}_resume_after_read_barrier:
231   .if $wide
232   ldr     x0, [x0, x1]
233   SET_VREG_WIDE x0, w2                // fp[A] <- value
234   .elseif $is_object
235   $load   w0, [x0, x1]
236   // No need to check the marking register, we know it's not set here.
237.L${opcode}_after_reference_load:
238   SET_VREG_OBJECT w0, w2              // fp[A] <- value
239   .else
240   $load   w0, [x0, x1]
241   SET_VREG w0, w2                     // fp[A] <- value
242   .endif
243   FETCH_ADVANCE_INST 2
244   GET_INST_OPCODE ip
245   GOTO_OPCODE ip
246.L${opcode}_read_barrier:
247   bl      art_quick_read_barrier_mark_reg00
248   .if $is_object
249   $load   w0, [x0, x1]
250.L${opcode}_mark_after_load:
251   // Here, we know the marking register is set.
252   bl      art_quick_read_barrier_mark_reg00
253   b       .L${opcode}_after_reference_load
254   .else
255   b       .L${opcode}_resume_after_read_barrier
256   .endif
257
258%def op_sget_slow_path(volatile_load, maybe_extend, wide, is_object):
259   mov     x0, xSELF
260   ldr     x1, [sp]
261   mov     x2, xPC
262   mov     x3, #0
263   EXPORT_PC
264   bl      nterp_get_static_field
265   tbz     x0, #0, .L${opcode}_resume
266   CLEAR_STATIC_VOLATILE_MARKER x0
267   ldr     w1, [x0, #ART_FIELD_OFFSET_OFFSET]
268   lsr     w2, wINST, #8               // w2 <- A
269   ldr     w0, [x0, #ART_FIELD_DECLARING_CLASS_OFFSET]
270   cbnz    wMR, .L${opcode}_slow_path_read_barrier
271.L${opcode}_slow_path_resume_after_read_barrier:
272   add     x0, x0, x1
273   .if $wide
274   ldar    x0, [x0]
275   SET_VREG_WIDE x0, w2                // fp[A] <- value
276   .elseif $is_object
277   $volatile_load w0, [x0]
278   cbnz    wMR, .L${opcode}_mark_after_load
279   SET_VREG_OBJECT w0, w2              // fp[A] <- value
280   .else
281   $volatile_load w0, [x0]
282   $maybe_extend
283   SET_VREG w0, w2                     // fp[A] <- value
284   .endif
285   FETCH_ADVANCE_INST 2
286   GET_INST_OPCODE ip
287   GOTO_OPCODE ip
288.L${opcode}_slow_path_read_barrier:
289   bl      art_quick_read_barrier_mark_reg00
290   b       .L${opcode}_slow_path_resume_after_read_barrier
291
292%def op_sget_wide():
293%  op_sget(load="ldr", volatile_load="ldar", maybe_extend="", wide="1", is_object="0")
294
295%def op_sget_object():
296%  op_sget(load="ldr", volatile_load="ldar", maybe_extend="", wide="0", is_object="1")
297
298%def op_sput_boolean():
299%  op_sput(store="strb", volatile_store="stlrb", wide="0", is_object="0")
300
301%def op_sput_byte():
302%  op_sput(store="strb", volatile_store="stlrb", wide="0", is_object="0")
303
304%def op_sput_char():
305%  op_sput(store="strh", volatile_store="stlrh", wide="0", is_object="0")
306
307%def op_sput_short():
308%  op_sput(store="strh", volatile_store="stlrh", wide="0", is_object="0")
309
310%def op_sput(store="str", volatile_store="stlr", wide="0", is_object="0"):
311   // Share slow paths for boolean and byte (strb) and slow paths for char and short (strh).
312   // It does not matter to which `.L${opcode}_resume` the slow path returns.
313%  slow_path = "nterp_op_sput_helper_" + store + wide + is_object
314%  add_helper(lambda: op_sput_slow_path(volatile_store, wide, is_object), slow_path)
315   lsr     w2, wINST, #8               // w2 <- A
316   .if $wide
317   GET_VREG_WIDE x26, w2               // x26 <- v[A]
318   .else
319   GET_VREG w26, w2                    // w26 <- v[A]
320   .endif
321   // Fast-path which gets the field from thread-local cache.
322   FETCH_FROM_THREAD_CACHE x0, ${slow_path}
323.L${opcode}_resume:
324   ldr     w1, [x0, #ART_FIELD_OFFSET_OFFSET]
325   ldr     w0, [x0, #ART_FIELD_DECLARING_CLASS_OFFSET]
326   cbnz    wMR, .L${opcode}_read_barrier
327.L${opcode}_resume_after_read_barrier:
328   .if $wide
329   $store  x26, [x0, x1]
330   .else
331   $store  w26, [x0, x1]
332   WRITE_BARRIER_IF_OBJECT $is_object, w26, w0, .L${opcode}_skip_write_barrier
333   .endif
334   FETCH_ADVANCE_INST 2
335   GET_INST_OPCODE ip
336   GOTO_OPCODE ip
337.L${opcode}_read_barrier:
338   bl      art_quick_read_barrier_mark_reg00
339   b       .L${opcode}_resume_after_read_barrier
340
341%def op_sput_slow_path(volatile_store, wide, is_object):
342   mov     x0, xSELF
343   ldr     x1, [sp]
344   mov     x2, xPC
345   .if $is_object
346   mov     x3, x26
347   .else
348   mov     x3, #0
349   .endif
350   EXPORT_PC
351   bl      nterp_get_static_field
352   .if $is_object
353   // Reload the value as it may have moved.
354   lsr     w2, wINST, #8               // w2 <- A
355   GET_VREG w26, w2                    // w26 <- v[A]
356   .endif
357   tbz     x0, #0, .L${opcode}_resume
358   CLEAR_STATIC_VOLATILE_MARKER x0
359   ldr     w1, [x0, #ART_FIELD_OFFSET_OFFSET]
360   ldr     w0, [x0, #ART_FIELD_DECLARING_CLASS_OFFSET]
361   cbnz    wMR, .L${opcode}_slow_path_read_barrier
362.L${opcode}_slow_path_resume_after_read_barrier:
363   add     x1, x0, x1
364   .if $wide
365   $volatile_store    x26, [x1]
366   .else
367   $volatile_store    w26, [x1]
368   WRITE_BARRIER_IF_OBJECT $is_object, w26, w0, .L${opcode}_slow_path_skip_write_barrier
369   .endif
370   FETCH_ADVANCE_INST 2
371   GET_INST_OPCODE ip
372   GOTO_OPCODE ip
373.L${opcode}_slow_path_read_barrier:
374   bl      art_quick_read_barrier_mark_reg00
375   b       .L${opcode}_slow_path_resume_after_read_barrier
376
377%def op_sput_wide():
378%  op_sput(store="str", volatile_store="stlr", wide="1", is_object="0")
379
380%def op_sput_object():
381%  op_sput(store="str", volatile_store="stlr", wide="0", is_object="1")
382
383%def op_new_instance():
384   EXPORT_PC
385   // Fast-path which gets the class from thread-local cache.
386   FETCH_FROM_THREAD_CACHE x0, 2f
387   cbnz    wMR, 3f
3884:
389   ldr     lr, [xSELF, #THREAD_ALLOC_OBJECT_ENTRYPOINT_OFFSET]
390   blr     lr
3911:
392   lsr     w1, wINST, #8               // w1 <- A
393   SET_VREG_OBJECT w0, w1              // fp[A] <- value
394   FETCH_ADVANCE_INST 2
395   GET_INST_OPCODE ip
396   GOTO_OPCODE ip
3972:
398   mov     x0, xSELF
399   ldr     x1, [sp]
400   mov     x2, xPC
401   bl      nterp_get_class_or_allocate_object
402   b       1b
4033:
404   bl      art_quick_read_barrier_mark_reg00
405   b       4b
406