xref: /aosp_15_r20/art/runtime/interpreter/mterp/x86ng/array.S (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker%def op_aget(load="movl", multiplier="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    movzbl  2(rPC), %eax                    # eax <- BB
10*795d594fSAndroid Build Coastguard Worker    movzbl  3(rPC), %ecx                    # ecx <- CC
11*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, %eax                     # eax <- vBB (array object)
12*795d594fSAndroid Build Coastguard Worker    GET_VREG %ecx, %ecx                     # ecx <- vCC (requested index)
13*795d594fSAndroid Build Coastguard Worker    testl   %eax, %eax                      # null array object?
14*795d594fSAndroid Build Coastguard Worker    je      common_errNullObject            # bail if so
15*795d594fSAndroid Build Coastguard Worker    cmpl    MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
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(%eax,%ecx,8), %xmm0
19*795d594fSAndroid Build Coastguard Worker    SET_WIDE_FP_VREG %xmm0, rINST           # vAA <- xmm0
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(%eax)
23*795d594fSAndroid Build Coastguard Worker    $load   $data_offset(%eax,%ecx,$multiplier), %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, rINST
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(%eax,%ecx,$multiplier), %eax
36*795d594fSAndroid Build Coastguard Worker    SET_VREG %eax, rINST
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", multiplier="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
42*795d594fSAndroid Build Coastguard Worker
43*795d594fSAndroid Build Coastguard Worker%def op_aget_byte():
44*795d594fSAndroid Build Coastguard Worker%  op_aget(load="movsbl", multiplier="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
45*795d594fSAndroid Build Coastguard Worker
46*795d594fSAndroid Build Coastguard Worker%def op_aget_char():
47*795d594fSAndroid Build Coastguard Worker%  op_aget(load="movzwl", multiplier="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
48*795d594fSAndroid Build Coastguard Worker
49*795d594fSAndroid Build Coastguard Worker%def op_aget_object():
50*795d594fSAndroid Build Coastguard Worker%  op_aget(load="movl", multiplier="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", multiplier="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
54*795d594fSAndroid Build Coastguard Worker
55*795d594fSAndroid Build Coastguard Worker%def op_aget_wide():
56*795d594fSAndroid Build Coastguard Worker%  op_aget(load="", multiplier="8", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1")
57*795d594fSAndroid Build Coastguard Worker
58*795d594fSAndroid Build Coastguard Worker%def op_aput(rINST_reg="rINST", store="movl", multiplier="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    movzbl  2(rPC), %eax                     # eax <- BB
67*795d594fSAndroid Build Coastguard Worker    movzbl  3(rPC), %ecx                     # ecx <- CC
68*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, %eax                      # eax <- vBB (array object)
69*795d594fSAndroid Build Coastguard Worker    GET_VREG %ecx, %ecx                      # ecx <- vCC (requested index)
70*795d594fSAndroid Build Coastguard Worker    testl   %eax, %eax                       # null array object?
71*795d594fSAndroid Build Coastguard Worker    je      common_errNullObject             # bail if so
72*795d594fSAndroid Build Coastguard Worker    cmpl    MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
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_FP_VREG %xmm0, rINST            # xmm0 <- vAA
76*795d594fSAndroid Build Coastguard Worker    movq    %xmm0, $data_offset(%eax,%ecx,8) # vBB[vCC] <- xmm0
77*795d594fSAndroid Build Coastguard Worker    .else
78*795d594fSAndroid Build Coastguard Worker    GET_VREG rINST, rINST
79*795d594fSAndroid Build Coastguard Worker    $store    $rINST_reg, $data_offset(%eax,%ecx,$multiplier)
80*795d594fSAndroid Build Coastguard Worker    .endif
81*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
82*795d594fSAndroid Build Coastguard Worker
83*795d594fSAndroid Build Coastguard Worker%def op_aput_boolean():
84*795d594fSAndroid Build Coastguard Worker%  op_aput(rINST_reg="rINSTbl", store="movb", multiplier="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
85*795d594fSAndroid Build Coastguard Worker
86*795d594fSAndroid Build Coastguard Worker%def op_aput_byte():
87*795d594fSAndroid Build Coastguard Worker%  op_aput(rINST_reg="rINSTbl", store="movb", multiplier="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
88*795d594fSAndroid Build Coastguard Worker
89*795d594fSAndroid Build Coastguard Worker%def op_aput_char():
90*795d594fSAndroid Build Coastguard Worker%  op_aput(rINST_reg="rINSTw", store="movw", multiplier="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
91*795d594fSAndroid Build Coastguard Worker
92*795d594fSAndroid Build Coastguard Worker%def op_aput_short():
93*795d594fSAndroid Build Coastguard Worker%  op_aput(rINST_reg="rINSTw", store="movw", multiplier="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
94*795d594fSAndroid Build Coastguard Worker
95*795d594fSAndroid Build Coastguard Worker%def op_aput_wide():
96*795d594fSAndroid Build Coastguard Worker%  op_aput(rINST_reg="", store="", multiplier="8", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1")
97*795d594fSAndroid Build Coastguard Worker
98*795d594fSAndroid Build Coastguard Worker%def op_aput_object():
99*795d594fSAndroid Build Coastguard Worker    EXPORT_PC                               # for the art_quick_aput_obj call
100*795d594fSAndroid Build Coastguard Worker    movzbl  2(rPC), %eax                    # eax <- BB
101*795d594fSAndroid Build Coastguard Worker    movzbl  3(rPC), %ecx                    # ecx <- CC
102*795d594fSAndroid Build Coastguard Worker    GET_VREG %eax, %eax                     # eax <- vBB (array object)
103*795d594fSAndroid Build Coastguard Worker    GET_VREG %ecx, %ecx                     # ecx <- vCC (requested index)
104*795d594fSAndroid Build Coastguard Worker    testl   %eax, %eax                      # null array object?
105*795d594fSAndroid Build Coastguard Worker    je      common_errNullObject            # bail if so
106*795d594fSAndroid Build Coastguard Worker    cmpl    MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
107*795d594fSAndroid Build Coastguard Worker    jae     common_errArrayIndex            # index >= length, bail.
108*795d594fSAndroid Build Coastguard Worker    GET_VREG %edx, rINST
109*795d594fSAndroid Build Coastguard Worker    call art_quick_aput_obj
110*795d594fSAndroid Build Coastguard Worker    RESTORE_IBASE                           # edx got overwritten, restore it
111*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
112*795d594fSAndroid Build Coastguard Worker
113*795d594fSAndroid Build Coastguard Worker%def op_array_length():
114*795d594fSAndroid Build Coastguard Worker/*
115*795d594fSAndroid Build Coastguard Worker * Return the length of an array.
116*795d594fSAndroid Build Coastguard Worker */
117*795d594fSAndroid Build Coastguard Worker    movl    rINST, %eax                     # eax <- BA
118*795d594fSAndroid Build Coastguard Worker    sarl    $$4, rINST                      # rINST <- B
119*795d594fSAndroid Build Coastguard Worker    GET_VREG %ecx, rINST                    # ecx <- vB (object ref)
120*795d594fSAndroid Build Coastguard Worker    testl   %ecx, %ecx                      # is null?
121*795d594fSAndroid Build Coastguard Worker    je      common_errNullObject
122*795d594fSAndroid Build Coastguard Worker    andb    $$0xf, %al                      # eax <- A
123*795d594fSAndroid Build Coastguard Worker    movl    MIRROR_ARRAY_LENGTH_OFFSET(%ecx), rINST
124*795d594fSAndroid Build Coastguard Worker    SET_VREG rINST, %eax
125*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
126*795d594fSAndroid Build Coastguard Worker
127*795d594fSAndroid Build Coastguard Worker%def op_fill_array_data():
128*795d594fSAndroid Build Coastguard Worker    /* fill-array-data vAA, +BBBBBBBB */
129*795d594fSAndroid Build Coastguard Worker    EXPORT_PC
130*795d594fSAndroid Build Coastguard Worker    movl    2(rPC), %ecx                    # ecx <- BBBBbbbb
131*795d594fSAndroid Build Coastguard Worker    leal    (rPC,%ecx,2), ARG0              # ARG0 <- PC + BBBBbbbb*2
132*795d594fSAndroid Build Coastguard Worker    GET_VREG ARG1, rINST                    # ARG1 <- vAA (array object)
133*795d594fSAndroid Build Coastguard Worker    call    art_quick_handle_fill_data
134*795d594fSAndroid Build Coastguard Worker    RESTORE_IBASE
135*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
136*795d594fSAndroid Build Coastguard Worker
137*795d594fSAndroid Build Coastguard Worker%def op_filled_new_array(helper="nterp_filled_new_array"):
138*795d594fSAndroid Build Coastguard Worker/*
139*795d594fSAndroid Build Coastguard Worker * Create a new array with elements filled from registers.
140*795d594fSAndroid Build Coastguard Worker *
141*795d594fSAndroid Build Coastguard Worker * for: filled-new-array, filled-new-array/range
142*795d594fSAndroid Build Coastguard Worker */
143*795d594fSAndroid Build Coastguard Worker    /* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
144*795d594fSAndroid Build Coastguard Worker    /* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
145*795d594fSAndroid Build Coastguard Worker    EXPORT_PC
146*795d594fSAndroid Build Coastguard Worker    movl    rSELF:THREAD_SELF_OFFSET, ARG0
147*795d594fSAndroid Build Coastguard Worker    movl    (%esp), ARG1
148*795d594fSAndroid Build Coastguard Worker    movl    rFP, ARG2
149*795d594fSAndroid Build Coastguard Worker    movl    rPC, ARG3
150*795d594fSAndroid Build Coastguard Worker    call    SYMBOL($helper)
151*795d594fSAndroid Build Coastguard Worker    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
152*795d594fSAndroid Build Coastguard Worker
153*795d594fSAndroid Build Coastguard Worker%def op_filled_new_array_range():
154*795d594fSAndroid Build Coastguard Worker%  op_filled_new_array(helper="nterp_filled_new_array_range")
155*795d594fSAndroid Build Coastguard Worker
156*795d594fSAndroid Build Coastguard Worker%def op_new_array():
157*795d594fSAndroid Build Coastguard Worker  jmp NterpNewArray
158