aboutsummaryrefslogtreecommitdiff
path: root/target/arm/translate-neon.inc.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-06-16 10:32:26 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-06-16 10:32:26 +0100
commit18fb58d588898550919392277787979ee7d0d84e (patch)
tree95081ce9e65d312a84d51bee7e2ca50177bdb50e /target/arm/translate-neon.inc.c
parent9546ca5998d3cbd98a81b2d46a2e92a11b0f78a4 (diff)
downloadqemu-18fb58d588898550919392277787979ee7d0d84e.zip
qemu-18fb58d588898550919392277787979ee7d0d84e.tar.gz
qemu-18fb58d588898550919392277787979ee7d0d84e.tar.bz2
target/arm: Convert Neon 3-reg-diff polynomial VMULL
Convert the Neon 3-reg-diff insn polynomial VMULL. This is the last insn in this group to be converted. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/arm/translate-neon.inc.c')
-rw-r--r--target/arm/translate-neon.inc.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
index 083e3af..c2cc109 100644
--- a/target/arm/translate-neon.inc.c
+++ b/target/arm/translate-neon.inc.c
@@ -2304,3 +2304,46 @@ static bool trans_VQDMLSL_3d(DisasContext *s, arg_3diff *a)
return do_long_3d(s, a, opfn[a->size], accfn[a->size]);
}
+
+static bool trans_VMULL_P_3d(DisasContext *s, arg_3diff *a)
+{
+ gen_helper_gvec_3 *fn_gvec;
+
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
+ return false;
+ }
+
+ /* UNDEF accesses to D16-D31 if they don't exist. */
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
+ ((a->vd | a->vn | a->vm) & 0x10)) {
+ return false;
+ }
+
+ if (a->vd & 1) {
+ return false;
+ }
+
+ switch (a->size) {
+ case 0:
+ fn_gvec = gen_helper_neon_pmull_h;
+ break;
+ case 2:
+ if (!dc_isar_feature(aa32_pmull, s)) {
+ return false;
+ }
+ fn_gvec = gen_helper_gvec_pmull_q;
+ break;
+ default:
+ return false;
+ }
+
+ if (!vfp_access_check(s)) {
+ return true;
+ }
+
+ tcg_gen_gvec_3_ool(neon_reg_offset(a->vd, 0),
+ neon_reg_offset(a->vn, 0),
+ neon_reg_offset(a->vm, 0),
+ 16, 16, 0, fn_gvec);
+ return true;
+}