diff --git a/qemu/target/arm/neon-dp.decode b/qemu/target/arm/neon-dp.decode index 1e9e8592..ea2f0dfc 100644 --- a/qemu/target/arm/neon-dp.decode +++ b/qemu/target/arm/neon-dp.decode @@ -45,11 +45,16 @@ @3same_q0 .... ... . . . size:2 .... .... .... . 0 . . .... \ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp q=0 -# For FP insns the high bit of 'size' is used as part of opcode decode -@3same_fp .... ... . . . . size:1 .... .... .... . q:1 . . .... \ - &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp -@3same_fp_q0 .... ... . . . . size:1 .... .... .... . 0 . . .... \ - &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp q=0 +# For FP insns the high bit of 'size' is used as part of opcode decode, +# and the 'size' bit is 0 for 32-bit float and 1 for 16-bit float. +# This converts this encoding to the same MO_8/16/32/64 values that the +# integer neon insns use. +%3same_fp_size 20:1 !function=neon_3same_fp_size + +@3same_fp .... ... . . . . . .... .... .... . q:1 . . .... \ + &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=%3same_fp_size +@3same_fp_q0 .... ... . . . . . .... .... .... . 0 . . .... \ + &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp q=0 size=%3same_fp_size VHADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 0 .... @3same VHADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 0 .... @3same diff --git a/qemu/target/arm/translate-neon.inc.c b/qemu/target/arm/translate-neon.inc.c index b05119cc..8e760209 100644 --- a/qemu/target/arm/translate-neon.inc.c +++ b/qemu/target/arm/translate-neon.inc.c @@ -49,6 +49,12 @@ static inline int rsub_8(DisasContext *s, int x) return 8 - x; } +static inline int neon_3same_fp_size(DisasContext *s, int x) +{ + /* Convert 0==fp32, 1==fp16 into a MO_* value */ + return MO_32 - x; +} + /* Include the generated Neon decoder */ #include "decode-neon-dp.inc.c" #include "decode-neon-ls.inc.c" @@ -1067,7 +1073,7 @@ DO_3SAME_VQDMULH(VQRDMULH, qrdmulh) WRAP_FP_GVEC(gen_##INSN##_fp16_3s, FPST_STD_F16, HFUNC) \ static bool trans_##INSN##_fp_3s(DisasContext *s, arg_3same *a) \ { \ - if (a->size != 0) { \ + if (a->size == MO_16) { \ if (!dc_isar_feature(aa32_fp16_arith, s)) { \ return false; \ } \ @@ -1106,7 +1112,7 @@ static bool trans_VMAXNM_fp_3s(DisasContext *s, arg_3same *a) return false; } - if (a->size != 0) { + if (a->size == MO_16) { if (!dc_isar_feature(aa32_fp16_arith, s)) { return false; } @@ -1122,7 +1128,7 @@ static bool trans_VMINNM_fp_3s(DisasContext *s, arg_3same *a) return false; } - if (a->size != 0) { + if (a->size == MO_16) { if (!dc_isar_feature(aa32_fp16_arith, s)) { return false; } @@ -1155,7 +1161,7 @@ static bool do_3same_fp_pair(DisasContext *s, arg_3same *a, assert(a->q == 0); /* enforced by decode patterns */ - fpstatus = fpstatus_ptr(tcg_ctx, a->size != 0 ? FPST_STD_F16 : FPST_STD); + fpstatus = fpstatus_ptr(tcg_ctx, a->size == MO_16 ? FPST_STD_F16 : FPST_STD); tcg_gen_gvec_3_ptr(tcg_ctx, vfp_reg_offset(1, a->vd), vfp_reg_offset(1, a->vn), vfp_reg_offset(1, a->vm), @@ -1172,7 +1178,7 @@ static bool do_3same_fp_pair(DisasContext *s, arg_3same *a, #define DO_3S_FP_PAIR(INSN,FUNC) \ static bool trans_##INSN##_fp_3s(DisasContext *s, arg_3same *a) \ { \ - if (a->size != 0) { \ + if (a->size == MO_16) { \ if (!dc_isar_feature(aa32_fp16_arith, s)) { \ return false; \ } \