mirror of https://github.com/xemu-project/xemu.git
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. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20200513163245.17915-10-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
e9eee5316f
commit
8161b75357
|
@ -577,15 +577,6 @@ static void gen_gvec_fn4(DisasContext *s, bool is_q, int rd, int rn, int 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)
|
||||
{
|
||||
tcg_gen_gvec_3(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)
|
||||
|
@ -11193,8 +11184,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) {
|
||||
|
@ -11233,7 +11227,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 */
|
||||
|
|
|
@ -603,6 +603,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) \
|
||||
|
@ -634,6 +636,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(unsigned vece, uint32_t rd_ofs, \
|
||||
|
@ -650,13 +653,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(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, &cmtst_op[vece]);
|
||||
}
|
||||
DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
|
||||
|
||||
#define DO_3SAME_GVEC4(INSN, OPARRAY) \
|
||||
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
|
||||
uint32_t rn_ofs, uint32_t rm_ofs, \
|
||||
|
@ -686,16 +682,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(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(INSN, gen_##INSN##_3s)
|
||||
|
||||
DO_3SAME_GVEC3_SHIFT(VSHL_S, sshl_op)
|
||||
DO_3SAME_GVEC3_SHIFT(VSHL_U, ushl_op)
|
||||
|
|
|
@ -4606,27 +4606,31 @@ static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
|
|||
tcg_gen_cmp_vec(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,
|
||||
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
|
||||
.opt_opc = vecop_list_cmtst,
|
||||
.vece = MO_64 },
|
||||
};
|
||||
void gen_gvec_cmtst(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(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
|
||||
}
|
||||
|
||||
void gen_ushl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
|
||||
{
|
||||
|
@ -4744,29 +4748,33 @@ static void gen_ushl_vec(unsigned vece, TCGv_vec dst,
|
|||
tcg_temp_free_vec(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(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(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
|
||||
}
|
||||
|
||||
void gen_sshl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
|
||||
{
|
||||
|
@ -4878,29 +4886,33 @@ static void gen_sshl_vec(unsigned vece, TCGv_vec dst,
|
|||
tcg_temp_free_vec(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(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(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
|
||||
}
|
||||
|
||||
static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
|
||||
TCGv_vec a, TCGv_vec b)
|
||||
|
|
|
@ -291,9 +291,13 @@ void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
|
|||
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];
|
||||
void gen_gvec_cmtst(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(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(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];
|
||||
|
|
Loading…
Reference in New Issue