• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1%def op_aget(load="lw", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
2    /*
3     * Array get, 32 bits or less.  vAA <- vBB[vCC].
4     *
5     * Note: using the usual FETCH/and/shift stuff, this fits in exactly 17
6     * instructions.  We use a pair of FETCH_Bs instead.
7     *
8     * for: aget, aget-boolean, aget-byte, aget-char, aget-short
9     *
10     * NOTE: assumes data offset for arrays is the same for all non-wide types.
11     * If this changes, specialize.
12     */
13    /* op vAA, vBB, vCC */
14    FETCH_B(a2, 1, 0)                      #  a2 <- BB
15    GET_OPA(rOBJ)                          #  rOBJ <- AA
16    FETCH_B(a3, 1, 1)                      #  a3 <- CC
17    GET_VREG(a0, a2)                       #  a0 <- vBB (array object)
18    GET_VREG(a1, a3)                       #  a1 <- vCC (requested index)
19    # null array object?
20    beqz      a0, common_errNullObject     #  yes, bail
21    LOAD_base_offMirrorArray_length(a3, a0) #  a3 <- arrayObj->length
22    EASN(a0, a0, a1, $shift)               #  a0 <- arrayObj + index*width
23    # a1 >= a3; compare unsigned index
24    bgeu      a1, a3, common_errArrayIndex #  index >= length, bail
25    FETCH_ADVANCE_INST(2)                  #  advance rPC, load rINST
26    $load a2, $data_offset(a0)             #  a2 <- vBB[vCC]
27    GET_INST_OPCODE(t0)                    #  extract opcode from rINST
28    SET_VREG_GOTO(a2, rOBJ, t0)            #  vAA <- a2
29
30%def op_aget_boolean():
31%  op_aget(load="lbu", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
32
33%def op_aget_byte():
34%  op_aget(load="lb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
35
36%def op_aget_char():
37%  op_aget(load="lhu", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
38
39%def op_aget_object():
40    /*
41     * Array object get.  vAA <- vBB[vCC].
42     *
43     * for: aget-object
44     */
45    /* op vAA, vBB, vCC */
46    FETCH_B(a2, 1, 0)                      #  a2 <- BB
47    GET_OPA(rOBJ)                          #  rOBJ <- AA
48    FETCH_B(a3, 1, 1)                      #  a3 <- CC
49    EXPORT_PC()
50    GET_VREG(a0, a2)                       #  a0 <- vBB (array object)
51    GET_VREG(a1, a3)                       #  a1 <- vCC (requested index)
52    JAL(artAGetObjectFromMterp)            #  v0 <- GetObj(array, index)
53    lw   a1, THREAD_EXCEPTION_OFFSET(rSELF)
54    PREFETCH_INST(2)                       #  load rINST
55    bnez a1, MterpException
56    ADVANCE(2)                             #  advance rPC
57    GET_INST_OPCODE(t0)                    #  extract opcode from rINST
58    SET_VREG_OBJECT_GOTO(v0, rOBJ, t0)     #  vAA <- v0
59
60%def op_aget_short():
61%  op_aget(load="lh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
62
63%def op_aget_wide():
64    /*
65     * Array get, 64 bits.  vAA <- vBB[vCC].
66     *
67     * Arrays of long/double are 64-bit aligned.
68     */
69    /* aget-wide vAA, vBB, vCC */
70    FETCH(a0, 1)                           #  a0 <- CCBB
71    GET_OPA(rOBJ)                          #  rOBJ <- AA
72    and       a2, a0, 255                  #  a2 <- BB
73    srl       a3, a0, 8                    #  a3 <- CC
74    GET_VREG(a0, a2)                       #  a0 <- vBB (array object)
75    GET_VREG(a1, a3)                       #  a1 <- vCC (requested index)
76    # null array object?
77    beqz      a0, common_errNullObject     #  yes, bail
78    LOAD_base_offMirrorArray_length(a3, a0) #  a3 <- arrayObj->length
79    EAS3(a0, a0, a1)                       #  a0 <- arrayObj + index*width
80    bgeu      a1, a3, common_errArrayIndex #  index >= length, bail
81
82    FETCH_ADVANCE_INST(2)                  #  advance rPC, load rINST
83    LOAD64_off(a2, a3, a0, MIRROR_WIDE_ARRAY_DATA_OFFSET)
84    GET_INST_OPCODE(t0)                    #  extract opcode from rINST
85    SET_VREG64_GOTO(a2, a3, rOBJ, t0)      #  vAA/vAA+1 <- a2/a3
86
87%def op_aput(store="sw", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET"):
88
89    /*
90     * Array put, 32 bits or less.  vBB[vCC] <- vAA.
91     *
92     * for: aput, aput-boolean, aput-byte, aput-char, aput-short
93     *
94     * NOTE: this assumes data offset for arrays is the same for all non-wide types.
95     * If this changes, specialize.
96     */
97    /* op vAA, vBB, vCC */
98    FETCH_B(a2, 1, 0)                      #  a2 <- BB
99    GET_OPA(rOBJ)                          #  rOBJ <- AA
100    FETCH_B(a3, 1, 1)                      #  a3 <- CC
101    GET_VREG(a0, a2)                       #  a0 <- vBB (array object)
102    GET_VREG(a1, a3)                       #  a1 <- vCC (requested index)
103    # null array object?
104    beqz      a0, common_errNullObject     #  yes, bail
105    LOAD_base_offMirrorArray_length(a3, a0) #  a3 <- arrayObj->length
106    EASN(a0, a0, a1, $shift)               #  a0 <- arrayObj + index*width
107    bgeu      a1, a3, common_errArrayIndex #  index >= length, bail
108    FETCH_ADVANCE_INST(2)                  #  advance rPC, load rINST
109    GET_VREG(a2, rOBJ)                     #  a2 <- vAA
110    GET_INST_OPCODE(t0)                    #  extract opcode from rINST
111    GET_OPCODE_TARGET(t0)
112    $store a2, $data_offset(a0)            #  vBB[vCC] <- a2
113    JR(t0)                                 #  jump to next instruction
114
115%def op_aput_boolean():
116%  op_aput(store="sb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
117
118%def op_aput_byte():
119%  op_aput(store="sb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
120
121%def op_aput_char():
122%  op_aput(store="sh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
123
124%def op_aput_object():
125    /*
126     * Store an object into an array.  vBB[vCC] <- vAA.
127     *
128     */
129    /* op vAA, vBB, vCC */
130    EXPORT_PC()
131    addu   a0, rFP, OFF_FP_SHADOWFRAME
132    move   a1, rPC
133    move   a2, rINST
134    JAL(MterpAputObject)
135    beqz   v0, MterpPossibleException
136    FETCH_ADVANCE_INST(2)               # advance rPC, load rINST
137    GET_INST_OPCODE(t0)                 # extract opcode from rINST
138    GOTO_OPCODE(t0)                     # jump to next instruction
139
140%def op_aput_short():
141%  op_aput(store="sh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
142
143%def op_aput_wide():
144    /*
145     * Array put, 64 bits.  vBB[vCC] <- vAA.
146     */
147    /* aput-wide vAA, vBB, vCC */
148    FETCH(a0, 1)                           #  a0 <- CCBB
149    GET_OPA(t0)                            #  t0 <- AA
150    and       a2, a0, 255                  #  a2 <- BB
151    srl       a3, a0, 8                    #  a3 <- CC
152    GET_VREG(a0, a2)                       #  a0 <- vBB (array object)
153    GET_VREG(a1, a3)                       #  a1 <- vCC (requested index)
154    # null array object?
155    beqz      a0, common_errNullObject     #  yes, bail
156    LOAD_base_offMirrorArray_length(a3, a0) #  a3 <- arrayObj->length
157    EAS3(a0, a0, a1)                       #  a0 <- arrayObj + index*width
158    EAS2(rOBJ, rFP, t0)                    #  rOBJ <- &fp[AA]
159    # compare unsigned index, length
160    bgeu      a1, a3, common_errArrayIndex #  index >= length, bail
161
162    FETCH_ADVANCE_INST(2)                  #  advance rPC, load rINST
163    LOAD64(a2, a3, rOBJ)                   #  a2/a3 <- vAA/vAA+1
164    GET_INST_OPCODE(t0)                    #  extract opcode from rINST
165    GET_OPCODE_TARGET(t0)
166    STORE64_off(a2, a3, a0, MIRROR_WIDE_ARRAY_DATA_OFFSET) #  a2/a3 <- vBB[vCC]
167    JR(t0)                                 #  jump to next instruction
168
169%def op_array_length():
170    /*
171     * Return the length of an array.
172     */
173    /* array-length vA, vB */
174    GET_OPB(a1)                            #  a1 <- B
175    GET_OPA4(a2)                           #  a2 <- A+
176    GET_VREG(a0, a1)                       #  a0 <- vB (object ref)
177    # is object null?
178    beqz      a0, common_errNullObject     #  yup, fail
179    FETCH_ADVANCE_INST(1)                  #  advance rPC, load rINST
180    LOAD_base_offMirrorArray_length(a3, a0) #  a3 <- array length
181    GET_INST_OPCODE(t0)                    #  extract opcode from rINST
182    SET_VREG_GOTO(a3, a2, t0)              #  vA <- length
183
184%def op_fill_array_data():
185    /* fill-array-data vAA, +BBBBBBBB */
186    EXPORT_PC()
187    FETCH(a1, 1)                           #  a1 <- bbbb (lo)
188    FETCH(a0, 2)                           #  a0 <- BBBB (hi)
189    GET_OPA(a3)                            #  a3 <- AA
190    INSERT_HIGH_HALF(a1, a0)               #  a1 <- BBBBbbbb
191    GET_VREG(a0, a3)                       #  a0 <- vAA (array object)
192    EAS1(a1, rPC, a1)                      #  a1 <- PC + BBBBbbbb*2 (array data off.)
193    JAL(MterpFillArrayData)                #  v0 <- Mterp(obj, payload)
194    beqz      v0,  MterpPossibleException  #  has exception
195    FETCH_ADVANCE_INST(3)                  #  advance rPC, load rINST
196    GET_INST_OPCODE(t0)                    #  extract opcode from rINST
197    GOTO_OPCODE(t0)                        #  jump to next instruction
198
199%def op_filled_new_array(helper="MterpFilledNewArray"):
200    /*
201     * Create a new array with elements filled from registers.
202     *
203     * for: filled-new-array, filled-new-array/range
204     */
205    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
206    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
207    .extern $helper
208    EXPORT_PC()
209    addu   a0, rFP, OFF_FP_SHADOWFRAME     # a0 <- shadow frame
210    move   a1, rPC
211    move   a2, rSELF
212    JAL($helper)                           #  v0 <- helper(shadow_frame, pc, self)
213    beqz      v0,  MterpPossibleException  #  has exception
214    FETCH_ADVANCE_INST(3)                  #  advance rPC, load rINST
215    GET_INST_OPCODE(t0)                    #  extract opcode from rINST
216    GOTO_OPCODE(t0)                        #  jump to next instruction
217
218%def op_filled_new_array_range():
219%  op_filled_new_array(helper="MterpFilledNewArrayRange")
220
221%def op_new_array():
222    /*
223     * Allocate an array of objects, specified with the array class
224     * and a count.
225     *
226     * The verifier guarantees that this is an array class, so we don't
227     * check for it here.
228     */
229    /* new-array vA, vB, class@CCCC */
230    EXPORT_PC()
231    addu   a0, rFP, OFF_FP_SHADOWFRAME
232    move   a1, rPC
233    move   a2, rINST
234    move   a3, rSELF
235    JAL(MterpNewArray)
236    beqz   v0, MterpPossibleException
237    FETCH_ADVANCE_INST(2)               # advance rPC, load rINST
238    GET_INST_OPCODE(t0)                 # extract opcode from rINST
239    GOTO_OPCODE(t0)                     # jump to next instruction
240