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