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.

Backports commit 271063206a46062a45fc6bab8dabe45f0b88159d from qemu
This commit is contained in:
Richard Henderson 2020-05-15 21:04:50 -04:00 committed by Lioncash
parent 340f97bf4c
commit 546db9089c
9 changed files with 83 additions and 85 deletions

View file

@ -3423,6 +3423,8 @@
#define gen_gvec_cgt0 gen_gvec_cgt0_aarch64
#define gen_gvec_cle0 gen_gvec_cle0_aarch64
#define gen_gvec_clt0 gen_gvec_clt0_aarch64
#define gen_gvec_mla gen_gvec_mla_aarch64
#define gen_gvec_mls gen_gvec_mls_aarch64
#define gen_gvec_sli gen_gvec_sli_aarch64
#define gen_gvec_ssra gen_gvec_ssra_aarch64
#define gen_gvec_sri gen_gvec_sri_aarch64
@ -4452,8 +4454,6 @@
#define helper_xpacd helper_xpacd_aarch64
#define helper_xpaci helper_xpaci_aarch64
#define logic_imm_decode_wmask logic_imm_decode_wmask_aarch64
#define mla_op mla_op_aarch64
#define mls_op mls_op_aarch64
#define new_tmp_a64 new_tmp_a64_aarch64
#define new_tmp_a64_zero new_tmp_a64_zero_aarch64
#define pmsav8_mpu_lookup pmsav8_mpu_lookup_aarch64

View file

@ -3423,6 +3423,8 @@
#define gen_gvec_cgt0 gen_gvec_cgt0_aarch64eb
#define gen_gvec_cle0 gen_gvec_cle0_aarch64eb
#define gen_gvec_clt0 gen_gvec_clt0_aarch64eb
#define gen_gvec_mla gen_gvec_mla_aarch64eb
#define gen_gvec_mls gen_gvec_mls_aarch64eb
#define gen_gvec_sli gen_gvec_sli_aarch64eb
#define gen_gvec_ssra gen_gvec_ssra_aarch64eb
#define gen_gvec_sri gen_gvec_sri_aarch64eb
@ -4452,8 +4454,6 @@
#define helper_xpacd helper_xpacd_aarch64eb
#define helper_xpaci helper_xpaci_aarch64eb
#define logic_imm_decode_wmask logic_imm_decode_wmask_aarch64eb
#define mla_op mla_op_aarch64eb
#define mls_op mls_op_aarch64eb
#define new_tmp_a64 new_tmp_a64_aarch64eb
#define new_tmp_a64_zero new_tmp_a64_zero_aarch64eb
#define pmsav8_mpu_lookup pmsav8_mpu_lookup_aarch64eb

View file

@ -3408,6 +3408,8 @@
#define gen_gvec_cgt0 gen_gvec_cgt0_arm
#define gen_gvec_cle0 gen_gvec_cle0_arm
#define gen_gvec_clt0 gen_gvec_clt0_arm
#define gen_gvec_mla gen_gvec_mla_arm
#define gen_gvec_mls gen_gvec_mls_arm
#define gen_gvec_sli gen_gvec_sli_arm
#define gen_gvec_ssra gen_gvec_ssra_arm
#define gen_gvec_sri gen_gvec_sri_arm
@ -3456,8 +3458,6 @@
#define helper_gvec_usra_s helper_gvec_usra_s_arm
#define helper_vjcvt helper_vjcvt_arm
#define pmu_init pmu_init_arm
#define mla_op mla_op_arm
#define mls_op mls_op_arm
#define pmsav8_mpu_lookup pmsav8_mpu_lookup_arm
#define pmu_op_start pmu_op_start_arm
#define pmu_op_finish pmu_op_finish_arm

View file

@ -3408,6 +3408,8 @@
#define gen_gvec_cgt0 gen_gvec_cgt0_armeb
#define gen_gvec_cle0 gen_gvec_cle0_armeb
#define gen_gvec_clt0 gen_gvec_clt0_armeb
#define gen_gvec_mla gen_gvec_mla_armeb
#define gen_gvec_mls gen_gvec_mls_armeb
#define gen_gvec_sli gen_gvec_sli_armeb
#define gen_gvec_ssra gen_gvec_ssra_armeb
#define gen_gvec_sri gen_gvec_sri_armeb
@ -3456,8 +3458,6 @@
#define helper_gvec_usra_s helper_gvec_usra_s_armeb
#define helper_vjcvt helper_vjcvt_armeb
#define pmu_init pmu_init_armeb
#define mla_op mla_op_armeb
#define mls_op mls_op_armeb
#define pmsav8_mpu_lookup pmsav8_mpu_lookup_armeb
#define pmu_op_start pmu_op_start_armeb
#define pmu_op_finish pmu_op_finish_armeb

