1%def op_aget(load="movl", shift="4", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET", wide="0"):
2/*
3 * Array get, 32 bits or less.  vAA <- vBB[vCC].
4 *
5 * for: aget, aget-boolean, aget-byte, aget-char, aget-short, aget-wide
6 *
7 */
8    /* op vAA, vBB, vCC */
9    movzbq  2(rPC), %rax                    # eax <- BB
10    movzbq  3(rPC), %rcx                    # ecx <- CC
11    GET_VREG %eax, %rax                     # eax <- vBB (array object)
12    GET_VREG %ecx, %rcx                     # ecx <- vCC (requested index)
13    testl   %eax, %eax                      # null array object?
14    je      common_errNullObject            # bail if so
15    cmpl    MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
16    jae     common_errArrayIndex            # index >= length, bail.
17    .if $wide
18    movq    $data_offset(%rax,%rcx,8), %rax
19    SET_WIDE_VREG %rax, rINSTq
20    .else
21    $load   $data_offset(%rax,%rcx,$shift), %eax
22    SET_VREG %eax, rINSTq
23    .endif
24    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
25
26%def op_aget_boolean():
27%  op_aget(load="movzbl", shift="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
28
29%def op_aget_byte():
30%  op_aget(load="movsbl", shift="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
31
32%def op_aget_char():
33%  op_aget(load="movzwl", shift="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
34
35%def op_aget_object():
36/*
37 * Array object get.  vAA <- vBB[vCC].
38 *
39 * for: aget-object
40 */
41    /* op vAA, vBB, vCC */
42    movzbq  2(rPC), %rax                    # rax <- BB
43    movzbq  3(rPC), %rcx                    # rcx <- CC
44    GET_VREG OUT_32_ARG0, %rax              # eax <- vBB (array object)
45    GET_VREG OUT_32_ARG1, %rcx              # ecx <- vCC (requested index)
46    EXPORT_PC
47    call    SYMBOL(artAGetObjectFromMterp)  # (array, index)
48    movq    rSELF, %rcx
49    cmpq    $$0, THREAD_EXCEPTION_OFFSET(%rcx)
50    jnz     MterpException
51    SET_VREG_OBJECT %eax, rINSTq
52    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
53
54%def op_aget_short():
55%  op_aget(load="movswl", shift="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
56
57%def op_aget_wide():
58%  op_aget(load="movq", shift="8", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1")
59
60%def op_aput(reg="rINST", store="movl", shift="4", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET", wide="0"):
61/*
62 * Array put, 32 bits or less.  vBB[vCC] <- vAA.
63 *
64 * for: aput, aput-boolean, aput-byte, aput-char, aput-short, aput-wide
65 *
66 */
67    /* op vAA, vBB, vCC */
68    movzbq  2(rPC), %rax                    # rax <- BB
69    movzbq  3(rPC), %rcx                    # rcx <- CC
70    GET_VREG %eax, %rax                     # eax <- vBB (array object)
71    GET_VREG %ecx, %rcx                     # ecx <- vCC (requested index)
72    testl   %eax, %eax                      # null array object?
73    je      common_errNullObject            # bail if so
74    cmpl    MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
75    jae     common_errArrayIndex            # index >= length, bail.
76    .if $wide
77    GET_WIDE_VREG rINSTq, rINSTq
78    .else
79    GET_VREG rINST, rINSTq
80    .endif
81    $store    $reg, $data_offset(%rax,%rcx,$shift)
82    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
83
84%def op_aput_boolean():
85%  op_aput(reg="rINSTbl", store="movb", shift="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
86
87%def op_aput_byte():
88%  op_aput(reg="rINSTbl", store="movb", shift="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
89
90%def op_aput_char():
91%  op_aput(reg="rINSTw", store="movw", shift="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
92
93%def op_aput_object():
94/*
95 * Store an object into an array.  vBB[vCC] <- vAA.
96 */
97    /* op vAA, vBB, vCC */
98    EXPORT_PC
99    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
100    movq    rPC, OUT_ARG1
101    REFRESH_INST ${opnum}
102    movq    rINSTq, OUT_ARG2
103    call    SYMBOL(MterpAputObject)         # (array, index)
104    testb   %al, %al
105    jz      MterpPossibleException
106    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
107
108%def op_aput_short():
109%  op_aput(reg="rINSTw", store="movw", shift="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
110
111%def op_aput_wide():
112%  op_aput(reg="rINSTq", store="movq", shift="8", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1")
113
114%def op_array_length():
115/*
116 * Return the length of an array.
117 */
118    movl    rINST, %eax                     # eax <- BA
119    sarl    $$4, rINST                      # rINST <- B
120    GET_VREG %ecx, rINSTq                   # ecx <- vB (object ref)
121    testl   %ecx, %ecx                      # is null?
122    je      common_errNullObject
123    andb    $$0xf, %al                      # eax <- A
124    movl    MIRROR_ARRAY_LENGTH_OFFSET(%rcx), rINST
125    SET_VREG rINST, %rax
126    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
127
128%def op_fill_array_data():
129    /* fill-array-data vAA, +BBBBBBBB */
130    EXPORT_PC
131    movslq  2(rPC), %rcx                    # rcx <- ssssssssBBBBbbbb
132    leaq    (rPC,%rcx,2), OUT_ARG1          # OUT_ARG1 <- PC + ssssssssBBBBbbbb*2
133    GET_VREG OUT_32_ARG0, rINSTq            # OUT_ARG0 <- vAA (array object)
134    call    SYMBOL(MterpFillArrayData)      # (obj, payload)
135    testb   %al, %al                        # 0 means an exception is thrown
136    jz      MterpPossibleException
137    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
138
139%def op_filled_new_array(helper="MterpFilledNewArray"):
140/*
141 * Create a new array with elements filled from registers.
142 *
143 * for: filled-new-array, filled-new-array/range
144 */
145    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
146    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
147    .extern $helper
148    EXPORT_PC
149    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
150    movq    rPC, OUT_ARG1
151    movq    rSELF, OUT_ARG2
152    call    SYMBOL($helper)
153    testb   %al, %al                        # 0 means an exception is thrown
154    jz      MterpPossibleException
155    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
156
157%def op_filled_new_array_range():
158%  op_filled_new_array(helper="MterpFilledNewArrayRange")
159
160%def op_new_array():
161/*
162 * Allocate an array of objects, specified with the array class
163 * and a count.
164 *
165 * The verifier guarantees that this is an array class, so we don't
166 * check for it here.
167 */
168    /* new-array vA, vB, class@CCCC */
169    EXPORT_PC
170    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
171    movq    rPC, OUT_ARG1
172    REFRESH_INST ${opnum}
173    movq    rINSTq, OUT_ARG2
174    movq    rSELF, OUT_ARG3
175    call    SYMBOL(MterpNewArray)
176    testb   %al, %al                        # 0 means an exception is thrown
177    jz      MterpPossibleException
178    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
179