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