From ac9ae5cbe7c9d0d3b4791727c570337564e963e0 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Sun, 28 Feb 2021 04:58:29 -0500 Subject: [PATCH] target/arm: Implement VFP fp16 VLDR and VSTR Implement the fp16 versions of the VFP VLDR/VSTR (immediate). Backports commit 274afbb121107b8aaeaa11b3e7904d5f8ae38a94 --- qemu/target/arm/translate-vfp.inc.c | 36 +++++++++++++++++++++++++++++ qemu/target/arm/vfp.decode | 3 +-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/qemu/target/arm/translate-vfp.inc.c b/qemu/target/arm/translate-vfp.inc.c index 2ac733b1..2df9fa13 100644 --- a/qemu/target/arm/translate-vfp.inc.c +++ b/qemu/target/arm/translate-vfp.inc.c @@ -899,6 +899,42 @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a) return true; } +static bool trans_VLDR_VSTR_hp(DisasContext *s, arg_VLDR_VSTR_sp *a) +{ + uint32_t offset; + TCGv_i32 addr, tmp; + TCGContext *tcg_ctx = s->uc->tcg_ctx; + + if (!dc_isar_feature(aa32_fp16_arith, s)) { + return false; + } + + if (!vfp_access_check(s)) { + return true; + } + + /* imm8 field is offset/2 for fp16, unlike fp32 and fp64 */ + offset = a->imm << 1; + if (!a->u) { + offset = -offset; + } + + /* For thumb, use of PC is UNPREDICTABLE. */ + addr = add_reg_for_lit(s, a->rn, offset); + tmp = tcg_temp_new_i32(tcg_ctx); + if (a->l) { + gen_aa32_ld16u(s, tmp, addr, get_mem_index(s)); + neon_store_reg32(s, tmp, a->vd); + } else { + neon_load_reg32(s, tmp, a->vd); + gen_aa32_st16(s, tmp, addr, get_mem_index(s)); + } + tcg_temp_free_i32(tcg_ctx, tmp); + tcg_temp_free_i32(tcg_ctx, addr); + + return true; +} + static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a) { TCGContext *tcg_ctx = s->uc->tcg_ctx; diff --git a/qemu/target/arm/vfp.decode b/qemu/target/arm/vfp.decode index b213da4b..37f96e2d 100644 --- a/qemu/target/arm/vfp.decode +++ b/qemu/target/arm/vfp.decode @@ -79,8 +79,7 @@ VMOV_single ---- 1110 000 l:1 .... rt:4 1010 . 001 0000 vn=%vn_sp VMOV_64_sp ---- 1100 010 op:1 rt2:4 rt:4 1010 00.1 .... vm=%vm_sp VMOV_64_dp ---- 1100 010 op:1 rt2:4 rt:4 1011 00.1 .... vm=%vm_dp -# Note that the half-precision variants of VLDR and VSTR are -# not part of this decodetree at all because they have bits [9:8] == 0b01 +VLDR_VSTR_hp ---- 1101 u:1 .0 l:1 rn:4 .... 1001 imm:8 vd=%vd_sp VLDR_VSTR_sp ---- 1101 u:1 .0 l:1 rn:4 .... 1010 imm:8 vd=%vd_sp VLDR_VSTR_dp ---- 1101 u:1 .0 l:1 rn:4 .... 1011 imm:8 vd=%vd_dp