在 2023/3/21 下午11:55, Richard Henderson 写道:
On 3/21/23 04:31, gaosong wrote:
but for this case.
e.g
vreplve_b vd vj, rk
index = gpr[rk] % (128/8);
Vd->B(i) = Vj->B(index);
tcg_gen_gvec_dup_mem(MO_8, vreg_full_offset(a->vd), offsetof(CPULoongArchState,
fpr[a->vj].vreg.B(index))), 16, 16 );
How can we get the index with cpu_env? or need env->gpr[rk]?
The index type is not TCGv.
For this case you would load the value Vj->B(index) into a TCGv_i32,
tcg_gen_andi_i64(t0, gpr_src(rk), 15);
// Handle endian adjustment on t0, e.g. xor 15 for big-endian?
tcg_gen_trunc_i64_ptr(t1, t0);
tcg_gen_add_ptr(t1, t1, cpu_env);
tcg_gen_ld8u_i32(t2, t1, vreg_full_offset(vj));
// At this point t2 contains Vj->B(index)
tcg_gen_gvec_dup_i32(MO_8, vreg_full_offset(vd), 16, 16, t2);
It's weird. this is no problem for vreplve_b, but for vreplve_h/w/d is not
correct.
e.g vreplve h
index = gpr[rk] % 8
Vd->H(i) = Vj->H(index);
like this:
{
tcg_gen_andi_i64(t0, gpr_src(ctx, a->rk, EXT_NONE), 7);
if (HOST_BIG_ENDIAN) {
tcg_gen_xori_i64(t0, t0, 7);
}
tcg_gen_trunc_i64_ptr(t1, t0);
tcg_gen_add_ptr(t1, t1, cpu_env);
tcg_gen_ld16u_i32(t2, t1, vreg_full_offset(a->vj));
tcg_gen_gvec_dup_i32(MO_16, vreg_full_offset(a->vd), 16, 16, t2);
}
vreplve.h vr25, vr31, r30
r30 : 000000007aab5617
v31 : {efd0efc1efd0efc1, efd0efc1efd0efc1}
result: {efd0efd0efd0efd0, efd0efd0efd0efd0},
and we get result is : {c1efc1efc1efc1ef, c1efc1efc1efc1ef}.
my host is little-endian.