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