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