mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
target/arm: Create gen_gvec_{mla,mls}
Provide a functional interface for the vector expansion. This fits better with the existing set of helpers that we provide for other operations. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20200513163245.17915-8-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
69d5e2bf8c
commit
271063206a
4 changed files with 71 additions and 73 deletions
|
@ -11226,9 +11226,9 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
|
|||
return;
|
||||
case 0x12: /* MLA, MLS */
|
||||
if (u) {
|
||||
gen_gvec_op3(s, is_q, rd, rn, rm, &mls_op[size]);
|
||||
gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_mls, size);
|
||||
} else {
|
||||
gen_gvec_op3(s, is_q, rd, rn, rm, &mla_op[size]);
|
||||
gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_mla, size);
|
||||
}
|
||||
return;
|
||||
case 0x11:
|
||||
|
|
|
@ -632,6 +632,8 @@ DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
|
|||
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
|
||||
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
|
||||
DO_3SAME_NO_SZ_3(VMUL, tcg_gen_gvec_mul)
|
||||
DO_3SAME_NO_SZ_3(VMLA, gen_gvec_mla)
|
||||
DO_3SAME_NO_SZ_3(VMLS, gen_gvec_mls)
|
||||
|
||||
#define DO_3SAME_CMP(INSN, COND) \
|
||||
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
|
||||
|
@ -685,20 +687,6 @@ static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
|
|||
return do_3same(s, a, gen_VMUL_p_3s);
|
||||
}
|
||||
|
||||
#define DO_3SAME_GVEC3_NO_SZ_3(INSN, OPARRAY) \
|
||||
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) \
|
||||
{ \
|
||||
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, \
|
||||
oprsz, maxsz, &OPARRAY[vece]); \
|
||||
} \
|
||||
DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
|
||||
|
||||
|
||||
DO_3SAME_GVEC3_NO_SZ_3(VMLA, mla_op)
|
||||
DO_3SAME_GVEC3_NO_SZ_3(VMLS, mls_op)
|
||||
|
||||
#define DO_3SAME_GVEC3_SHIFT(INSN, OPARRAY) \
|
||||
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
|
||||
uint32_t rn_ofs, uint32_t rm_ofs, \
|
||||
|
|
|
@ -4520,62 +4520,69 @@ static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
|
|||
/* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
|
||||
* these tables are shared with AArch64 which does support them.
|
||||
*/
|
||||
void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
|
||||
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
|
||||
{
|
||||
static const TCGOpcode vecop_list[] = {
|
||||
INDEX_op_mul_vec, INDEX_op_add_vec, 0
|
||||
};
|
||||
static const GVecGen3 ops[4] = {
|
||||
{ .fni4 = gen_mla8_i32,
|
||||
.fniv = gen_mla_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_8 },
|
||||
{ .fni4 = gen_mla16_i32,
|
||||
.fniv = gen_mla_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_16 },
|
||||
{ .fni4 = gen_mla32_i32,
|
||||
.fniv = gen_mla_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_32 },
|
||||
{ .fni8 = gen_mla64_i64,
|
||||
.fniv = gen_mla_vec,
|
||||
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_64 },
|
||||
};
|
||||
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
|
||||
}
|
||||
|
||||
static const TCGOpcode vecop_list_mla[] = {
|
||||
INDEX_op_mul_vec, INDEX_op_add_vec, 0
|
||||
};
|
||||
|
||||
static const TCGOpcode vecop_list_mls[] = {
|
||||
INDEX_op_mul_vec, INDEX_op_sub_vec, 0
|
||||
};
|
||||
|
||||
const GVecGen3 mla_op[4] = {
|
||||
{ .fni4 = gen_mla8_i32,
|
||||
.fniv = gen_mla_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list_mla,
|
||||
.vece = MO_8 },
|
||||
{ .fni4 = gen_mla16_i32,
|
||||
.fniv = gen_mla_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list_mla,
|
||||
.vece = MO_16 },
|
||||
{ .fni4 = gen_mla32_i32,
|
||||
.fniv = gen_mla_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list_mla,
|
||||
.vece = MO_32 },
|
||||
{ .fni8 = gen_mla64_i64,
|
||||
.fniv = gen_mla_vec,
|
||||
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list_mla,
|
||||
.vece = MO_64 },
|
||||
};
|
||||
|
||||
const GVecGen3 mls_op[4] = {
|
||||
{ .fni4 = gen_mls8_i32,
|
||||
.fniv = gen_mls_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list_mls,
|
||||
.vece = MO_8 },
|
||||
{ .fni4 = gen_mls16_i32,
|
||||
.fniv = gen_mls_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list_mls,
|
||||
.vece = MO_16 },
|
||||
{ .fni4 = gen_mls32_i32,
|
||||
.fniv = gen_mls_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list_mls,
|
||||
.vece = MO_32 },
|
||||
{ .fni8 = gen_mls64_i64,
|
||||
.fniv = gen_mls_vec,
|
||||
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list_mls,
|
||||
.vece = MO_64 },
|
||||
};
|
||||
void gen_gvec_mls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
|
||||
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
|
||||
{
|
||||
static const TCGOpcode vecop_list[] = {
|
||||
INDEX_op_mul_vec, INDEX_op_sub_vec, 0
|
||||
};
|
||||
static const GVecGen3 ops[4] = {
|
||||
{ .fni4 = gen_mls8_i32,
|
||||
.fniv = gen_mls_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_8 },
|
||||
{ .fni4 = gen_mls16_i32,
|
||||
.fniv = gen_mls_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_16 },
|
||||
{ .fni4 = gen_mls32_i32,
|
||||
.fniv = gen_mls_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_32 },
|
||||
{ .fni8 = gen_mls64_i64,
|
||||
.fniv = gen_mls_vec,
|
||||
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_64 },
|
||||
};
|
||||
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
|
||||
}
|
||||
|
||||
/* CMTST : test is "if (X & Y != 0)". */
|
||||
static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
|
||||
|
|
|
@ -286,8 +286,11 @@ void gen_gvec_cle0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
|
|||
void gen_gvec_cge0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
|
||||
uint32_t opr_sz, uint32_t max_sz);
|
||||
|
||||
extern const GVecGen3 mla_op[4];
|
||||
extern const GVecGen3 mls_op[4];
|
||||
void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
|
||||
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
|
||||
void gen_gvec_mls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
|
||||
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
|
||||
|
||||
extern const GVecGen3 cmtst_op[4];
|
||||
extern const GVecGen3 sshl_op[4];
|
||||
extern const GVecGen3 ushl_op[4];
|
||||
|
|
Loading…
Reference in a new issue