On 4/30/20 11:09 AM, Peter Maydell wrote:
> +
> +    rn = tcg_temp_new_i64();
> +    rm = tcg_temp_new_i64();
> +    rd = tcg_temp_new_i64();
> +
> +    for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
> +        neon_load_reg64(rn, a->vn + pass);
> +        neon_load_reg64(rm, a->vm + pass);
> +        fn(rd, rm, rn);
> +        neon_store_reg64(rd, a->vd + pass);
> +    }
> +
> +    tcg_temp_free_i64(rn);
> +    tcg_temp_free_i64(rm);
> +    tcg_temp_free_i64(rd);
> +
> +    return true;
> +}
> +
> +#define DO_3SAME_64(INSN, FUNC)                                         \
> +    static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a)        \
> +    {                                                                   \
> +        return do_3same_64(s, a, FUNC);                                 \
> +    }

You can morph this into the gvec interface like so:

#define DO_3SAME_64(INSN, FUNC) \
    static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs,
                                uint32_t rn_ofs, uint32_t rm_ofs,
                                uint32_t oprsz, uint32_t maxsz)
    {
        static const GVecGen3 op = { .fni8 = FUNC };
        tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
                       oprsz, maxsz, &op);
    }
    DO_3SAME(INSN, gen_##INSN##_3s)

The .fni8 function tells gvec that we have a helper that processes the
operation in 8 byte chunks.  It will handle the pass loop for you.

There's also a .fni4 member, for those neon helpers that operate on 4-byte
quantities, fwiw.


r~

Reply via email to