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); /* Convert the index to a pointer. */ tcg_gen_extu_i32_ptr(base, ofs); tcg_gen_add_ptr(base, base, cpu_env); /* Perform the load. */ do_extract(dest, base, vreg_ofs(s, a->rs2), s->sew); tcg_temp_free_ptr(base); tcg_temp_free_i32(ofs); /* Flush out-of-range indexing to zero. */ t_vlen = tcg_const_tl(vlen); t_zero = tcg_const_tl(0); tcg_gen_movcond_tl(TCG_COND_LTU, dest, cpu_gpr[a->rs1], t_vlen, dest, t_zero); tcg_temp_free(t_vlen); tcg_temp_free(t_zero); } r~