target/arm: Implement VFP fp16 VSEL

Implement the fp16 versions of the VFP VSEL instruction.

Backports commit 11e78fecdf2d605cfed33aa09bbcf0cc4fb95886
This commit is contained in:
Peter Maydell 2021-03-01 16:08:49 -05:00 committed by Lioncash
parent beee4ad7f3
commit 1c8088b48a
2 changed files with 16 additions and 7 deletions

View file

@ -193,19 +193,22 @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
{ {
TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGContext *tcg_ctx = s->uc->tcg_ctx;
uint32_t rd, rn, rm; uint32_t rd, rn, rm;
bool dp = a->dp; int sz = a->sz;
if (!dc_isar_feature(aa32_vsel, s)) { if (!dc_isar_feature(aa32_vsel, s)) {
return false; return false;
} }
/* UNDEF accesses to D16-D31 if they don't exist */ if (sz == 3 && !dc_isar_feature(aa32_fpdp_v2, s)) {
if (dp && !dc_isar_feature(aa32_fpdp_v2, s)) { return false;
}
if (sz == 1 && !dc_isar_feature(aa32_fp16_arith, s)) {
return false; return false;
} }
/* UNDEF accesses to D16-D31 if they don't exist */ /* 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)) { ((a->vm | a->vn | a->vd) & 0x10)) {
return false; return false;
} }
@ -218,7 +221,7 @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
return true; return true;
} }
if (dp) { if (sz == 3) {
TCGv_i64 frn, frm, dest; TCGv_i64 frn, frm, dest;
TCGv_i64 tmp, zero, zf, nf, vf; TCGv_i64 tmp, zero, zf, nf, vf;
@ -311,6 +314,10 @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
tcg_temp_free_i32(tcg_ctx, tmp); tcg_temp_free_i32(tcg_ctx, tmp);
break; break;
} }
/* For fp16 the top half is always zeroes */
if (sz == 1) {
tcg_gen_andi_i32(tcg_ctx, dest, dest, 0xffff);
}
neon_store_reg32(s, dest, rd); neon_store_reg32(s, dest, rd);
tcg_temp_free_i32(tcg_ctx, frn); tcg_temp_free_i32(tcg_ctx, frn);
tcg_temp_free_i32(tcg_ctx, frm); tcg_temp_free_i32(tcg_ctx, frm);

View file

@ -44,10 +44,12 @@
@vfp_dnm_s ................................ vm=%vm_sp vn=%vn_sp vd=%vd_sp @vfp_dnm_s ................................ vm=%vm_sp vn=%vn_sp vd=%vd_sp
@vfp_dnm_d ................................ vm=%vm_dp vn=%vn_dp vd=%vd_dp @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 .... \ 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 .... \ 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 VMAXNM_hp 1111 1110 1.00 .... .... 1001 .0.0 .... @vfp_dnm_s
VMINNM_hp 1111 1110 1.00 .... .... 1001 .1.0 .... @vfp_dnm_s VMINNM_hp 1111 1110 1.00 .... .... 1001 .1.0 .... @vfp_dnm_s