Signed-off-by: Richard Henderson
---
target/arm/helper.h| 10 ++
target/arm/tcg/a64.decode | 16 +++
target/arm/tcg/translate-a64.c | 206 +
target/arm/tcg/vec_helper.c| 72
4 files changed, 180 insertions(+), 124 deletions(-)
diff --git a/target/arm/helper.h b/target/arm/helper.h
index eca2043fc2..970d059dec 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -979,6 +979,16 @@ DEF_HELPER_FLAGS_5(neon_sqrdmulh_idx_h, TCG_CALL_NO_RWG,
DEF_HELPER_FLAGS_5(neon_sqrdmulh_idx_s, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(neon_sqrdmlah_idx_h, TCG_CALL_NO_RWG,
+ void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(neon_sqrdmlah_idx_s, TCG_CALL_NO_RWG,
+ void, ptr, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_5(neon_sqrdmlsh_idx_h, TCG_CALL_NO_RWG,
+ void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(neon_sqrdmlsh_idx_s, TCG_CALL_NO_RWG,
+ void, ptr, ptr, ptr, ptr, i32)
+
DEF_HELPER_FLAGS_4(sve2_sqdmulh_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(sve2_sqdmulh_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(sve2_sqdmulh_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 2b7a3254a0..613cc9365c 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -781,6 +781,8 @@ CMEQ_s 0111 1110 111 . 10001 1 . .
@rrr_d
SQDMULH_s 0101 1110 ..1 . 10110 1 . . @rrr_e
SQRDMULH_s 0111 1110 ..1 . 10110 1 . . @rrr_e
+SQRDMLAH_s 0111 1110 ..0 . 1 1 . . @rrr_e
+SQRDMLSH_s 0111 1110 ..0 . 10001 1 . . @rrr_e
### Advanced SIMD scalar pairwise
@@ -941,6 +943,8 @@ MLS_v 0.10 1110 ..1 . 10010 1 . .
@qrrr_e
SQDMULH_v 0.00 1110 ..1 . 10110 1 . . @qrrr_e
SQRDMULH_v 0.10 1110 ..1 . 10110 1 . . @qrrr_e
+SQRDMLAH_v 0.10 1110 ..0 . 1 1 . . @qrrr_e
+SQRDMLSH_v 0.10 1110 ..0 . 10001 1 . . @qrrr_e
### Advanced SIMD scalar x indexed element
@@ -966,6 +970,12 @@ SQDMULH_si 0101 10 .. 1100 . 0 . .
@rrx_s
SQRDMULH_si 0101 01 .. 1101 . 0 . . @rrx_h
SQRDMULH_si 0101 10 . . 1101 . 0 . . @rrx_s
+SQRDMLAH_si 0111 01 .. 1101 . 0 . . @rrx_h
+SQRDMLAH_si 0111 10 .. 1101 . 0 . . @rrx_s
+
+SQRDMLSH_si 0111 01 .. . 0 . . @rrx_h
+SQRDMLSH_si 0111 10 .. . 0 . . @rrx_s
+
### Advanced SIMD vector x indexed element
FMUL_vi 0.00 00 .. 1001 . 0 . . @qrrx_h
@@ -1004,6 +1014,12 @@ SQDMULH_vi 0.00 10 . . 1100 . 0 .
. @qrrx_s
SQRDMULH_vi 0.00 01 .. 1101 . 0 . . @qrrx_h
SQRDMULH_vi 0.00 10 . . 1101 . 0 . . @qrrx_s
+SQRDMLAH_vi 0.10 01 .. 1101 . 0 . . @qrrx_h
+SQRDMLAH_vi 0.10 10 .. 1101 . 0 . . @qrrx_s
+
+SQRDMLSH_vi 0.10 01 .. . 0 . . @qrrx_h
+SQRDMLSH_vi 0.10 10 .. . 0 . . @qrrx_s
+
# Floating-point conditional select
FCSEL 0001 1110 .. 1 rm:5 cond:4 11 rn:5 rd:5 esz=%esz_hsd
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 93543da39c..32c24c7422 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5235,6 +5235,43 @@ static const ENVScalar2 f_scalar_sqrdmulh = {
};
TRANS(SQRDMULH_s, do_env_scalar2_hs, a, &f_scalar_sqrdmulh)
+typedef struct ENVScalar3 {
+NeonGenThreeOpEnvFn *gen_hs[2];
+} ENVScalar3;
+
+static bool do_env_scalar3_hs(DisasContext *s, arg_rrr_e *a,
+ const ENVScalar3 *f)
+{
+TCGv_i32 t0, t1, t2;
+
+if (a->esz != MO_16 && a->esz != MO_32) {
+return false;
+}
+if (!fp_access_check(s)) {
+return true;
+}
+
+t0 = tcg_temp_new_i32();
+t1 = tcg_temp_new_i32();
+t2 = tcg_temp_new_i32();
+read_vec_element_i32(s, t0, a->rn, 0, a->esz);
+read_vec_element_i32(s, t1, a->rm, 0, a->esz);
+read_vec_element_i32(s, t2, a->rd, 0, a->esz);
+f->gen_hs[a->esz - 1](t0, tcg_env, t0, t1, t2);
+write_fp_sreg(s, a->rd, t0);
+return true;
+}
+
+static const ENVScalar3 f_scalar_sqrdmlah = {
+{ gen_helper_neon_qrdmlah_s16, gen_helper_neon_qrdmlah_s32 }
+};
+TRANS_FEAT(SQRDMLAH_s, aa64_rdm, do_env_scalar3_hs, a, &f_scalar_sqrdmlah)
+
+static const ENVScalar3 f_scalar_sqrdmlsh = {
+{ gen_helper_neon_qrdmlsh_s16, gen_helper_neon_qrdmlsh_s32 }
+};
+TRANS_FEAT(SQRDMLSH_s, aa64_rdm, do_env_scalar3_hs, a, &f_scalar_sqrdmlsh)
+
static bool do_cmop_d(DisasContext *s, arg_rrr_e *a, TCGCond cond)