target/arm: Create gen_gvec_{cmtst,ushl,sshl}

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 8161b75357095fef54c76b1a6ed1e54d0e8655e0 from qemu
This commit is contained in:
Richard Henderson 2020-05-15 21:14:12 -04:00 committed by Lioncash
parent 15b2850f4d
commit 4abfe5156d
9 changed files with 113 additions and 117 deletions

View file

@ -3410,7 +3410,6 @@
#define bif_op bif_op_aarch64
#define bit_op bit_op_aarch64
#define bsl_op bsl_op_aarch64
#define cmtst_op cmtst_op_aarch64
#define cpu_mmu_index cpu_mmu_index_aarch64
#define cpu_reg cpu_reg_aarch64
#define cpu_reg_sp cpu_reg_sp_aarch64
@ -3423,15 +3422,18 @@
#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_cmtst gen_gvec_cmtst_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_sshl gen_gvec_sshl_aarch64
#define gen_gvec_ssra gen_gvec_ssra_aarch64
#define gen_gvec_sri gen_gvec_sri_aarch64
#define gen_gvec_srshr gen_gvec_srshr_aarch64
#define gen_gvec_srsra gen_gvec_srsra_aarch64
#define gen_gvec_ursra gen_gvec_ursra_aarch64
#define gen_gvec_urshr gen_gvec_urshr_aarch64
#define gen_gvec_ushl gen_gvec_ushl_aarch64
#define gen_gvec_usra gen_gvec_usra_aarch64
#define get_phys_addr get_phys_addr_aarch64
#define gen_sshl_i32 gen_sshl_i32_aarch64

View file

@ -3410,7 +3410,6 @@
#define bif_op bif_op_aarch64eb
#define bit_op bit_op_aarch64eb
#define bsl_op bsl_op_aarch64eb
#define cmtst_op cmtst_op_aarch64eb
#define cpu_mmu_index cpu_mmu_index_aarch64eb
#define cpu_reg cpu_reg_aarch64eb
#define cpu_reg_sp cpu_reg_sp_aarch64eb
@ -3423,15 +3422,18 @@
#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_cmtst gen_gvec_cmtst_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_sshl gen_gvec_sshl_aarch64eb
#define gen_gvec_ssra gen_gvec_ssra_aarch64eb
#define gen_gvec_sri gen_gvec_sri_aarch64eb
#define gen_gvec_srshr gen_gvec_srshr_aarch64eb
#define gen_gvec_srsra gen_gvec_srsra_aarch64eb
#define gen_gvec_ursra gen_gvec_ursra_aarch64eb
#define gen_gvec_urshr gen_gvec_urshr_aarch64eb
#define gen_gvec_ushl gen_gvec_ushl_aarch64eb
#define gen_gvec_usra gen_gvec_usra_aarch64eb
#define get_phys_addr get_phys_addr_aarch64eb
#define gen_sshl_i32 gen_sshl_i32_aarch64eb

View file

@ -3399,7 +3399,6 @@
#define arm_set_cpu_off arm_set_cpu_off_arm
#define arm_set_cpu_on arm_set_cpu_on_arm
#define arm_stage1_mmu_idx arm_stage1_mmu_idx_arm
#define cmtst_op cmtst_op_arm
#define cpu_mmu_index cpu_mmu_index_arm
#define fp_exception_el fp_exception_el_arm
#define gen_cmtst_i64 gen_cmtst_i64_arm
@ -3408,15 +3407,18 @@
#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_cmtst gen_gvec_cmtst_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_sshl gen_gvec_sshl_arm
#define gen_gvec_ssra gen_gvec_ssra_arm
#define gen_gvec_sri gen_gvec_sri_arm
#define gen_gvec_srshr gen_gvec_srshr_arm
#define gen_gvec_srsra gen_gvec_srsra_arm
#define gen_gvec_ursra gen_gvec_ursra_arm
#define gen_gvec_urshr gen_gvec_urshr_arm
#define gen_gvec_ushl gen_gvec_ushl_arm
#define gen_gvec_usra gen_gvec_usra_arm
#define get_phys_addr get_phys_addr_arm
#define gen_sshl_i32 gen_sshl_i32_arm
@ -3467,12 +3469,10 @@
#define raise_exception_ra raise_exception_ra_arm
#define sqadd_op sqadd_op_arm
#define sqsub_op sqsub_op_arm
#define sshl_op sshl_op_arm
#define sve_exception_el sve_exception_el_arm
#define sve_zcr_len_for_el sve_zcr_len_for_el_arm
#define uqadd_op uqadd_op_arm
#define uqsub_op uqsub_op_arm
#define ushl_op ushl_op_arm
#define v8m_security_lookup v8m_security_lookup_arm
#define vfp_expand_imm vfp_expand_imm_arm
#endif

View file

