diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2020-06-16 18:08:24 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-06-23 11:39:46 +0100 |
commit | 353d2b85058711a5e44c2dc63eb5b620db50a602 (patch) | |
tree | 0d4a55d877c6a086474ae0e2671ce34b4d7e0724 /target/arm/translate-neon.inc.c | |
parent | 2032e243a52c9834e5536463bcaa179f18d3319f (diff) | |
download | qemu-353d2b85058711a5e44c2dc63eb5b620db50a602.zip qemu-353d2b85058711a5e44c2dc63eb5b620db50a602.tar.gz qemu-353d2b85058711a5e44c2dc63eb5b620db50a602.tar.bz2 |
target/arm: Convert Neon 2-reg-misc VREV64 to decodetree
Convert the Neon VREV64 insn from the 2-reg-misc grouping to decodetree.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20200616170844.13318-2-peter.maydell@linaro.org
Diffstat (limited to 'target/arm/translate-neon.inc.c')
-rw-r--r-- | target/arm/translate-neon.inc.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c index a5aa56b..90431a5 100644 --- a/target/arm/translate-neon.inc.c +++ b/target/arm/translate-neon.inc.c @@ -2970,3 +2970,53 @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a) a->q ? 16 : 8, a->q ? 16 : 8); return true; } + +static bool trans_VREV64(DisasContext *s, arg_VREV64 *a) +{ + int pass, half; + + 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 ((a->vd | a->vm) & a->q) { + return false; + } + + if (a->size == 3) { + return false; + } + + if (!vfp_access_check(s)) { + return true; + } + + for (pass = 0; pass < (a->q ? 2 : 1); pass++) { + TCGv_i32 tmp[2]; + + for (half = 0; half < 2; half++) { + tmp[half] = neon_load_reg(a->vm, pass * 2 + half); + switch (a->size) { + case 0: + tcg_gen_bswap32_i32(tmp[half], tmp[half]); + break; + case 1: + gen_swap_half(tmp[half]); + break; + case 2: + break; + default: + g_assert_not_reached(); + } + } + neon_store_reg(a->vd, pass * 2, tmp[1]); + neon_store_reg(a->vd, pass * 2 + 1, tmp[0]); + } + return true; +} |