blob: fced2e86209594813e57ee3375d96533d2d4204b [file] [log] [blame]
%def op_aget(load="movl", multiplier="4", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET", wide="0", is_object="0"):
/*
* Array get. vAA <- vBB[vCC].
*
* for: aget, aget-boolean, aget-byte, aget-char, aget-short, aget-wide, aget-object
*
*/
/* op vAA, vBB, vCC */
movzbl 2(rPC), %eax # eax <- BB
movzbl 3(rPC), %ecx # ecx <- CC
GET_VREG %eax, %eax # eax <- vBB (array object)
GET_VREG %ecx, %ecx # ecx <- vCC (requested index)
testl %eax, %eax # null array object?
je common_errNullObject # bail if so
cmpl MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
jae common_errArrayIndex # index >= length, bail.
.if $wide
movq $data_offset(%eax,%ecx,8), %xmm0
SET_WIDE_FP_VREG %xmm0, rINST # vAA <- xmm0
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
.elseif $is_object
testb $$READ_BARRIER_TEST_VALUE, GRAY_BYTE_OFFSET(%eax)
$load $data_offset(%eax,%ecx,$multiplier), %eax
jnz 2f
1:
SET_VREG_OBJECT %eax, rINST
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
2:
// reg00 is eax
call art_quick_read_barrier_mark_reg00
jmp 1b
.else
$load $data_offset(%eax,%ecx,$multiplier), %eax
SET_VREG %eax, rINST
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
.endif
%def op_aget_boolean():
% op_aget(load="movzbl", multiplier="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
%def op_aget_byte():
% op_aget(load="movsbl", multiplier="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
%def op_aget_char():
% op_aget(load="movzwl", multiplier="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
%def op_aget_object():
% op_aget(load="movl", multiplier="4", data_offset="MIRROR_OBJECT_ARRAY_DATA_OFFSET", is_object="1")
%def op_aget_short():
% op_aget(load="movswl", multiplier="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
%def op_aget_wide():
% op_aget(load="", multiplier="8", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1")
%def op_aput(rINST_reg="rINST", store="movl", multiplier="4", data_offset="MIRROR_INT_ARRAY_DATA_OFFSET", wide="0"):
/*
* Array put. vBB[vCC] <- vAA.
*
* for: aput, aput-boolean, aput-byte, aput-char, aput-short, aput-wide
*
*/
/* op vAA, vBB, vCC */
movzbl 2(rPC), %eax # eax <- BB
movzbl 3(rPC), %ecx # ecx <- CC
GET_VREG %eax, %eax # eax <- vBB (array object)
GET_VREG %ecx, %ecx # ecx <- vCC (requested index)
testl %eax, %eax # null array object?
je common_errNullObject # bail if so
cmpl MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
jae common_errArrayIndex # index >= length, bail.
.if $wide
GET_WIDE_FP_VREG %xmm0, rINST # xmm0 <- vAA
movq %xmm0, $data_offset(%eax,%ecx,8) # vBB[vCC] <- xmm0
.else
GET_VREG rINST, rINST
$store $rINST_reg, $data_offset(%eax,%ecx,$multiplier)
.endif
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
%def op_aput_boolean():
% op_aput(rINST_reg="rINSTbl", store="movb", multiplier="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET")
%def op_aput_byte():
% op_aput(rINST_reg="rINSTbl", store="movb", multiplier="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET")
%def op_aput_char():
% op_aput(rINST_reg="rINSTw", store="movw", multiplier="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET")
%def op_aput_short():
% op_aput(rINST_reg="rINSTw", store="movw", multiplier="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET")
%def op_aput_wide():
% op_aput(rINST_reg="", store="", multiplier="8", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1")
%def op_aput_object():
EXPORT_PC # for the art_quick_aput_obj call
movzbl 2(rPC), %eax # eax <- BB
movzbl 3(rPC), %ecx # ecx <- CC
GET_VREG %eax, %eax # eax <- vBB (array object)
GET_VREG %ecx, %ecx # ecx <- vCC (requested index)
testl %eax, %eax # null array object?
je common_errNullObject # bail if so
cmpl MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ecx
jae common_errArrayIndex # index >= length, bail.
GET_VREG %edx, rINST
call art_quick_aput_obj
RESTORE_IBASE # edx got overwritten, restore it
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
%def op_array_length():
/*
* Return the length of an array.
*/
movl rINST, %eax # eax <- BA
sarl $$4, rINST # rINST <- B
GET_VREG %ecx, rINST # ecx <- vB (object ref)
testl %ecx, %ecx # is null?
je common_errNullObject
andb $$0xf, %al # eax <- A
movl MIRROR_ARRAY_LENGTH_OFFSET(%ecx), rINST
SET_VREG rINST, %eax
ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
%def op_fill_array_data():
/* fill-array-data vAA, +BBBBBBBB */
EXPORT_PC
movl 2(rPC), %ecx # ecx <- BBBBbbbb
leal (rPC,%ecx,2), ARG0 # ARG0 <- PC + BBBBbbbb*2
GET_VREG ARG1, rINST # ARG1 <- vAA (array object)
call art_quick_handle_fill_data
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
%def op_filled_new_array(helper="nterp_filled_new_array"):
/*
* Create a new array with elements filled from registers.
*
* for: filled-new-array, filled-new-array/range
*/
/* op vB, {vD, vE, vF, vG, vA}, class@CCCC */
/* op {vCCCC..v(CCCC+AA-1)}, type@BBBB */
EXPORT_PC
movl rSELF:THREAD_SELF_OFFSET, ARG0
movl (%esp), ARG1
movl rFP, ARG2
movl rPC, ARG3
call SYMBOL($helper)
ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
%def op_filled_new_array_range():
% op_filled_new_array(helper="nterp_filled_new_array_range")
%def op_new_array():
jmp NterpNewArray