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