aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-08-28 19:33:26 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-09-01 11:19:32 +0100
commit11e78fecdf2d605cfed33aa09bbcf0cc4fb95886 (patch)
tree449929b7352946db85b27a01b4e0542dcdea6cb2
parentc505bc6a9d50a48f9d89d6cf930e863838a5b367 (diff)
target/arm: Implement VFP fp16 VSEL
Implement the fp16 versions of the VFP VSEL instruction. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20200828183354.27913-18-peter.maydell@linaro.org
-rw-r--r--target/arm/translate-vfp.c.inc16
-rw-r--r--target/arm/vfp-uncond.decode6
2 files changed, 16 insertions, 6 deletions
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index 583e7ccdb2..869b67b2b9 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -190,18 +190,22 @@ static bool vfp_access_check(DisasContext *s)
static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
{
uint32_t rd, rn, rm;
- bool dp = a->dp;
+ int sz = a->sz;
if (!dc_isar_feature(aa32_vsel, s)) {
return false;
}
- if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) {
+ if (sz == 3 && !dc_isar_feature(aa32_fpdp_v2, s)) {
+ return false;
+ }
+
+ if (sz == 1 && !dc_isar_feature(aa32_fp16_arith, s)) {
return false;
}
/* UNDEF accesses to D16-D31 if they don't exist */
- if (dp && !dc_isar_feature(aa32_simd_r32, s) &&
+ if (sz == 3 && !dc_isar_feature(aa32_simd_r32, s) &&
((a->vm | a->vn | a->vd) & 0x10)) {
return false;
}
@@ -214,7 +218,7 @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
return true;
}
- if (dp) {
+ if (sz == 3) {
TCGv_i64 frn, frm, dest;
TCGv_i64 tmp, zero, zf, nf, vf;
@@ -307,6 +311,10 @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
tcg_temp_free_i32(tmp);
break;
}
+ /* For fp16 the top half is always zeroes */
+ if (sz == 1) {
+ tcg_gen_andi_i32(dest, dest, 0xffff);
+ }
neon_store_reg32(dest, rd);
tcg_temp_free_i32(frn);
tcg_temp_free_i32(frm);
diff --git a/target/arm/vfp-uncond.decode b/target/arm/vfp-uncond.decode
index b7cd9d11ed..8ba7b1703e 100644
--- a/target/arm/vfp-uncond.decode
+++ b/target/arm/vfp-uncond.decode
@@ -44,10 +44,12 @@
@vfp_dnm_s ................................ vm=%vm_sp vn=%vn_sp vd=%vd_sp
@vfp_dnm_d ................................ vm=%vm_dp vn=%vn_dp vd=%vd_dp
+VSEL 1111 1110 0. cc:2 .... .... 1001 .0.0 .... \
+ vm=%vm_sp vn=%vn_sp vd=%vd_sp sz=1
VSEL 1111 1110 0. cc:2 .... .... 1010 .0.0 .... \
- vm=%vm_sp vn=%vn_sp vd=%vd_sp dp=0
+ vm=%vm_sp vn=%vn_sp vd=%vd_sp sz=2
VSEL 1111 1110 0. cc:2 .... .... 1011 .0.0 .... \
- vm=%vm_dp vn=%vn_dp vd=%vd_dp dp=1
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp sz=3
VMAXNM_hp 1111 1110 1.00 .... .... 1001 .0.0 .... @vfp_dnm_s
VMINNM_hp 1111 1110 1.00 .... .... 1001 .1.0 .... @vfp_dnm_s