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