1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
%def op_aget(load="movl", shift="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 */
movzbq 2(rPC), %rax # eax <- BB
movzbq 3(rPC), %rcx # ecx <- CC
GET_VREG %edi, %rax # eax <- vBB (array object)
GET_VREG %esi, %rcx # ecx <- vCC (requested index)
testl %edi, %edi # null array object?
je common_errNullObject # bail if so
cmpl MIRROR_ARRAY_LENGTH_OFFSET(%edi), %esi
jae common_errArrayIndex # index >= length, bail.
.if $wide
movq $data_offset(%rdi,%rsi,8), %rax
SET_WIDE_VREG %rax, rINSTq
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
.elseif $is_object
testb $$READ_BARRIER_TEST_VALUE, GRAY_BYTE_OFFSET(%edi)
$load $data_offset(%rdi,%rsi,$shift), %eax
jnz 2f
1:
SET_VREG_OBJECT %eax, rINSTq
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
2:
// reg00 is eax
call art_quick_read_barrier_mark_reg00
jmp 1b
.else
$load $data_offset(%rdi,%rsi,$shift), %eax
SET_VREG %eax, rINSTq
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
.endif
%def op_aget_boolean():
% op_aget(load="movzbl", shift="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET", is_object="0")
%def op_aget_byte():
% op_aget(load="movsbl", shift="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET", is_object="0")
%def op_aget_char():
% op_aget(load="movzwl", shift="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET", is_object="0")
%def op_aget_object():
% op_aget(load="movl", shift="4", data_offset="MIRROR_OBJECT_ARRAY_DATA_OFFSET", is_object="1")
%def op_aget_short():
% op_aget(load="movswl", shift="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET", is_object="0")
%def op_aget_wide():
% op_aget(load="movq", shift="8", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1", is_object="0")
%def op_aput(rINST_reg="rINST", store="movl", shift="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 */
movzbq 2(rPC), %rax # rax <- BB
movzbq 3(rPC), %rcx # rcx <- CC
GET_VREG %edi, %rax # edi <- vBB (array object)
GET_VREG %esi, %rcx # esi <- vCC (requested index)
testl %edi, %edi # null array object?
je common_errNullObject # bail if so
cmpl MIRROR_ARRAY_LENGTH_OFFSET(%edi), %esi
jae common_errArrayIndex # index >= length, bail.
.if $wide
GET_WIDE_VREG rINSTq, rINSTq
.else
GET_VREG rINST, rINSTq
.endif
$store $rINST_reg, $data_offset(%rdi,%rsi,$shift)
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
%def op_aput_boolean():
% op_aput(rINST_reg="rINSTbl", store="movb", shift="1", data_offset="MIRROR_BOOLEAN_ARRAY_DATA_OFFSET", wide="0")
%def op_aput_byte():
% op_aput(rINST_reg="rINSTbl", store="movb", shift="1", data_offset="MIRROR_BYTE_ARRAY_DATA_OFFSET", wide="0")
%def op_aput_char():
% op_aput(rINST_reg="rINSTw", store="movw", shift="2", data_offset="MIRROR_CHAR_ARRAY_DATA_OFFSET", wide="0")
%def op_aput_short():
% op_aput(rINST_reg="rINSTw", store="movw", shift="2", data_offset="MIRROR_SHORT_ARRAY_DATA_OFFSET", wide="0")
%def op_aput_wide():
% op_aput(rINST_reg="rINSTq", store="movq", shift="8", data_offset="MIRROR_WIDE_ARRAY_DATA_OFFSET", wide="1")
%def op_aput_object():
movzbq 2(rPC), %rax # rax <- BB
movzbq 3(rPC), %rcx # rcx <- CC
GET_VREG %edi, %rax # edi <- vBB (array object)
GET_VREG %esi, %rcx # esi <- vCC (requested index)
testl %edi, %edi # null array object?
je common_errNullObject # bail if so
cmpl MIRROR_ARRAY_LENGTH_OFFSET(%edi), %esi
jae common_errArrayIndex # index >= length, bail.
GET_VREG %edx, rINSTq
call art_quick_aput_obj
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, rINSTq # ecx <- vB (object ref)
testl %ecx, %ecx # is null?
je common_errNullObject
andb $$0xf, %al # eax <- A
movl MIRROR_ARRAY_LENGTH_OFFSET(%rcx), rINST
SET_VREG rINST, %rax
ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
%def op_fill_array_data():
/* fill-array-data vAA, +BBBBBBBB */
EXPORT_PC
movslq 2(rPC), %rcx # rcx <- ssssssssBBBBbbbb
leaq (rPC,%rcx,2), OUT_ARG0 # OUT_ARG0 <- PC + ssssssssBBBBbbbb*2
GET_VREG OUT_32_ARG1, rINSTq # OUT_ARG1 <- vAA (array object)
call art_quick_handle_fill_data
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
movq rSELF:THREAD_SELF_OFFSET, OUT_ARG0
movq (%rsp), OUT_ARG1
movq rFP, OUT_ARG2
movq rPC, OUT_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
|