xref: /aosp_15_r20/art/runtime/interpreter/mterp/armng/array.S (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker%def op_aget(load="ldr", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET", wide="0", is_object="0"):
2*795d594fSAndroid Build Coastguard Worker/*
3*795d594fSAndroid Build Coastguard Worker * Array get.  vAA <- vBB[vCC].
4*795d594fSAndroid Build Coastguard Worker *
5*795d594fSAndroid Build Coastguard Worker * for: aget, aget-boolean, aget-byte, aget-char, aget-short, aget-wide, aget-object
6*795d594fSAndroid Build Coastguard Worker *
7*795d594fSAndroid Build Coastguard Worker */
8*795d594fSAndroid Build Coastguard Worker    FETCH_B r2, 1, 0                    @ r2<- BB
9*795d594fSAndroid Build Coastguard Worker    mov     r4, rINST, lsr #8           @ r4<- AA
10*795d594fSAndroid Build Coastguard Worker    FETCH_B r3, 1, 1                    @ r3<- CC
11*795d594fSAndroid Build Coastguard Worker    GET_VREG r0, r2                     @ r0<- vBB (array object)
12*795d594fSAndroid Build Coastguard Worker    GET_VREG r1, r3                     @ r1<- vCC (requested index)
13*795d594fSAndroid Build Coastguard Worker    cmp     r0, #0                      @ null array object?
14*795d594fSAndroid Build Coastguard Worker    beq     common_errNullObject        @ yes, bail
15*795d594fSAndroid Build Coastguard Worker    ldr     r3, [r0, #MIRROR_ARRAY_LENGTH_OFFSET]    @ r3<- arrayObj->length
16*795d594fSAndroid Build Coastguard Worker    add     r0, r0, r1, lsl #$shift     @ r0<- arrayObj + index*width
17*795d594fSAndroid Build Coastguard Worker    cmp     r1, r3                      @ compare unsigned index, length
18*795d594fSAndroid Build Coastguard Worker    bcs     common_errArrayIndex        @ index >= length, bail
19*795d594fSAndroid Build Coastguard Worker    FETCH_ADVANCE_INST 2                @ advance rPC, load rINST
20*795d594fSAndroid Build Coastguard Worker    .if $wide
21*795d594fSAndroid Build Coastguard Worker    CLEAR_SHADOW_PAIR r4, lr, ip        @ Zero out the shadow regs
22*795d594fSAndroid Build Coastguard Worker    ldrd    r2, [r0, #$data_offset]     @ r2/r3<- vBB[vCC]
23*795d594fSAndroid Build Coastguard Worker    VREG_INDEX_TO_ADDR r4, r4           @ r4<- &fp[AA]
24*795d594fSAndroid Build Coastguard Worker    GET_INST_OPCODE ip                  @ extract opcode from rINST
25*795d594fSAndroid Build Coastguard Worker    SET_VREG_WIDE_BY_ADDR r2, r3, r4    @ vAA/vAA+1<- r2/r3
26*795d594fSAndroid Build Coastguard Worker    GOTO_OPCODE ip                      @ jump to next instruction
27*795d594fSAndroid Build Coastguard Worker    .elseif $is_object
28*795d594fSAndroid Build Coastguard Worker    $load   r2, [r0, #$data_offset]     @ w2<- vBB[vCC]
29*795d594fSAndroid Build Coastguard Worker    UNPOISON_HEAP_REF r2
30*795d594fSAndroid Build Coastguard Worker    TEST_IF_MARKING 2f
31*795d594fSAndroid Build Coastguard Worker1:
32*795d594fSAndroid Build Coastguard Worker    GET_INST_OPCODE ip                  @ extract opcode from rINST
33*795d594fSAndroid Build Coastguard Worker    SET_VREG_OBJECT r2, r4              @ vAA<- w2
34*795d594fSAndroid Build Coastguard Worker    GOTO_OPCODE ip                      @ jump to next instruction
35*795d594fSAndroid Build Coastguard Worker2:
36*795d594fSAndroid Build Coastguard Worker    bl art_quick_read_barrier_mark_reg02
37*795d594fSAndroid Build Coastguard Worker    b 1b
38*795d594fSAndroid Build Coastguard Worker    .else
39*795d594fSAndroid Build Coastguard Worker    GET_INST_OPCODE ip                  @ extract opcode from rINST
40*795d594fSAndroid Build Coastguard Worker    $load   r2, [r0, #$data_offset]     @ r2<- vBB[vCC]
41*795d594fSAndroid Build Coastguard Worker    SET_VREG r2, r4                     @ vAA<- r2
42*795d594fSAndroid Build Coastguard Worker    GOTO_OPCODE ip                      @ jump to next instruction
43*795d594fSAndroid Build Coastguard Worker    .endif
44*795d594fSAndroid Build Coastguard Worker
45*795d594fSAndroid Build Coastguard Worker%def op_aget_boolean():
46*795d594fSAndroid Build Coastguard Worker%  op_aget(load="ldrb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET", wide="0", is_object="0")
47*795d594fSAndroid Build Coastguard Worker
48*795d594fSAndroid Build Coastguard Worker%def op_aget_byte():
49*795d594fSAndroid Build Coastguard Worker%  op_aget(load="ldrsb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET", wide="0", is_object="0")
50*795d594fSAndroid Build Coastguard Worker
51*795d594fSAndroid Build Coastguard Worker%def op_aget_char():
52*795d594fSAndroid Build Coastguard Worker%  op_aget(load="ldrh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET", wide="0", is_object="0")
53*795d594fSAndroid Build Coastguard Worker
54*795d594fSAndroid Build Coastguard Worker%def op_aget_object():
55*795d594fSAndroid Build Coastguard Worker%  op_aget(load="ldr", shift="2", data_offset="MIRROR_OBJECT_ARRAY_DATA_OFFSET", wide="0", is_object="1")
56*795d594fSAndroid Build Coastguard Worker
57*795d594fSAndroid Build Coastguard Worker%def op_aget_short():
58*795d594fSAndroid Build Coastguard Worker%  op_aget(load="ldrsh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET", wide="0", is_object="0")
59*795d594fSAndroid Build Coastguard Worker
60*795d594fSAndroid Build Coastguard Worker%def op_aget_wide():
61*795d594fSAndroid Build Coastguard Worker%  op_aget(load="ldrd", shift="3", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1", is_object="0")
62*795d594fSAndroid Build Coastguard Worker
63*795d594fSAndroid Build Coastguard Worker%def op_aput(store="str", shift="2", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET", wide="0", is_object="0"):
64*795d594fSAndroid Build Coastguard Worker/*
65*795d594fSAndroid Build Coastguard Worker * Array put.  vBB[vCC] <- vAA.
66*795d594fSAndroid Build Coastguard Worker *
67*795d594fSAndroid Build Coastguard Worker * for: aput, aput-boolean, aput-byte, aput-char, aput-short, aput-wide, aput-object
68*795d594fSAndroid Build Coastguard Worker *
69*795d594fSAndroid Build Coastguard Worker */
70*795d594fSAndroid Build Coastguard Worker    FETCH_B r2, 1, 0                    @ r2<- BB
71*795d594fSAndroid Build Coastguard Worker    mov     r4, rINST, lsr #8           @ r4<- AA
72*795d594fSAndroid Build Coastguard Worker    FETCH_B r3, 1, 1                    @ r3<- CC
73*795d594fSAndroid Build Coastguard Worker    GET_VREG r0, r2                     @ r0<- vBB (array object)
74*795d594fSAndroid Build Coastguard Worker    GET_VREG r1, r3                     @ r1<- vCC (requested index)
75*795d594fSAndroid Build Coastguard Worker    cmp     r0, #0                      @ null array object?
76*795d594fSAndroid Build Coastguard Worker    beq     common_errNullObject        @ yes, bail
77*795d594fSAndroid Build Coastguard Worker    ldr     r3, [r0, #MIRROR_ARRAY_LENGTH_OFFSET]     @ r3<- arrayObj->length
78*795d594fSAndroid Build Coastguard Worker    cmp     r1, r3                      @ compare unsigned index, length
79*795d594fSAndroid Build Coastguard Worker    bcs     common_errArrayIndex        @ index >= length, bail
80*795d594fSAndroid Build Coastguard Worker    .if $is_object
81*795d594fSAndroid Build Coastguard Worker    EXPORT_PC                           // Export PC before overwriting it.
82*795d594fSAndroid Build Coastguard Worker    FETCH_ADVANCE_INST 2                @ advance rPC, load rINST
83*795d594fSAndroid Build Coastguard Worker    GET_VREG r2, r4                     @ r2<- vAA
84*795d594fSAndroid Build Coastguard Worker    bl art_quick_aput_obj
85*795d594fSAndroid Build Coastguard Worker    GET_INST_OPCODE ip                  @ extract opcode from rINST
86*795d594fSAndroid Build Coastguard Worker    .elseif $wide
87*795d594fSAndroid Build Coastguard Worker    add     r0, r0, r1, lsl #$shift     @ r0<- arrayObj + index*width
88*795d594fSAndroid Build Coastguard Worker    VREG_INDEX_TO_ADDR r4, r4           @ r4<- &fp[AA]
89*795d594fSAndroid Build Coastguard Worker    FETCH_ADVANCE_INST 2                @ advance rPC, load rINST
90*795d594fSAndroid Build Coastguard Worker    GET_VREG_WIDE_BY_ADDR r2, r3, r4    @ r2/r3<- vAA/vAA+1
91*795d594fSAndroid Build Coastguard Worker    GET_INST_OPCODE ip                  @ extract opcode from rINST
92*795d594fSAndroid Build Coastguard Worker    strd    r2, [r0, #$data_offset]     @ r2/r3<- vBB[vCC]
93*795d594fSAndroid Build Coastguard Worker    .else
94*795d594fSAndroid Build Coastguard Worker    add     r0, r0, r1, lsl #$shift     @ r0<- arrayObj + index*width
95*795d594fSAndroid Build Coastguard Worker    FETCH_ADVANCE_INST 2                @ advance rPC, load rINST
96*795d594fSAndroid Build Coastguard Worker    GET_VREG r2, r4                     @ r2<- vAA
97*795d594fSAndroid Build Coastguard Worker    GET_INST_OPCODE ip                  @ extract opcode from rINST
98*795d594fSAndroid Build Coastguard Worker    $store  r2, [r0, #$data_offset]     @ vBB[vCC]<- r2
99*795d594fSAndroid Build Coastguard Worker    .endif
100*795d594fSAndroid Build Coastguard Worker    GOTO_OPCODE ip                      @ jump to next instruction
101*795d594fSAndroid Build Coastguard Worker
102*795d594fSAndroid Build Coastguard Worker%def op_aput_boolean():
103*795d594fSAndroid Build Coastguard Worker%  op_aput(store="strb", shift="0", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET", wide="0", is_object="0")
104*795d594fSAndroid Build Coastguard Worker
105*795d594fSAndroid Build Coastguard Worker%def op_aput_byte():
106*795d594fSAndroid Build Coastguard Worker%  op_aput(store="strb", shift="0", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET", wide="0", is_object="0")
107*795d594fSAndroid Build Coastguard Worker
108*795d594fSAndroid Build Coastguard Worker%def op_aput_char():
109*795d594fSAndroid Build Coastguard Worker%  op_aput(store="strh", shift="1", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET", wide="0", is_object="0")
110*795d594fSAndroid Build Coastguard Worker
111*795d594fSAndroid Build Coastguard Worker%def op_aput_short():
112*795d594fSAndroid Build Coastguard Worker%  op_aput(store="strh", shift="1", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET", wide="0", is_object="0")
113*795d594fSAndroid Build Coastguard Worker
114*795d594fSAndroid Build Coastguard Worker%def op_aput_wide():
115*795d594fSAndroid Build Coastguard Worker%  op_aput(store="str", shift="3", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1", is_object="0")
116*795d594fSAndroid Build Coastguard Worker
117*795d594fSAndroid Build Coastguard Worker%def op_aput_object():
118*795d594fSAndroid Build Coastguard Worker%  op_aput(store="str", shift="2", data_offset="MIRROR_OBJECT_ARRAY_DATA_OFFSET", wide="0", is_object="1")
119*795d594fSAndroid Build Coastguard Worker
120*795d594fSAndroid Build Coastguard Worker%def op_array_length():
121*795d594fSAndroid Build Coastguard Worker    /*
122*795d594fSAndroid Build Coastguard Worker     * Return the length of an array.
123*795d594fSAndroid Build Coastguard Worker     */
124*795d594fSAndroid Build Coastguard Worker    mov     r1, rINST, lsr #12          @ r1<- B
125*795d594fSAndroid Build Coastguard Worker    ubfx    r2, rINST, #8, #4           @ r2<- A
126*795d594fSAndroid Build Coastguard Worker    GET_VREG r0, r1                     @ r0<- vB (object ref)
127*795d594fSAndroid Build Coastguard Worker    cmp     r0, #0                      @ is object null?
128*795d594fSAndroid Build Coastguard Worker    beq     common_errNullObject        @ yup, fail
129*795d594fSAndroid Build Coastguard Worker    FETCH_ADVANCE_INST 1                @ advance rPC, load rINST
130*795d594fSAndroid Build Coastguard Worker    ldr     r3, [r0, #MIRROR_ARRAY_LENGTH_OFFSET]    @ r3<- array length
131*795d594fSAndroid Build Coastguard Worker    GET_INST_OPCODE ip                  @ extract opcode from rINST
132*795d594fSAndroid Build Coastguard Worker    SET_VREG r3, r2                     @ vB<- length
133*795d594fSAndroid Build Coastguard Worker    GOTO_OPCODE ip                      @ jump to next instruction
134*795d594fSAndroid Build Coastguard Worker
135*795d594fSAndroid Build Coastguard Worker%def op_fill_array_data():
136*795d594fSAndroid Build Coastguard Worker    /* fill-array-data vAA, +BBBBBBBB */
137*795d594fSAndroid Build Coastguard Worker    EXPORT_PC
138*795d594fSAndroid Build Coastguard Worker    FETCH r0, 1                         @ r0<- bbbb (lo)
139*795d594fSAndroid Build Coastguard Worker    FETCH r1, 2                         @ r1<- BBBB (hi)
140*795d594fSAndroid Build Coastguard Worker    mov     r3, rINST, lsr #8           @ r3<- AA
141*795d594fSAndroid Build Coastguard Worker    orr     r0, r0, r1, lsl #16         @ r0<- BBBBbbbb
142*795d594fSAndroid Build Coastguard Worker    GET_VREG r1, r3                     @ r1<- vAA (array object)
143*795d594fSAndroid Build Coastguard Worker    add     r0, rPC, r0, lsl #1         @ r1<- PC + BBBBbbbb*2 (array data off.)
144*795d594fSAndroid Build Coastguard Worker    bl      art_quick_handle_fill_data  @ (payload, object)
145*795d594fSAndroid Build Coastguard Worker    FETCH_ADVANCE_INST 3                @ advance rPC, load rINST
146*795d594fSAndroid Build Coastguard Worker    GET_INST_OPCODE ip                  @ extract opcode from rINST
147*795d594fSAndroid Build Coastguard Worker    GOTO_OPCODE ip                      @ jump to next instruction
148*795d594fSAndroid Build Coastguard Worker
149*795d594fSAndroid Build Coastguard Worker%def op_filled_new_array(helper="nterp_filled_new_array"):
150*795d594fSAndroid Build Coastguard Worker/*
151*795d594fSAndroid Build Coastguard Worker * Create a new array with elements filled from registers.
152*795d594fSAndroid Build Coastguard Worker *
153*795d594fSAndroid Build Coastguard Worker * for: filled-new-array, filled-new-array/range
154*795d594fSAndroid Build Coastguard Worker */
155*795d594fSAndroid Build Coastguard Worker    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
156*795d594fSAndroid Build Coastguard Worker    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
157*795d594fSAndroid Build Coastguard Worker    EXPORT_PC
158*795d594fSAndroid Build Coastguard Worker    mov     r0, rSELF
159*795d594fSAndroid Build Coastguard Worker    ldr     r1, [sp]
160*795d594fSAndroid Build Coastguard Worker    mov     r2, rFP
161*795d594fSAndroid Build Coastguard Worker    mov     r3, rPC
162*795d594fSAndroid Build Coastguard Worker    bl      $helper
163*795d594fSAndroid Build Coastguard Worker    FETCH_ADVANCE_INST 3                // advance rPC, load rINST
164*795d594fSAndroid Build Coastguard Worker    GET_INST_OPCODE ip                  // extract opcode from rINST
165*795d594fSAndroid Build Coastguard Worker    GOTO_OPCODE ip                      // jump to next instruction
166*795d594fSAndroid Build Coastguard Worker
167*795d594fSAndroid Build Coastguard Worker%def op_filled_new_array_range():
168*795d594fSAndroid Build Coastguard Worker%  op_filled_new_array(helper="nterp_filled_new_array_range")
169*795d594fSAndroid Build Coastguard Worker
170*795d594fSAndroid Build Coastguard Worker%def op_new_array():
171*795d594fSAndroid Build Coastguard Worker   /* new-array vA, vB, class@CCCC */
172*795d594fSAndroid Build Coastguard Worker   EXPORT_PC
173*795d594fSAndroid Build Coastguard Worker   // Fast-path which gets the class from thread-local cache.
174*795d594fSAndroid Build Coastguard Worker%  fetch_from_thread_cache("r0", miss_label="2f")
175*795d594fSAndroid Build Coastguard Worker   TEST_IF_MARKING 3f
176*795d594fSAndroid Build Coastguard Worker1:
177*795d594fSAndroid Build Coastguard Worker   lsr     r1, rINST, #12              // r1<- B
178*795d594fSAndroid Build Coastguard Worker   GET_VREG r1, r1                     // r1<- vB (array length)
179*795d594fSAndroid Build Coastguard Worker   ldr lr, [rSELF, #THREAD_ALLOC_ARRAY_ENTRYPOINT_OFFSET]
180*795d594fSAndroid Build Coastguard Worker   blx lr
181*795d594fSAndroid Build Coastguard Worker   dmb ishst                           // need fence for making array's class visible
182*795d594fSAndroid Build Coastguard Worker   ubfx    r1, rINST, #8, #4           // r1<- A
183*795d594fSAndroid Build Coastguard Worker   SET_VREG_OBJECT r0, r1
184*795d594fSAndroid Build Coastguard Worker   FETCH_ADVANCE_INST 2
185*795d594fSAndroid Build Coastguard Worker   GET_INST_OPCODE ip
186*795d594fSAndroid Build Coastguard Worker   GOTO_OPCODE ip
187*795d594fSAndroid Build Coastguard Worker2:
188*795d594fSAndroid Build Coastguard Worker   mov r0, rSELF
189*795d594fSAndroid Build Coastguard Worker   ldr r1, [sp]
190*795d594fSAndroid Build Coastguard Worker   mov r2, rPC
191*795d594fSAndroid Build Coastguard Worker   bl nterp_get_class
192*795d594fSAndroid Build Coastguard Worker   b 1b
193*795d594fSAndroid Build Coastguard Worker3:
194*795d594fSAndroid Build Coastguard Worker   bl art_quick_read_barrier_mark_reg00
195*795d594fSAndroid Build Coastguard Worker   b 1b
196