[PATCH v2 8/8] target/arm: Pull Neon dregs checks out into a function
Peter Maydell <[email protected]>
| Newsgroups | org.nongnu.qemu-arm,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
Abstract out the register check for Neon insns into a new function, similarly to what we have for VFP. We don't have any extra checks that we need to add here, but having a neon_dregs_ok() is cleaner and means the Neon decode isn't oddly different to the VFP decode. Signed-off-by: Peter Maydell <[email protected]> --- target/arm/tcg/translate-neon.c | 118 ++++++++++++++------------------ target/arm/tcg/translate.c | 1 + target/arm/tcg/translate.h | 1 + 3 files changed, 53 insertions(+), 67 deletions(-) diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c index 50a44511d9..f811940f64 100644 --- a/target/arm/tcg/translate-neon.c +++ b/target/arm/tcg/translate-neon.c @@ -118,11 +118,24 @@ static void neon_store_element64(int reg, int ele, MemOp size, TCGv_i64 var) } } +/* + * Return true if a Neon insn is OK to access the registers indicated + * by regmask, false if it should UNDEF. This checks whether the + * D16-D31 regs are implemented by the CPU. + * Note that Neon insns accessing D16..D31 do not need to check D32DIS. + * + * @regmask should be the logical OR of the Dregs being accessed. + */ +static bool neon_dregs_ok(DisasContext *s, int dregmask) +{ + return !(dregmask & s->invalid_neon_dreg_mask); +} + static bool do_neon_ddda(DisasContext *s, int q, int vd, int vn, int vm, int data, gen_helper_gvec_4 *fn_gvec) { /* UNDEF accesses to D16-D31 if they don't exist. */ - if (((vd | vn | vm) & 0x10) && !dc_isar_feature(aa32_simd_r32, s)) { + if (!neon_dregs_ok(s, vd | vn | vm)) { return false; } @@ -152,7 +165,7 @@ static bool do_neon_ddda_env(DisasContext *s, int q, int vd, int vn, int vm, int data, gen_helper_gvec_4_ptr *fn_gvec) { /* UNDEF accesses to D16-D31 if they don't exist. */ - if (((vd | vn | vm) & 0x10) && !dc_isar_feature(aa32_simd_r32, s)) { + if (!neon_dregs_ok(s, vd | vn | vm)) { return false; } @@ -184,7 +197,7 @@ static bool do_neon_ddda_fpst(DisasContext *s, int q, int vd, int vn, int vm, gen_helper_gvec_4_ptr *fn_gvec_ptr) { /* UNDEF accesses to D16-D31 if they don't exist. */ - if (((vd | vn | vm) & 0x10) && !dc_isar_feature(aa32_simd_r32, s)) { + if (!neon_dregs_ok(s, vd | vn | vm)) { return false; } @@ -240,8 +253,7 @@ static bool trans_VCADD(DisasContext *s, arg_VCADD *a) } /* 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)) { + if (!neon_dregs_ok(s, a->vd | a->vn | a->vm)) { return false; } @@ -310,8 +322,7 @@ static bool trans_VFML(DisasContext *s, arg_VFML *a) } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - (a->vd & 0x10)) { + if (!neon_dregs_ok(s, a->vd)) { return false; } @@ -398,14 +409,14 @@ static bool trans_VDOT_b16_scal(DisasContext *s, arg_VDOT_b16_scal *a) static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a) { int opr_sz; + int dregmask = a->vd | (a->q ? a->vn : 0); if (!dc_isar_feature(aa32_fhm, s)) { return false; } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - ((a->vd & 0x10) || (a->q && (a->vn & 0x10)))) { + if (!neon_dregs_ok(s, dregmask)) { return false; } @@ -478,7 +489,7 @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a) } /* UNDEF accesses to D16-D31 if they don't exist */ - if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) { + if (!neon_dregs_ok(s, a->vd)) { return false; } if (a->itype > 10) { @@ -580,7 +591,7 @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a) } /* UNDEF accesses to D16-D31 if they don't exist */ - if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) { + if (!neon_dregs_ok(s, a->vd)) { return false; } @@ -672,7 +683,7 @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a) } /* UNDEF accesses to D16-D31 if they don't exist */ - if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) { + if (!neon_dregs_ok(s, a->vd)) { return false; } @@ -789,8 +800,7 @@ static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn) } /* 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)) { + if (!neon_dregs_ok(s, a->vd | a->vn | a->vm)) { return false; } @@ -1067,8 +1077,7 @@ static bool do_vector_2sh(DisasContext *s, arg_2reg_shift *a, GVecGen2iFn *fn) } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - ((a->vd | a->vm) & 0x10)) { + if (!neon_dregs_ok(s, a->vd | a->vm)) { return false; } @@ -1117,8 +1126,7 @@ static bool do_2shift_narrow_64(DisasContext *s, arg_2reg_shift *a, } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - ((a->vd | a->vm) & 0x10)) { + if (!neon_dregs_ok(s, a->vd | a->vm)) { return false; } @@ -1168,8 +1176,7 @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a, } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - ((a->vd | a->vm) & 0x10)) { + if (!neon_dregs_ok(s, a->vd | a->vm)) { return false; } @@ -1293,8 +1300,7 @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a, } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - ((a->vd | a->vm) & 0x10)) { + if (!neon_dregs_ok(s, a->vd | a->vm)) { return false; } @@ -1383,8 +1389,7 @@ static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a, } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - ((a->vd | a->vm) & 0x10)) { + if (!neon_dregs_ok(s, a->vd | a->vm)) { return false; } @@ -1428,7 +1433,7 @@ static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a, } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) { + if (!neon_dregs_ok(s, a->vd)) { return false; } @@ -1485,8 +1490,7 @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a, } /* 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)) { + if (!neon_dregs_ok(s, a->vd | a->vn | a->vm)) { return false; } @@ -1592,8 +1596,7 @@ static bool do_narrow_3d(DisasContext *s, arg_3diff *a, } /* 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)) { + if (!neon_dregs_ok(s, a->vd | a->vn | a->vm)) { return false; } @@ -1682,8 +1685,7 @@ static bool do_long_3d(DisasContext *s, arg_3diff *a, } /* 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)) { + if (!neon_dregs_ok(s, a->vd | a->vn | a->vm)) { return false; } @@ -1944,8 +1946,7 @@ static bool trans_VMULL_P_3d(DisasContext *s, arg_3diff *a) } /* 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)) { + if (!neon_dregs_ok(s, a->vd | a->vn | a->vm)) { return false; } @@ -2027,8 +2028,7 @@ static bool do_2scalar(DisasContext *s, arg_2scalar *a, } /* 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)) { + if (!neon_dregs_ok(s, a->vd | a->vn | a->vm)) { return false; } @@ -2125,8 +2125,7 @@ static bool do_2scalar_fp_vec(DisasContext *s, arg_2scalar *a, } /* 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)) { + if (!neon_dregs_ok(s, a->vd | a->vn | a->vm)) { return false; } @@ -2222,8 +2221,7 @@ static bool do_vqrdmlah_2sc(DisasContext *s, arg_2scalar *a, } /* 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)) { + if (!neon_dregs_ok(s, a->vd | a->vn | a->vm)) { return false; } @@ -2293,8 +2291,7 @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a, } /* 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)) { + if (!neon_dregs_ok(s, a->vd | a->vn | a->vm)) { return false; } @@ -2438,8 +2435,7 @@ static bool trans_VEXT(DisasContext *s, arg_VEXT *a) } /* 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)) { + if (!neon_dregs_ok(s, a->vd | a->vn | a->vm)) { return false; } @@ -2507,8 +2503,7 @@ static bool trans_VTBL(DisasContext *s, arg_VTBL *a) } /* 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)) { + if (!neon_dregs_ok(s, a->vd | a->vn | a->vm)) { return false; } @@ -2546,8 +2541,7 @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a) } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - ((a->vd | a->vm) & 0x10)) { + if (!neon_dregs_ok(s, a->vd | a->vm)) { return false; } @@ -2577,8 +2571,7 @@ static bool do_zip_uzp(DisasContext *s, arg_2misc *a, } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - ((a->vd | a->vm) & 0x10)) { + if (!neon_dregs_ok(s, a->vd | a->vm)) { return false; } @@ -2647,8 +2640,7 @@ static bool do_vmovn(DisasContext *s, arg_2misc *a, } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - ((a->vd | a->vm) & 0x10)) { + if (!neon_dregs_ok(s, a->vd | a->vm)) { return false; } @@ -2711,8 +2703,7 @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a) } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - ((a->vd | a->vm) & 0x10)) { + if (!neon_dregs_ok(s, a->vd | a->vm)) { return false; } @@ -2755,8 +2746,7 @@ static bool trans_VCVT_B16_F32(DisasContext *s, arg_2misc *a) } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - ((a->vd | a->vm) & 0x10)) { + if (!neon_dregs_ok(s, a->vd | a->vm)) { return false; } @@ -2795,8 +2785,7 @@ static bool trans_VCVT_F16_F32(DisasContext *s, arg_2misc *a) } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - ((a->vd | a->vm) & 0x10)) { + if (!neon_dregs_ok(s, a->vd | a->vm)) { return false; } @@ -2841,8 +2830,7 @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a) } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - ((a->vd | a->vm) & 0x10)) { + if (!neon_dregs_ok(s, a->vd | a->vm)) { return false; } @@ -2887,8 +2875,7 @@ static bool do_2misc_vec(DisasContext *s, arg_2misc *a, GVecGen2Fn *fn) } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - ((a->vd | a->vm) & 0x10)) { + if (!neon_dregs_ok(s, a->vd | a->vm)) { return false; } @@ -3015,8 +3002,7 @@ static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn) } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - ((a->vd | a->vm) & 0x10)) { + if (!neon_dregs_ok(s, a->vd | a->vm)) { return false; } @@ -3219,8 +3205,7 @@ static bool trans_VSWP(DisasContext *s, arg_2misc *a) } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - ((a->vd | a->vm) & 0x10)) { + if (!neon_dregs_ok(s, a->vd | a->vm)) { return false; } @@ -3292,8 +3277,7 @@ static bool trans_VTRN(DisasContext *s, arg_2misc *a) } /* UNDEF accesses to D16-D31 if they don't exist. */ - if (!dc_isar_feature(aa32_simd_r32, s) && - ((a->vd | a->vm) & 0x10)) { + if (!neon_dregs_ok(s, a->vd | a->vm)) { return false; } diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c index 1bf9d61035..a311abb0a5 100644 --- a/target/arm/tcg/translate.c +++ b/target/arm/tcg/translate.c @@ -6410,6 +6410,7 @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) dc->invalid_vfp_dreg_mask = (d32dis || !dc_isar_feature(aa32_simd_r32, dc)) ? 0x10 : 0; + dc->invalid_neon_dreg_mask = !dc_isar_feature(aa32_simd_r32, dc) ? 0x10 : 0; dc->lse2 = false; /* applies only to aarch64 */ dc->cp_regs = cpu->cp_regs; diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h index b08bded398..31f52a34a6 100644 --- a/target/arm/tcg/translate.h +++ b/target/arm/tcg/translate.h @@ -95,6 +95,7 @@ typedef struct DisasContext { int max_any_vl; /* maximum implemented vector length */ bool vfp_enabled; /* FP enabled via FPSCR.EN */ int invalid_vfp_dreg_mask; /* mask for whether VFP D16..D31 should UNDEF */ + int invalid_neon_dreg_mask; /* ditto, for Neon */ int vec_len; int vec_stride; bool v7m_handler_mode; -- 2.43.0