On 3/14/20 10:15 PM, LIU Zhiwei wrote: > > > On 2020/3/15 10:53, Richard Henderson wrote: >> On 3/12/20 7:58 AM, LIU Zhiwei wrote: >>> +static bool trans_vext_x_v(DisasContext *s, arg_r *a) >>> +{ >>> + if (vext_check_isa_ill(s, RVV)) { >>> + TCGv_ptr src2; >>> + TCGv dest, src1; >>> + gen_helper_vext_x_v fns[4] = { >>> + gen_helper_vext_x_v_b, gen_helper_vext_x_v_h, >>> + gen_helper_vext_x_v_w, gen_helper_vext_x_v_d >>> + }; >>> + >>> + dest = tcg_temp_new(); >>> + src1 = tcg_temp_new(); >>> + src2 = tcg_temp_new_ptr(); >>> + >>> + gen_get_gpr(src1, a->rs1); >>> + tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2)); >>> + >>> + fns[s->sew](dest, src2, src1, cpu_env); >>> + gen_set_gpr(a->rd, dest); >>> + >>> + tcg_temp_free(dest); >>> + tcg_temp_free(src1); >>> + tcg_temp_free_ptr(src2); >>> + return true; >>> + } >>> + return false; >>> +} >> This entire operation can be performed inline easily. >> >> static void extract_element(TCGv dest, TCGv_ptr base, >> int ofs, int sew) >> { >> switch (sew) { >> case MO_8: >> tcg_gen_ld8u_tl(dest, base, ofs); >> break; >> case MO_16: >> tcg_gen_ld16u_tl(dest, base, ofs); >> break; >> default: >> tcg_gen_ld32u_tl(dest, base, ofs); >> break; >> #if TARGET_LONG_BITS == 64 >> case MO_64: >> tcg_gen_ld_i64(dest, base, ofs); >> break; >> #endif >> } >> } >> >> static bool trans_vext_x_v(DisasContext *s, arg_r *a) >> { >> ... >> if (a->rs1 == 0) { >> /* Special case vmv.x.s rd, vs2. */ >> do_extract(dest, cpu_env, >> vreg_ofs(s, a->rs2), s->sew); >> } else { >> int vlen = s->vlen >> (3 + s->sew); >> TCGv_i32 ofs = tcg_temp_new_i32(); >> TCGv_ptr base = tcg_temp_new_ptr(); >> TCGv t_vlen, t_zero; >> >> /* Mask the index to the length so that we do >> not produce an out-of-range load. */ >> tcg_gen_trunc_tl_i32(ofs, cpu_gpr[a->rs1]); >> tcg_gen_andi_i32(ofs, ofs, vlen - 1); >> >> /* Convert the index to an offset. */ >> tcg_gen_shli_i32(ofs, ofs, s->sew); > > In big endianess host, should I convert the index first before this > statement. > > #ifdef HOST_WORDS_BIGENDIAN > static void convert_idx(TCGv_i32 idx, int sew) > { > switch (sew) { > case MO_8: > tcg_gen_xori_i32(idx, idx, 7); > break; > case MO_16: > tcg_gen_xori_i32(idx, idx, 3); > break; > case MO_32: > tcg_gen_xori_i32(idx, idx, 1); > break; > default: > break; > } > } > #endif > > > When convert the index to an offset, use this function first > > #ifdef HOST_WORDS_BIGENDIAN > convert_idx(ofs, s->sew) > #endif
Yes, I forgot about endian adjust. I would say static void endian_adjust(TCGv_i32 ofs, int sew) { #ifdef HOST_WORDS_BIGENDIAN tcg_gen_xori_i32(ofs, ofs, 7 >> sew); #endif } so that you don't need the ifdef at the use site. r~