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:28 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-06-16 10:32:28 +0100
commit54e96c744b70a5d19f14b212a579dd3be8fcaad9 (patch)
tree313dd9ae69f63e097656e9908cd368bad8e5dad4 /target/arm/translate-neon.inc.c
parent0aad761fb0aed40c99039eacac470cbd03d07019 (diff)
target/arm: Convert Neon VTBL, VTBX to decodetree
Convert the Neon VTBL, VTBX instructions to decodetree. The actual implementation of the insn is copied across to the new trans function unchanged except for renaming 'tmp5' to 'tmp4'. 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.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
index 84bc2b239c..da0e5dbc6f 100644
--- a/target/arm/translate-neon.inc.c
+++ b/target/arm/translate-neon.inc.c
@@ -2888,3 +2888,59 @@ static bool trans_VEXT(DisasContext *s, arg_VEXT *a)
}
return true;
}
+
+static bool trans_VTBL(DisasContext *s, arg_VTBL *a)
+{
+ int n;
+ TCGv_i32 tmp, tmp2, tmp3, tmp4;
+ TCGv_ptr ptr1;
+
+ 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 (!vfp_access_check(s)) {
+ return true;
+ }
+
+ n = a->len + 1;
+ if ((a->vn + n) > 32) {
+ /*
+ * This is UNPREDICTABLE; we choose to UNDEF to avoid the
+ * helper function running off the end of the register file.
+ */
+ return false;
+ }
+ n <<= 3;
+ if (a->op) {
+ tmp = neon_load_reg(a->vd, 0);
+ } else {
+ tmp = tcg_temp_new_i32();
+ tcg_gen_movi_i32(tmp, 0);
+ }
+ tmp2 = neon_load_reg(a->vm, 0);
+ ptr1 = vfp_reg_ptr(true, a->vn);
+ tmp4 = tcg_const_i32(n);
+ gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp4);
+ tcg_temp_free_i32(tmp);
+ if (a->op) {
+ tmp = neon_load_reg(a->vd, 1);
+ } else {
+ tmp = tcg_temp_new_i32();
+ tcg_gen_movi_i32(tmp, 0);
+ }
+ tmp3 = neon_load_reg(a->vm, 1);
+ gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp4);
+ tcg_temp_free_i32(tmp4);
+ tcg_temp_free_ptr(ptr1);
+ neon_store_reg(a->vd, 0, tmp2);
+ neon_store_reg(a->vd, 1, tmp3);
+ tcg_temp_free_i32(tmp);
+ return true;
+}