target/arm: Create gen_gvec_{qrdmla,qrdmls}

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 146aa66ce58b686b8037d0eb3921c1125942dbde from qemu
This commit is contained in:
Richard Henderson 2020-05-15 21:42:07 -04:00 committed by Lioncash
parent efdcad70b1
commit 3c4f226e00
8 changed files with 45 additions and 62 deletions

View file

@ -3427,6 +3427,8 @@
#define gen_gvec_mls gen_gvec_mls_aarch64
#define gen_gvec_sli gen_gvec_sli_aarch64
#define gen_gvec_sqadd_qc gen_gvec_sqadd_qc_aarch64
#define gen_gvec_sqrdmlah_qc gen_gvec_sqrdmlah_qc_aarch64
#define gen_gvec_sqrdmlsh_qc gen_gvec_sqrdmlsh_qc_aarch64
#define gen_gvec_sqsub_qc gen_gvec_sqsub_qc_aarch64
#define gen_gvec_sri gen_gvec_sri_aarch64
#define gen_gvec_srshr gen_gvec_srshr_aarch64

View file

@ -3427,6 +3427,8 @@
#define gen_gvec_mls gen_gvec_mls_aarch64eb
#define gen_gvec_sli gen_gvec_sli_aarch64eb
#define gen_gvec_sqadd_qc gen_gvec_sqadd_qc_aarch64eb
#define gen_gvec_sqrdmlah_qc gen_gvec_sqrdmlah_qc_aarch64eb
#define gen_gvec_sqrdmlsh_qc gen_gvec_sqrdmlsh_qc_aarch64eb
#define gen_gvec_sqsub_qc gen_gvec_sqsub_qc_aarch64eb
#define gen_gvec_sri gen_gvec_sri_aarch64eb
#define gen_gvec_srshr gen_gvec_srshr_aarch64eb

View file

@ -3412,6 +3412,8 @@
#define gen_gvec_mls gen_gvec_mls_arm
#define gen_gvec_sli gen_gvec_sli_arm
#define gen_gvec_sqadd_qc gen_gvec_sqadd_qc_arm
#define gen_gvec_sqrdmlah_qc gen_gvec_sqrdmlah_qc_arm
#define gen_gvec_sqrdmlsh_qc gen_gvec_sqrdmlsh_qc_arm
#define gen_gvec_sqsub_qc gen_gvec_sqsub_qc_arm
#define gen_gvec_sri gen_gvec_sri_arm
#define gen_gvec_srshr gen_gvec_srshr_arm

View file

@ -3412,6 +3412,8 @@
#define gen_gvec_mls gen_gvec_mls_armeb
#define gen_gvec_sli gen_gvec_sli_armeb
#define gen_gvec_sqadd_qc gen_gvec_sqadd_qc_armeb
#define gen_gvec_sqrdmlah_qc gen_gvec_sqrdmlah_qc_armeb
#define gen_gvec_sqrdmlsh_qc gen_gvec_sqrdmlsh_qc_armeb
#define gen_gvec_sqsub_qc gen_gvec_sqsub_qc_armeb
#define gen_gvec_sri gen_gvec_sri_armeb
#define gen_gvec_srshr gen_gvec_srshr_armeb

View file

@ -3421,6 +3421,8 @@ arm_symbols = (
'gen_gvec_mls',
'gen_gvec_sli',
'gen_gvec_sqadd_qc',
'gen_gvec_sqrdmlah_qc',
'gen_gvec_sqrdmlsh_qc',
'gen_gvec_sqsub_qc',
'gen_gvec_sri',
'gen_gvec_srshr',
@ -3538,6 +3540,8 @@ aarch64_symbols = (
'gen_gvec_mls',
'gen_gvec_sli',
'gen_gvec_sqadd_qc',
'gen_gvec_sqrdmlah_qc',
'gen_gvec_sqrdmlsh_qc',
'gen_gvec_sqsub_qc',
'gen_gvec_sri',
'gen_gvec_srshr',

View file

@ -753,20 +753,6 @@ static void gen_gvec_op3_ool(DisasContext *s, bool is_q, int rd,
is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
}
/* Expand a 3-operand + env pointer operation using
* an out-of-line helper.
*/
static void gen_gvec_op3_env(DisasContext *s, bool is_q, int rd,
int rn, int rm, gen_helper_gvec_3_ptr *fn)
{
TCGContext *tcg_ctx = s->uc->tcg_ctx;
tcg_gen_gvec_3_ptr(tcg_ctx, vec_full_reg_offset(s, rd),
vec_full_reg_offset(s, rn),
vec_full_reg_offset(s, rm), tcg_ctx->cpu_env,
is_q ? 16 : 8, vec_full_reg_size(s), 0, fn);
}
/* Expand a 3-operand + fpstatus pointer + simd data value operation using
* an out-of-line helper.
*/
@ -11988,29 +11974,11 @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
switch (opcode) {
case 0x0: /* SQRDMLAH (vector) */
switch (size) {
case 1:
gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlah_s16);
break;
case 2:
gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlah_s32);
break;
default:
g_assert_not_reached();
}
gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqrdmlah_qc, size);
return;
case 0x1: /* SQRDMLSH (vector) */
switch (size) {
case 1:
gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlsh_s16);
break;
case 2:
gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlsh_s32);
break;
default:
g_assert_not_reached();
}
gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqrdmlsh_qc, size);
return;
case 0x2: /* SDOT / UDOT */

