在 2023/9/12 上午6:27, Richard Henderson 写道:
> On 9/7/23 01:31, Song Gao wrote:
>> +static bool trans_xvinsgr2vr_w(DisasContext *ctx, arg_vr_i *a)
>> +{
>> + if (!avail_LASX(ctx)) {
>> + return false;
>> + }
>> + return trans_vinsgr2vr_w(ctx, a);
>> +}
>
> Using the other translator doesn't help.
>
>> static bool trans_vinsgr2vr_w(DisasContext *ctx, arg_vr_i *a)
>> {
>> TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
>>
>> if (!avail_LSX(ctx)) {
>> return false;
>> }
>>
>> CHECK_SXE;
>
> This portion doesn't apply, and you miss the check_vec for the larger LASX.
>
>> tcg_gen_st32_i64(src, cpu_env,
>> offsetof(CPULoongArchState,
>> fpr[a->vd].vreg.W(a->imm)));
>> return true;
>> }
>
> The only thing that is left is this one line, so I'm not sure it's worth
> splitting out a common helper function.
>
> I think we need, like this:
static bool gen_g2v_vl(DisasContext *ctx, arg_vr_i *a, uint32_t oprsz,
MemOp mop,
void (*func)(TCGv, TCGv_ptr, tcg_target_long))
{
TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
if (!check_vec(ctx, oprsz)) {
return true;
}
func(src, cpu_env, vec_reg_offset(a->vd, a->imm, mop));
return true;
}
static bool gen_g2v(DisasContext *ctx, arg_vr_i *a, MemOp mop,
void (*func)(TCGv, TCGv_ptr, tcg_target_long))
{
return gen_g2v_vl(ctx, a, 16, mop, func);
}
static bool gen_g2x(DisasContext *ctx, arg_vr_i *a, MemOp mop,
void (*func)(TCGv, TCGv_ptr, tcg_target_long))
{
return gen_g2v_vl(ctx, a, 32, mop, func);
}
TRANS(vinsgr2vr_b, LSX, gen_g2v, MO_8, tcg_gen_st8_i64)
TRANS(vinsgr2vr_h, LSX, gen_g2v, MO_16, tcg_gen_st16_i64)
TRANS(vinsgr2vr_w, LSX, gen_g2v, MO_32, tcg_gen_st32_i64)
TRANS(vinsgr2vr_d, LSX, gen_g2v, MO_64, tcg_gen_st_i64)
TRANS(xvinsgr2vr_w, LASX, gen_g2x, MO_32, tcg_gen_st32_i64)
TRANS(xvinsgr2vr_d, LASX, gen_g2x, MO_64, tcg_gen_st_i64)
Thanks.
Song Gao