View file

@ -3417,6 +3417,8 @@ arm_symbols = (
'gen_gvec_cgt0',
'gen_gvec_cle0',
'gen_gvec_clt0',
'gen_gvec_mla',
'gen_gvec_mls',
'gen_gvec_sli',
'gen_gvec_ssra',
'gen_gvec_sri',
@ -3465,8 +3467,6 @@ arm_symbols = (
'helper_gvec_usra_s',
'helper_vjcvt',
'pmu_init',
'mla_op',
'mls_op',
'pmsav8_mpu_lookup',
'pmu_op_start',
'pmu_op_finish',
@ -3530,6 +3530,8 @@ aarch64_symbols = (
'gen_gvec_cgt0',
'gen_gvec_cle0',
'gen_gvec_clt0',
'gen_gvec_mla',
'gen_gvec_mls',
'gen_gvec_sli',
'gen_gvec_ssra',
'gen_gvec_sri',
@ -4559,8 +4561,6 @@ aarch64_symbols = (
'helper_xpacd',
'helper_xpaci',
'logic_imm_decode_wmask',
'mla_op',
'mls_op',
'new_tmp_a64',
'new_tmp_a64_zero',
'pmsav8_mpu_lookup',

View file

@ -11520,9 +11520,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:

View file

@ -645,6 +645,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(TCGContext *s, unsigned vece, uint32_t rd_ofs, \
@ -698,20 +700,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(TCGContext *s, unsigned vece, uint32_t rd_ofs, \
uint32_t rn_ofs, uint32_t rm_ofs, \
uint32_t oprsz, uint32_t maxsz) \
{ \
tcg_gen_gvec_3(s, 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(TCGContext *s, unsigned vece, uint32_t rd_ofs, \
uint32_t rn_ofs, uint32_t rm_ofs, \

View file

@ -4648,62 +4648,69 @@ static void gen_mls_vec(TCGContext *s, unsigned vece, TCGv_vec d, TCGv_vec a, TC
/* 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(TCGContext *s, 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(s, 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,
.opt_opc = vecop_list_mla,
.load_dest = true,
.vece = MO_8 },
{ .fni4 = gen_mla16_i32,
.fniv = gen_mla_vec,
.opt_opc = vecop_list_mla,
.load_dest = true,
.vece = MO_16 },
{ .fni4 = gen_mla32_i32,
.fniv = gen_mla_vec,
.opt_opc = vecop_list_mla,
.load_dest = true,
.vece = MO_32 },
{ .fni8 = gen_mla64_i64,
.fniv = gen_mla_vec,
.opt_opc = vecop_list_mla,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
.load_dest = true,
.vece = MO_64 },
};
const GVecGen3 mls_op[4] = {
{ .fni4 = gen_mls8_i32,
.fniv = gen_mls_vec,
.opt_opc = vecop_list_mls,
.load_dest = true,
.vece = MO_8 },
{ .fni4 = gen_mls16_i32,
.fniv = gen_mls_vec,
.opt_opc = vecop_list_mls,
.load_dest = true,
.vece = MO_16 },
{ .fni4 = gen_mls32_i32,
.fniv = gen_mls_vec,
.opt_opc = vecop_list_mls,
.load_dest = true,
.vece = MO_32 },
{ .fni8 = gen_mls64_i64,
.fniv = gen_mls_vec,
.opt_opc = vecop_list_mls,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
.load_dest = true,
.vece = MO_64 },
};
void gen_gvec_mls(TCGContext *s, 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(s, rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
}
/* CMTST : test is "if (X & Y != 0)". */
static void gen_cmtst_i32(TCGContext *s, TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)

View file

@ -293,8 +293,11 @@ void gen_gvec_cle0(TCGContext *s, unsigned vece, uint32_t rd_ofs, uint32_t rm_of
void gen_gvec_cge0(TCGContext *s, 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(TCGContext *s, 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(TCGContext *s, 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];