@ -3399,7 +3399,6 @@
#define arm_set_cpu_off arm_set_cpu_off_armeb
#define arm_set_cpu_on arm_set_cpu_on_armeb
#define arm_stage1_mmu_idx arm_stage1_mmu_idx_armeb
#define cmtst_op cmtst_op_armeb
#define cpu_mmu_index cpu_mmu_index_armeb
#define fp_exception_el fp_exception_el_armeb
#define gen_cmtst_i64 gen_cmtst_i64_armeb
@ -3408,15 +3407,18 @@
#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_cmtst gen_gvec_cmtst_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_sshl gen_gvec_sshl_armeb
#define gen_gvec_ssra gen_gvec_ssra_armeb
#define gen_gvec_sri gen_gvec_sri_armeb
#define gen_gvec_srshr gen_gvec_srshr_armeb
#define gen_gvec_srsra gen_gvec_srsra_armeb
#define gen_gvec_ursra gen_gvec_ursra_armeb
#define gen_gvec_urshr gen_gvec_urshr_armeb
#define gen_gvec_ushl gen_gvec_ushl_armeb
#define gen_gvec_usra gen_gvec_usra_armeb
#define get_phys_addr get_phys_addr_armeb
#define gen_sshl_i32 gen_sshl_i32_armeb
@ -3467,12 +3469,10 @@
#define raise_exception_ra raise_exception_ra_armeb
#define sqadd_op sqadd_op_armeb
#define sqsub_op sqsub_op_armeb
#define sshl_op sshl_op_armeb
#define sve_exception_el sve_exception_el_armeb
#define sve_zcr_len_for_el sve_zcr_len_for_el_armeb
#define uqadd_op uqadd_op_armeb
#define uqsub_op uqsub_op_armeb
#define ushl_op ushl_op_armeb
#define v8m_security_lookup v8m_security_lookup_armeb
#define vfp_expand_imm vfp_expand_imm_armeb
#endif

View file

@ -3408,7 +3408,6 @@ arm_symbols = (
'arm_set_cpu_off',
'arm_set_cpu_on',
'arm_stage1_mmu_idx',
'cmtst_op',
'cpu_mmu_index',
'fp_exception_el',
'gen_cmtst_i64',
@ -3417,15 +3416,18 @@ arm_symbols = (
'gen_gvec_cgt0',
'gen_gvec_cle0',
'gen_gvec_clt0',
'gen_gvec_cmtst',
'gen_gvec_mla',
'gen_gvec_mls',
'gen_gvec_sli',
'gen_gvec_sshl',
'gen_gvec_ssra',
'gen_gvec_sri',
'gen_gvec_srshr',
'gen_gvec_srsra',
'gen_gvec_ursra',
'gen_gvec_urshr',
'gen_gvec_ushl',
'gen_gvec_usra',
'get_phys_addr',
'gen_sshl_i32',
@ -3476,12 +3478,10 @@ arm_symbols = (
'raise_exception_ra',
'sqadd_op',
'sqsub_op',
'sshl_op',
'sve_exception_el',
'sve_zcr_len_for_el',
'uqadd_op',
'uqsub_op',
'ushl_op',
'v8m_security_lookup',
'vfp_expand_imm',
)
@ -3517,7 +3517,6 @@ aarch64_symbols = (
'bif_op',
'bit_op',
'bsl_op',
'cmtst_op',
'cpu_mmu_index',
'cpu_reg',
'cpu_reg_sp',
@ -3530,15 +3529,18 @@ aarch64_symbols = (
'gen_gvec_cgt0',
'gen_gvec_cle0',
'gen_gvec_clt0',
'gen_gvec_cmtst',
'gen_gvec_mla',
'gen_gvec_mls',
'gen_gvec_sli',
'gen_gvec_sshl',
'gen_gvec_ssra',
'gen_gvec_sri',
'gen_gvec_srshr',
'gen_gvec_srsra',
'gen_gvec_ursra',
'gen_gvec_urshr',
'gen_gvec_ushl',
'gen_gvec_usra',
'get_phys_addr',
'gen_sshl_i32',

View file

@ -741,17 +741,6 @@ static void gen_gvec_fn3(DisasContext *s, bool is_q, int rd, int rn, int rm,
vec_full_reg_offset(s, rm), is_q ? 16 : 8, vec_full_reg_size(s));
}
/* Expand a 3-operand AdvSIMD vector operation using an op descriptor. */
static void gen_gvec_op3(DisasContext *s, bool is_q, int rd,
int rn, int rm, const GVecGen3 *gvec_op)
{
TCGContext *tcg_ctx = s->uc->tcg_ctx;
tcg_gen_gvec_3(tcg_ctx, vec_full_reg_offset(s, rd), vec_full_reg_offset(s, rn),
vec_full_reg_offset(s, rm), is_q ? 16 : 8,
vec_full_reg_size(s), gvec_op);
}
/* Expand a 3-operand operation using an out-of-line helper. */
static void gen_gvec_op3_ool(DisasContext *s, bool is_q, int rd,
int rn, int rm, int data, gen_helper_gvec_3 *fn)
@ -11487,8 +11476,11 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
(u ? uqsub_op : sqsub_op) + size);
return;
case 0x08: /* SSHL, USHL */
gen_gvec_op3(s, is_q, rd, rn, rm,
u ? &ushl_op[size] : &sshl_op[size]);
if (u) {
gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_ushl, size);
} else {
gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sshl, size);
}
return;
case 0x0c: /* SMAX, UMAX */
if (u) {
@ -11527,7 +11519,7 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
return;
case 0x11:
if (!u) { /* CMTST */
gen_gvec_op3(s, is_q, rd, rn, rm, &cmtst_op[size]);
gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_cmtst, size);
return;
}
/* else CMEQ */