View file

@ -3757,22 +3757,26 @@ static const uint8_t neon_2rm_sizes[] = {
[NEON_2RM_VCVT_UF] = 0x4,
};
/* Expand v8.1 simd helper. */
static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
int q, int rd, int rn, int rm)
void gen_gvec_sqrdmlah_qc(TCGContext *s, unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
{
TCGContext *tcg_ctx = s->uc->tcg_ctx;
if (dc_isar_feature(aa32_rdm, s)) {
int opr_sz = (1 + q) * 8;
tcg_gen_gvec_3_ptr(tcg_ctx, vfp_reg_offset(1, rd),
vfp_reg_offset(1, rn),
vfp_reg_offset(1, rm), tcg_ctx->cpu_env,
opr_sz, opr_sz, 0, fn);
return 0;
static gen_helper_gvec_3_ptr * const fns[2] = {
gen_helper_gvec_qrdmlah_s16, gen_helper_gvec_qrdmlah_s32
};
tcg_debug_assert(vece >= 1 && vece <= 2);
tcg_gen_gvec_3_ptr(s, rd_ofs, rn_ofs, rm_ofs, s->cpu_env,
opr_sz, max_sz, 0, fns[vece - 1]);
}
return 1;
void gen_gvec_sqrdmlsh_qc(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 gen_helper_gvec_3_ptr * const fns[2] = {
gen_helper_gvec_qrdmlsh_s16, gen_helper_gvec_qrdmlsh_s32
};
tcg_debug_assert(vece >= 1 && vece <= 2);
tcg_gen_gvec_3_ptr(s, rd_ofs, rn_ofs, rm_ofs, s->cpu_env,
opr_sz, max_sz, 0, fns[vece - 1]);
}
#define GEN_CMP0(NAME, COND) \
@ -5326,13 +5330,10 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
break; /* VPADD */
}
/* VQRDMLAH */
switch (size) {
case 1:
return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
q, rd, rn, rm);
case 2:
return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
q, rd, rn, rm);
if (dc_isar_feature(aa32_rdm, s) && (size == 1 || size == 2)) {
gen_gvec_sqrdmlah_qc(tcg_ctx, size, rd_ofs, rn_ofs, rm_ofs,
vec_size, vec_size);
return 0;
}
return 1;
@ -5345,13 +5346,10 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
break;
}
/* VQRDMLSH */
switch (size) {
case 1:
return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
q, rd, rn, rm);
case 2:
return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
q, rd, rn, rm);
if (dc_isar_feature(aa32_rdm, s) && (size == 1 || size == 2)) {
gen_gvec_sqrdmlsh_qc(tcg_ctx, size, rd_ofs, rn_ofs, rm_ofs,
vec_size, vec_size);
return 0;
}
return 1;

View file

@ -339,6 +339,11 @@ void gen_gvec_sri(TCGContext *tcg_ctx, unsigned vece, uint32_t rd_ofs, uint32_t
void gen_gvec_sli(TCGContext *tcg_ctx, unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
int64_t shift, uint32_t opr_sz, uint32_t max_sz);
void gen_gvec_sqrdmlah_qc(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_sqrdmlsh_qc(TCGContext *s, unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
/*
* Forward to the isar_feature_* tests given a DisasContext pointer.
*/