aboutsummaryrefslogtreecommitdiff
path: root/target/arm
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-06-16 18:08:35 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-06-23 11:39:46 +0100
commit8966808205b59d6c196b380b638475bcd1657ef4 (patch)
treec5034b9af98cb10d3da4414cdc34e9268b817282 /target/arm
parent8ec3de7018a8198624aae49eef5568256114a829 (diff)
target/arm: Convert Neon 2-reg-misc VREV32 and VREV16 to decodetree
Convert the VREV32 and VREV16 insns in the Neon 2-reg-misc group to decodetree. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20200616170844.13318-13-peter.maydell@linaro.org
Diffstat (limited to 'target/arm')
-rw-r--r--target/arm/neon-dp.decode2
-rw-r--r--target/arm/translate-neon.inc.c55
-rw-r--r--target/arm/translate.c12
-rw-r--r--target/arm/translate.h1
4 files changed, 60 insertions, 10 deletions
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
index 86b1b9e34b..0a791af46c 100644
--- a/target/arm/neon-dp.decode
+++ b/target/arm/neon-dp.decode
@@ -445,6 +445,8 @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
&2misc vm=%vm_dp vd=%vd_dp q=1
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
+ VREV32 1111 001 11 . 11 .. 00 .... 0 0001 . . 0 .... @2misc
+ VREV16 1111 001 11 . 11 .. 00 .... 0 0010 . . 0 .... @2misc
VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
index 4967e97438..0a779980d0 100644
--- a/target/arm/translate-neon.inc.c
+++ b/target/arm/translate-neon.inc.c
@@ -3547,3 +3547,58 @@ DO_2M_CRYPTO(AESIMC, aa32_aes, 0)
DO_2M_CRYPTO(SHA1H, aa32_sha1, 2)
DO_2M_CRYPTO(SHA1SU1, aa32_sha1, 2)
DO_2M_CRYPTO(SHA256SU0, aa32_sha2, 2)
+
+static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
+{
+ int pass;
+
+ /* Handle a 2-reg-misc operation by iterating 32 bits at a time */
+ 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->vm) & 0x10)) {
+ return false;
+ }
+
+ if (!fn) {
+ return false;
+ }
+
+ if ((a->vd | a->vm) & a->q) {
+ return false;
+ }
+
+ if (!vfp_access_check(s)) {
+ return true;
+ }
+
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
+ fn(tmp, tmp);
+ neon_store_reg(a->vd, pass, tmp);
+ }
+
+ return true;
+}
+
+static bool trans_VREV32(DisasContext *s, arg_2misc *a)
+{
+ static NeonGenOneOpFn * const fn[] = {
+ tcg_gen_bswap32_i32,
+ gen_swap_half,
+ NULL,
+ NULL,
+ };
+ return do_2misc(s, a, fn[a->size]);
+}
+
+static bool trans_VREV16(DisasContext *s, arg_2misc *a)
+{
+ if (a->size != 0) {
+ return false;
+ }
+ return do_2misc(s, a, gen_rev16);
+}
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 64b18a95b6..5b50eddd11 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -4936,6 +4936,8 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
case NEON_2RM_AESE: case NEON_2RM_AESMC:
case NEON_2RM_SHA1H:
case NEON_2RM_SHA1SU1:
+ case NEON_2RM_VREV32:
+ case NEON_2RM_VREV16:
/* handled by decodetree */
return 1;
case NEON_2RM_VTRN:
@@ -4957,16 +4959,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
for (pass = 0; pass < (q ? 4 : 2); pass++) {
tmp = neon_load_reg(rm, pass);
switch (op) {
- case NEON_2RM_VREV32:
- switch (size) {
- case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
- case 1: gen_swap_half(tmp, tmp); break;
- default: abort();
- }
- break;
- case NEON_2RM_VREV16:
- gen_rev16(tmp, tmp);
- break;
case NEON_2RM_VCLS:
switch (size) {
case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 467c529110..4dbeee4c89 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -363,6 +363,7 @@ typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
uint32_t, uint32_t, uint32_t);
/* Function prototype for gen_ functions for calling Neon helpers */
+typedef void NeonGenOneOpFn(TCGv_i32, TCGv_i32);
typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);