View file

@ -616,6 +616,8 @@ DO_3SAME(VBIC, tcg_gen_gvec_andc)
DO_3SAME(VORR, tcg_gen_gvec_or)
DO_3SAME(VORN, tcg_gen_gvec_orc)
DO_3SAME(VEOR, tcg_gen_gvec_xor)
DO_3SAME(VSHL_S, gen_gvec_sshl)
DO_3SAME(VSHL_U, gen_gvec_ushl)
/* These insns are all gvec_bitsel but with the inputs in various orders. */
#define DO_3SAME_BITSEL(INSN, O1, O2, O3) \
@ -647,6 +649,7 @@ 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)
DO_3SAME_NO_SZ_3(VTST, gen_gvec_cmtst)
#define DO_3SAME_CMP(INSN, COND) \
static void gen_##INSN##_3s(TCGContext *s, unsigned vece, uint32_t rd_ofs, \
@ -663,13 +666,6 @@ DO_3SAME_CMP(VCGE_S, TCG_COND_GE)
DO_3SAME_CMP(VCGE_U, TCG_COND_GEU)
DO_3SAME_CMP(VCEQ, TCG_COND_EQ)
static void gen_VTST_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, &cmtst_op[vece]);
}
DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
#define DO_3SAME_GVEC4(INSN, OPARRAY) \
static void gen_##INSN##_3s(TCGContext *s, unsigned vece, uint32_t rd_ofs, \
uint32_t rn_ofs, uint32_t rm_ofs, \
@ -699,17 +695,3 @@ static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
}
return do_3same(s, a, gen_VMUL_p_3s);
}
#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, \
uint32_t oprsz, uint32_t maxsz) \
{ \
/* Note the operation is vshl vd,vm,vn */ \
tcg_gen_gvec_3(s, rd_ofs, rn_ofs, rm_ofs, \
oprsz, maxsz, &OPARRAY[vece]); \
} \
DO_3SAME(INSN, gen_##INSN##_3s)
DO_3SAME_GVEC3_SHIFT(VSHL_S, sshl_op)
DO_3SAME_GVEC3_SHIFT(VSHL_U, ushl_op)

View file

@ -4734,27 +4734,31 @@ static void gen_cmtst_vec(TCGContext *s, unsigned vece, TCGv_vec d, TCGv_vec a,
tcg_gen_cmp_vec(s, TCG_COND_NE, vece, d, d, a);
}
static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
const GVecGen3 cmtst_op[4] = {
{ .fni4 = gen_helper_neon_tst_u8,
.fniv = gen_cmtst_vec,
.opt_opc = vecop_list_cmtst,
.vece = MO_8 },
{ .fni4 = gen_helper_neon_tst_u16,
.fniv = gen_cmtst_vec,
.opt_opc = vecop_list_cmtst,
.vece = MO_16 },
{ .fni4 = gen_cmtst_i32,
.fniv = gen_cmtst_vec,
.opt_opc = vecop_list_cmtst,
.vece = MO_32 },
{ .fni8 = gen_cmtst_i64,
.fniv = gen_cmtst_vec,
.opt_opc = vecop_list_cmtst,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
.vece = MO_64 },
};
void gen_gvec_cmtst(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_cmp_vec, 0 };
static const GVecGen3 ops[4] = {
{ .fni4 = gen_helper_neon_tst_u8,
.fniv = gen_cmtst_vec,
.opt_opc = vecop_list,
.vece = MO_8 },
{ .fni4 = gen_helper_neon_tst_u16,
.fniv = gen_cmtst_vec,
.opt_opc = vecop_list,
.vece = MO_16 },
{ .fni4 = gen_cmtst_i32,
.fniv = gen_cmtst_vec,
.opt_opc = vecop_list,
.vece = MO_32 },
{ .fni8 = gen_cmtst_i64,
.fniv = gen_cmtst_vec,
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
.opt_opc = vecop_list,
.vece = MO_64 },
};
tcg_gen_gvec_3(s, rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
}
void gen_ushl_i32(TCGContext *tcg_ctx, TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
{
@ -4872,29 +4876,33 @@ static void gen_ushl_vec(TCGContext *tcg_ctx, unsigned vece, TCGv_vec dst,
tcg_temp_free_vec(tcg_ctx, rsh);
}
static const TCGOpcode ushl_list[] = {
INDEX_op_neg_vec, INDEX_op_shlv_vec,
INDEX_op_shrv_vec, INDEX_op_cmp_vec, 0
};
const GVecGen3 ushl_op[4] = {
{ .fniv = gen_ushl_vec,
.fno = gen_helper_gvec_ushl_b,
.opt_opc = ushl_list,
.vece = MO_8 },
{ .fniv = gen_ushl_vec,
.fno = gen_helper_gvec_ushl_h,
.opt_opc = ushl_list,
.vece = MO_16 },
{ .fni4 = gen_ushl_i32,
.fniv = gen_ushl_vec,
.opt_opc = ushl_list,
.vece = MO_32 },
{ .fni8 = gen_ushl_i64,
.fniv = gen_ushl_vec,
.opt_opc = ushl_list,
.vece = MO_64 },
};
void gen_gvec_ushl(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_neg_vec, INDEX_op_shlv_vec,
INDEX_op_shrv_vec, INDEX_op_cmp_vec, 0
};
static const GVecGen3 ops[4] = {
{ .fniv = gen_ushl_vec,
.fno = gen_helper_gvec_ushl_b,
.opt_opc = vecop_list,
.vece = MO_8 },
{ .fniv = gen_ushl_vec,
.fno = gen_helper_gvec_ushl_h,
.opt_opc = vecop_list,
.vece = MO_16 },
{ .fni4 = gen_ushl_i32,
.fniv = gen_ushl_vec,
.opt_opc = vecop_list,
.vece = MO_32 },
{ .fni8 = gen_ushl_i64,
.fniv = gen_ushl_vec,
.opt_opc = vecop_list,
.vece = MO_64 },
};
tcg_gen_gvec_3(s, rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
}
void gen_sshl_i32(TCGContext *tcg_ctx, TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
{
@ -5006,29 +5014,33 @@ static void gen_sshl_vec(TCGContext *tcg_ctx, unsigned vece, TCGv_vec dst,
tcg_temp_free_vec(tcg_ctx, tmp);
}
static const TCGOpcode sshl_list[] = {
INDEX_op_neg_vec, INDEX_op_umin_vec, INDEX_op_shlv_vec,
INDEX_op_sarv_vec, INDEX_op_cmp_vec, INDEX_op_cmpsel_vec, 0
};
const GVecGen3 sshl_op[4] = {
{ .fniv = gen_sshl_vec,
.fno = gen_helper_gvec_sshl_b,
.opt_opc = sshl_list,
.vece = MO_8 },
{ .fniv = gen_sshl_vec,
.fno = gen_helper_gvec_sshl_h,
.opt_opc = sshl_list,
.vece = MO_16 },
{ .fni4 = gen_sshl_i32,
.fniv = gen_sshl_vec,
.opt_opc = sshl_list,
.vece = MO_32 },
{ .fni8 = gen_sshl_i64,
.fniv = gen_sshl_vec,
.opt_opc = sshl_list,
.vece = MO_64 },
};
void gen_gvec_sshl(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_neg_vec, INDEX_op_umin_vec, INDEX_op_shlv_vec,
INDEX_op_sarv_vec, INDEX_op_cmp_vec, INDEX_op_cmpsel_vec, 0
};
static const GVecGen3 ops[4] = {
{ .fniv = gen_sshl_vec,
.fno = gen_helper_gvec_sshl_b,
.opt_opc = vecop_list,
.vece = MO_8 },
{ .fniv = gen_sshl_vec,
.fno = gen_helper_gvec_sshl_h,
.opt_opc = vecop_list,
.vece = MO_16 },
{ .fni4 = gen_sshl_i32,
.fniv = gen_sshl_vec,
.opt_opc = vecop_list,
.vece = MO_32 },
{ .fni8 = gen_sshl_i64,
.fniv = gen_sshl_vec,
.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 void gen_uqadd_vec(TCGContext *s, unsigned vece, TCGv_vec t, TCGv_vec sat,
TCGv_vec a, TCGv_vec b)

View file

@ -298,9 +298,13 @@ void gen_gvec_mla(TCGContext *s, unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs
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];
void gen_gvec_cmtst(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_sshl(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_ushl(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 GVecGen4 uqadd_op[4];
extern const GVecGen4 sqadd_op[4];
extern const GVecGen4 uqsub_op[4];