1%def op_aget(load="movl", shift="4", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET", wide="0", is_object="0"):
2/*
3 * Array get.  vAA <- vBB[vCC].
4 *
5 * for: aget, aget-boolean, aget-byte, aget-char, aget-short, aget-wide, aget-object
6 *
7 */
8    /* op vAA, vBB, vCC */
9    movzbq  2(rPC), %rax                    # eax <- BB
10    movzbq  3(rPC), %rcx                    # ecx <- CC
11    GET_VREG %edi, %rax                     # eax <- vBB (array object)
12    GET_VREG %esi, %rcx                     # ecx <- vCC (requested index)
13    testl   %edi, %edi                      # null array object?
14    je      common_errNullObject            # bail if so
15    cmpl    MIRROR_ARRAY_LENGTH_OFFSET(%edi), %esi
16    jae     common_errArrayIndex            # index >= length, bail.
17    .if $wide
18    movq    $data_offset(%rdi,%rsi,8), %rax
19    SET_WIDE_VREG %rax, rINSTq
20    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
21    .elseif $is_object
22    testb $$READ_BARRIER_TEST_VALUE, GRAY_BYTE_OFFSET(%edi)
23    $load   $data_offset(%rdi,%rsi,$shift), %eax
24    jnz 2f
251:
26    SET_VREG_OBJECT %eax, rINSTq
27    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
282:
29    // reg00 is eax
30    call art_quick_read_barrier_mark_reg00
31    jmp 1b
32    .else
33    $load   $data_offset(%rdi,%rsi,$shift), %eax
34    SET_VREG %eax, rINSTq
35    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
36    .endif
37
38%def op_aget_boolean():
39%  op_aget(load="movzbl", shift="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET", is_object="0")
40
41%def op_aget_byte():
42%  op_aget(load="movsbl", shift="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET", is_object="0")
43
44%def op_aget_char():
45%  op_aget(load="movzwl", shift="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET", is_object="0")
46
47%def op_aget_object():
48%  op_aget(load="movl", shift="4", data_offset="MIRROR_OBJECT_ARRAY_DATA_OFFSET", is_object="1")
49
50%def op_aget_short():
51%  op_aget(load="movswl", shift="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET", is_object="0")
52
53%def op_aget_wide():
54%  op_aget(load="movq", shift="8", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1", is_object="0")
55
56%def op_aput(rINST_reg="rINST", store="movl", shift="4", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET", wide="0"):
57/*
58 * Array put.  vBB[vCC] <- vAA.
59 *
60 * for: aput, aput-boolean, aput-byte, aput-char, aput-short, aput-wide
61 *
62 */
63    /* op vAA, vBB, vCC */
64    movzbq  2(rPC), %rax                    # rax <- BB
65    movzbq  3(rPC), %rcx                    # rcx <- CC
66    GET_VREG %edi, %rax                     # edi <- vBB (array object)
67    GET_VREG %esi, %rcx                     # esi <- vCC (requested index)
68    testl   %edi, %edi                      # null array object?
69    je      common_errNullObject            # bail if so
70    cmpl    MIRROR_ARRAY_LENGTH_OFFSET(%edi), %esi
71    jae     common_errArrayIndex            # index >= length, bail.
72    .if $wide
73    GET_WIDE_VREG rINSTq, rINSTq
74    .else
75    GET_VREG rINST, rINSTq
76    .endif
77    $store    $rINST_reg, $data_offset(%rdi,%rsi,$shift)
78    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
79
80%def op_aput_boolean():
81%  op_aput(rINST_reg="rINSTbl", store="movb", shift="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET", wide="0")
82
83%def op_aput_byte():
84%  op_aput(rINST_reg="rINSTbl", store="movb", shift="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET", wide="0")
85
86%def op_aput_char():
87%  op_aput(rINST_reg="rINSTw", store="movw", shift="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET", wide="0")
88
89%def op_aput_short():
90%  op_aput(rINST_reg="rINSTw", store="movw", shift="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET", wide="0")
91
92%def op_aput_wide():
93%  op_aput(rINST_reg="rINSTq", store="movq", shift="8", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1")
94
95%def op_aput_object():
96    EXPORT_PC                               # for the art_quick_aput_obj call
97    movzbq  2(rPC), %rax                    # rax <- BB
98    movzbq  3(rPC), %rcx                    # rcx <- CC
99    GET_VREG %edi, %rax                     # edi <- vBB (array object)
100    GET_VREG %esi, %rcx                     # esi <- vCC (requested index)
101    testl   %edi, %edi                      # null array object?
102    je      common_errNullObject            # bail if so
103    cmpl    MIRROR_ARRAY_LENGTH_OFFSET(%edi), %esi
104    jae     common_errArrayIndex            # index >= length, bail.
105    GET_VREG %edx, rINSTq
106    call art_quick_aput_obj
107    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
108
109%def op_array_length():
110/*
111 * Return the length of an array.
112 */
113    movl    rINST, %eax                     # eax <- BA
114    sarl    $$4, rINST                      # rINST <- B
115    GET_VREG %ecx, rINSTq                   # ecx <- vB (object ref)
116    testl   %ecx, %ecx                      # is null?
117    je      common_errNullObject
118    andb    $$0xf, %al                      # eax <- A
119    movl    MIRROR_ARRAY_LENGTH_OFFSET(%rcx), rINST
120    SET_VREG rINST, %rax
121    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
122
123%def op_fill_array_data():
124    /* fill-array-data vAA, +BBBBBBBB */
125    EXPORT_PC
126    movslq  2(rPC), %rcx                    # rcx <- ssssssssBBBBbbbb
127    leaq    (rPC,%rcx,2), OUT_ARG0          # OUT_ARG0 <- PC + ssssssssBBBBbbbb*2
128    GET_VREG OUT_32_ARG1, rINSTq            # OUT_ARG1 <- vAA (array object)
129    call    art_quick_handle_fill_data
130    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
131
132%def op_filled_new_array(helper="nterp_filled_new_array"):
133/*
134 * Create a new array with elements filled from registers.
135 *
136 * for: filled-new-array, filled-new-array/range
137 */
138    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
139    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
140    EXPORT_PC
141    movq    rSELF:THREAD_SELF_OFFSET, OUT_ARG0
142    movq    (%rsp), OUT_ARG1
143    movq    rFP, OUT_ARG2
144    movq    rPC, OUT_ARG3
145    call    SYMBOL($helper)
146    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
147
148%def op_filled_new_array_range():
149%  op_filled_new_array(helper="nterp_filled_new_array_range")
150
151%def op_new_array():
152  jmp NterpNewArray
153