From d1c5d5b728486ca1a286f27a46faf5b899afbb11 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 3 Jul 2018 02:11:30 -0400 Subject: [PATCH] target/arm: Implement SVE floating-point arithmetic (predicated) Backports commit ec3b87c28eb120b6575cc1ed7bfbfbf1b0060163 from qemu --- qemu/aarch64.h | 33 ++++++++++++ qemu/aarch64eb.h | 33 ++++++++++++ qemu/header_gen.py | 33 ++++++++++++ qemu/target/arm/helper-sve.h | 77 ++++++++++++++++++++++++++++ qemu/target/arm/sve.decode | 17 +++++++ qemu/target/arm/sve_helper.c | 89 +++++++++++++++++++++++++++++++++ qemu/target/arm/translate-sve.c | 48 ++++++++++++++++++ 7 files changed, 330 insertions(+) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 35dbd562..0e7d154f 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -3495,15 +3495,48 @@ #define helper_sve_eorv_h helper_sve_eorv_h_aarch64 #define helper_sve_eorv_s helper_sve_eorv_s_aarch64 #define helper_sve_ext helper_sve_ext_aarch64 +#define helper_sve_fabd_d helper_sve_fabd_d_aarch64 +#define helper_sve_fabd_h helper_sve_fabd_h_aarch64 +#define helper_sve_fabd_s helper_sve_fabd_s_aarch64 #define helper_sve_fabs_d helper_sve_fabs_d_aarch64 #define helper_sve_fabs_h helper_sve_fabs_h_aarch64 #define helper_sve_fabs_s helper_sve_fabs_s_aarch64 +#define helper_sve_fadd_d helper_sve_fadd_d_aarch64 +#define helper_sve_fadd_h helper_sve_fadd_h_aarch64 +#define helper_sve_fadd_s helper_sve_fadd_s_aarch64 +#define helper_sve_fdiv_d helper_sve_fdiv_d_aarch64 +#define helper_sve_fdiv_h helper_sve_fdiv_h_aarch64 +#define helper_sve_fdiv_s helper_sve_fdiv_s_aarch64 #define helper_sve_fexpa_d helper_sve_fexpa_d_aarch64 #define helper_sve_fexpa_h helper_sve_fexpa_h_aarch64 #define helper_sve_fexpa_s helper_sve_fexpa_s_aarch64 +#define helper_sve_fmax_d helper_sve_fmax_d_aarch64 +#define helper_sve_fmax_h helper_sve_fmax_h_aarch64 +#define helper_sve_fmax_s helper_sve_fmax_s_aarch64 +#define helper_sve_fmaxnum_d helper_sve_fmaxnum_d_aarch64 +#define helper_sve_fmaxnum_h helper_sve_fmaxnum_h_aarch64 +#define helper_sve_fmaxnum_s helper_sve_fmaxnum_s_aarch64 +#define helper_sve_fmin_d helper_sve_fmin_d_aarch64 +#define helper_sve_fmin_h helper_sve_fmin_h_aarch64 +#define helper_sve_fmin_s helper_sve_fmin_s_aarch64 +#define helper_sve_fminnum_d helper_sve_fminnum_d_aarch64 +#define helper_sve_fminnum_h helper_sve_fminnum_h_aarch64 +#define helper_sve_fminnum_s helper_sve_fminnum_s_aarch64 +#define helper_sve_fmul_d helper_sve_fmul_d_aarch64 +#define helper_sve_fmul_h helper_sve_fmul_h_aarch64 +#define helper_sve_fmul_s helper_sve_fmul_s_aarch64 +#define helper_sve_fmulx_d helper_sve_fmulx_d_aarch64 +#define helper_sve_fmulx_h helper_sve_fmulx_h_aarch64 +#define helper_sve_fmulx_s helper_sve_fmulx_s_aarch64 #define helper_sve_fneg_d helper_sve_fneg_d_aarch64 #define helper_sve_fneg_h helper_sve_fneg_h_aarch64 #define helper_sve_fneg_s helper_sve_fneg_s_aarch64 +#define helper_sve_fscalbn_d helper_sve_fscalbn_d_aarch64 +#define helper_sve_fscalbn_h helper_sve_fscalbn_h_aarch64 +#define helper_sve_fscalbn_s helper_sve_fscalbn_s_aarch64 +#define helper_sve_fsub_d helper_sve_fsub_d_aarch64 +#define helper_sve_fsub_h helper_sve_fsub_h_aarch64 +#define helper_sve_fsub_s helper_sve_fsub_s_aarch64 #define helper_sve_ftssel_d helper_sve_ftssel_d_aarch64 #define helper_sve_ftssel_h helper_sve_ftssel_h_aarch64 #define helper_sve_ftssel_s helper_sve_ftssel_s_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 366b4cf6..25d3f415 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -3495,15 +3495,48 @@ #define helper_sve_eorv_h helper_sve_eorv_h_aarch64eb #define helper_sve_eorv_s helper_sve_eorv_s_aarch64eb #define helper_sve_ext helper_sve_ext_aarch64eb +#define helper_sve_fabd_d helper_sve_fabd_d_aarch64eb +#define helper_sve_fabd_h helper_sve_fabd_h_aarch64eb +#define helper_sve_fabd_s helper_sve_fabd_s_aarch64eb #define helper_sve_fabs_d helper_sve_fabs_d_aarch64eb #define helper_sve_fabs_h helper_sve_fabs_h_aarch64eb #define helper_sve_fabs_s helper_sve_fabs_s_aarch64eb +#define helper_sve_fadd_d helper_sve_fadd_d_aarch64eb +#define helper_sve_fadd_h helper_sve_fadd_h_aarch64eb +#define helper_sve_fadd_s helper_sve_fadd_s_aarch64eb +#define helper_sve_fdiv_d helper_sve_fdiv_d_aarch64eb +#define helper_sve_fdiv_h helper_sve_fdiv_h_aarch64eb +#define helper_sve_fdiv_s helper_sve_fdiv_s_aarch64eb #define helper_sve_fexpa_d helper_sve_fexpa_d_aarch64eb #define helper_sve_fexpa_h helper_sve_fexpa_h_aarch64eb #define helper_sve_fexpa_s helper_sve_fexpa_s_aarch64eb +#define helper_sve_fmax_d helper_sve_fmax_d_aarch64eb +#define helper_sve_fmax_h helper_sve_fmax_h_aarch64eb +#define helper_sve_fmax_s helper_sve_fmax_s_aarch64eb +#define helper_sve_fmaxnum_d helper_sve_fmaxnum_d_aarch64eb +#define helper_sve_fmaxnum_h helper_sve_fmaxnum_h_aarch64eb +#define helper_sve_fmaxnum_s helper_sve_fmaxnum_s_aarch64eb +#define helper_sve_fmin_d helper_sve_fmin_d_aarch64eb +#define helper_sve_fmin_h helper_sve_fmin_h_aarch64eb +#define helper_sve_fmin_s helper_sve_fmin_s_aarch64eb +#define helper_sve_fminnum_d helper_sve_fminnum_d_aarch64eb +#define helper_sve_fminnum_h helper_sve_fminnum_h_aarch64eb +#define helper_sve_fminnum_s helper_sve_fminnum_s_aarch64eb +#define helper_sve_fmul_d helper_sve_fmul_d_aarch64eb +#define helper_sve_fmul_h helper_sve_fmul_h_aarch64eb +#define helper_sve_fmul_s helper_sve_fmul_s_aarch64eb +#define helper_sve_fmulx_d helper_sve_fmulx_d_aarch64eb +#define helper_sve_fmulx_h helper_sve_fmulx_h_aarch64eb +#define helper_sve_fmulx_s helper_sve_fmulx_s_aarch64eb #define helper_sve_fneg_d helper_sve_fneg_d_aarch64eb #define helper_sve_fneg_h helper_sve_fneg_h_aarch64eb #define helper_sve_fneg_s helper_sve_fneg_s_aarch64eb +#define helper_sve_fscalbn_d helper_sve_fscalbn_d_aarch64eb +#define helper_sve_fscalbn_h helper_sve_fscalbn_h_aarch64eb +#define helper_sve_fscalbn_s helper_sve_fscalbn_s_aarch64eb +#define helper_sve_fsub_d helper_sve_fsub_d_aarch64eb +#define helper_sve_fsub_h helper_sve_fsub_h_aarch64eb +#define helper_sve_fsub_s helper_sve_fsub_s_aarch64eb #define helper_sve_ftssel_d helper_sve_ftssel_d_aarch64eb #define helper_sve_ftssel_h helper_sve_ftssel_h_aarch64eb #define helper_sve_ftssel_s helper_sve_ftssel_s_aarch64eb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index c37eda4c..fadf42e9 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -3516,15 +3516,48 @@ aarch64_symbols = ( 'helper_sve_eorv_h', 'helper_sve_eorv_s', 'helper_sve_ext', + 'helper_sve_fabd_d', + 'helper_sve_fabd_h', + 'helper_sve_fabd_s', 'helper_sve_fabs_d', 'helper_sve_fabs_h', 'helper_sve_fabs_s', + 'helper_sve_fadd_d', + 'helper_sve_fadd_h', + 'helper_sve_fadd_s', + 'helper_sve_fdiv_d', + 'helper_sve_fdiv_h', + 'helper_sve_fdiv_s', 'helper_sve_fexpa_d', 'helper_sve_fexpa_h', 'helper_sve_fexpa_s', + 'helper_sve_fmax_d', + 'helper_sve_fmax_h', + 'helper_sve_fmax_s', + 'helper_sve_fmaxnum_d', + 'helper_sve_fmaxnum_h', + 'helper_sve_fmaxnum_s', + 'helper_sve_fmin_d', + 'helper_sve_fmin_h', + 'helper_sve_fmin_s', + 'helper_sve_fminnum_d', + 'helper_sve_fminnum_h', + 'helper_sve_fminnum_s', + 'helper_sve_fmul_d', + 'helper_sve_fmul_h', + 'helper_sve_fmul_s', + 'helper_sve_fmulx_d', + 'helper_sve_fmulx_h', + 'helper_sve_fmulx_s', 'helper_sve_fneg_d', 'helper_sve_fneg_h', 'helper_sve_fneg_s', + 'helper_sve_fscalbn_d', + 'helper_sve_fscalbn_h', + 'helper_sve_fscalbn_s', + 'helper_sve_fsub_d', + 'helper_sve_fsub_h', + 'helper_sve_fsub_s', 'helper_sve_ftssel_d', 'helper_sve_ftssel_h', 'helper_sve_ftssel_s', diff --git a/qemu/target/arm/helper-sve.h b/qemu/target/arm/helper-sve.h index 185112e1..4097b55f 100644 --- a/qemu/target/arm/helper-sve.h +++ b/qemu/target/arm/helper-sve.h @@ -720,6 +720,83 @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG, DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fadd_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fadd_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fadd_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) + +DEF_HELPER_FLAGS_6(sve_fsub_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fsub_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fsub_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) + +DEF_HELPER_FLAGS_6(sve_fmul_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmul_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmul_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) + +DEF_HELPER_FLAGS_6(sve_fdiv_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fdiv_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fdiv_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) + +DEF_HELPER_FLAGS_6(sve_fmin_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmin_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmin_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) + +DEF_HELPER_FLAGS_6(sve_fmax_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmax_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmax_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) + +DEF_HELPER_FLAGS_6(sve_fminnum_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fminnum_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fminnum_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) + +DEF_HELPER_FLAGS_6(sve_fmaxnum_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmaxnum_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmaxnum_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) + +DEF_HELPER_FLAGS_6(sve_fabd_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fabd_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fabd_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) + +DEF_HELPER_FLAGS_6(sve_fscalbn_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fscalbn_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fscalbn_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) + +DEF_HELPER_FLAGS_6(sve_fmulx_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmulx_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmulx_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, ptr, ptr, i32) + DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG, diff --git a/qemu/target/arm/sve.decode b/qemu/target/arm/sve.decode index 2a6c7338..91988900 100644 --- a/qemu/target/arm/sve.decode +++ b/qemu/target/arm/sve.decode @@ -684,6 +684,23 @@ FTSMUL 01100101 .. 0 ..... 000 011 ..... ..... @rd_rn_rm FRECPS 01100101 .. 0 ..... 000 110 ..... ..... @rd_rn_rm FRSQRTS 01100101 .. 0 ..... 000 111 ..... ..... @rd_rn_rm +### SVE FP Arithmetic Predicated Group + +# SVE floating-point arithmetic (predicated) +FADD_zpzz 01100101 .. 00 0000 100 ... ..... ..... @rdn_pg_rm +FSUB_zpzz 01100101 .. 00 0001 100 ... ..... ..... @rdn_pg_rm +FMUL_zpzz 01100101 .. 00 0010 100 ... ..... ..... @rdn_pg_rm +FSUB_zpzz 01100101 .. 00 0011 100 ... ..... ..... @rdm_pg_rn # FSUBR +FMAXNM_zpzz 01100101 .. 00 0100 100 ... ..... ..... @rdn_pg_rm +FMINNM_zpzz 01100101 .. 00 0101 100 ... ..... ..... @rdn_pg_rm +FMAX_zpzz 01100101 .. 00 0110 100 ... ..... ..... @rdn_pg_rm +FMIN_zpzz 01100101 .. 00 0111 100 ... ..... ..... @rdn_pg_rm +FABD 01100101 .. 00 1000 100 ... ..... ..... @rdn_pg_rm +FSCALE 01100101 .. 00 1001 100 ... ..... ..... @rdn_pg_rm +FMULX 01100101 .. 00 1010 100 ... ..... ..... @rdn_pg_rm +FDIV 01100101 .. 00 1100 100 ... ..... ..... @rdm_pg_rn # FDIVR +FDIV 01100101 .. 00 1101 100 ... ..... ..... @rdn_pg_rm + ### SVE FP Unary Operations Predicated Group # SVE integer convert to floating-point diff --git a/qemu/target/arm/sve_helper.c b/qemu/target/arm/sve_helper.c index 16e452bb..fd2c6d8d 100644 --- a/qemu/target/arm/sve_helper.c +++ b/qemu/target/arm/sve_helper.c @@ -3331,6 +3331,95 @@ void HELPER(sve_st4dd_r)(CPUARMState *env, void *vg, } } +/* Fully general three-operand expander, controlled by a predicate, + * With the extra float_status parameter. + */ +#define DO_ZPZZ_FP(NAME, TYPE, H, OP) \ +void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, \ + void *status, uint32_t desc) \ +{ \ + intptr_t i = simd_oprsz(desc); \ + uint64_t *g = vg; \ + do { \ + uint64_t pg = g[(i - 1) >> 6]; \ + do { \ + i -= sizeof(TYPE); \ + if (likely((pg >> (i & 63)) & 1)) { \ + TYPE nn = *(TYPE *)(vn + H(i)); \ + TYPE mm = *(TYPE *)(vm + H(i)); \ + *(TYPE *)(vd + H(i)) = OP(nn, mm, status); \ + } \ + } while (i & 63); \ + } while (i != 0); \ +} + +DO_ZPZZ_FP(sve_fadd_h, uint16_t, H1_2, float16_add) +DO_ZPZZ_FP(sve_fadd_s, uint32_t, H1_4, float32_add) +DO_ZPZZ_FP(sve_fadd_d, uint64_t, , float64_add) + +DO_ZPZZ_FP(sve_fsub_h, uint16_t, H1_2, float16_sub) +DO_ZPZZ_FP(sve_fsub_s, uint32_t, H1_4, float32_sub) +DO_ZPZZ_FP(sve_fsub_d, uint64_t, , float64_sub) + +DO_ZPZZ_FP(sve_fmul_h, uint16_t, H1_2, float16_mul) +DO_ZPZZ_FP(sve_fmul_s, uint32_t, H1_4, float32_mul) +DO_ZPZZ_FP(sve_fmul_d, uint64_t, , float64_mul) + +DO_ZPZZ_FP(sve_fdiv_h, uint16_t, H1_2, float16_div) +DO_ZPZZ_FP(sve_fdiv_s, uint32_t, H1_4, float32_div) +DO_ZPZZ_FP(sve_fdiv_d, uint64_t, , float64_div) + +DO_ZPZZ_FP(sve_fmin_h, uint16_t, H1_2, float16_min) +DO_ZPZZ_FP(sve_fmin_s, uint32_t, H1_4, float32_min) +DO_ZPZZ_FP(sve_fmin_d, uint64_t, , float64_min) + +DO_ZPZZ_FP(sve_fmax_h, uint16_t, H1_2, float16_max) +DO_ZPZZ_FP(sve_fmax_s, uint32_t, H1_4, float32_max) +DO_ZPZZ_FP(sve_fmax_d, uint64_t, , float64_max) + +DO_ZPZZ_FP(sve_fminnum_h, uint16_t, H1_2, float16_minnum) +DO_ZPZZ_FP(sve_fminnum_s, uint32_t, H1_4, float32_minnum) +DO_ZPZZ_FP(sve_fminnum_d, uint64_t, , float64_minnum) + +DO_ZPZZ_FP(sve_fmaxnum_h, uint16_t, H1_2, float16_maxnum) +DO_ZPZZ_FP(sve_fmaxnum_s, uint32_t, H1_4, float32_maxnum) +DO_ZPZZ_FP(sve_fmaxnum_d, uint64_t, , float64_maxnum) + +static inline float16 abd_h(float16 a, float16 b, float_status *s) +{ + return float16_abs(float16_sub(a, b, s)); +} + +static inline float32 abd_s(float32 a, float32 b, float_status *s) +{ + return float32_abs(float32_sub(a, b, s)); +} + +static inline float64 abd_d(float64 a, float64 b, float_status *s) +{ + return float64_abs(float64_sub(a, b, s)); +} + +DO_ZPZZ_FP(sve_fabd_h, uint16_t, H1_2, abd_h) +DO_ZPZZ_FP(sve_fabd_s, uint32_t, H1_4, abd_s) +DO_ZPZZ_FP(sve_fabd_d, uint64_t, , abd_d) + +static inline float64 scalbn_d(float64 a, int64_t b, float_status *s) +{ + int b_int = MIN(MAX(b, INT_MIN), INT_MAX); + return float64_scalbn(a, b_int, s); +} + +DO_ZPZZ_FP(sve_fscalbn_h, int16_t, H1_2, float16_scalbn) +DO_ZPZZ_FP(sve_fscalbn_s, int32_t, H1_4, float32_scalbn) +DO_ZPZZ_FP(sve_fscalbn_d, int64_t, , scalbn_d) + +DO_ZPZZ_FP(sve_fmulx_h, uint16_t, H1_2, helper_advsimd_mulxh) +DO_ZPZZ_FP(sve_fmulx_s, uint32_t, H1_4, helper_vfp_mulxs) +DO_ZPZZ_FP(sve_fmulx_d, uint64_t, , helper_vfp_mulxd) + +#undef DO_ZPZZ_FP + /* Fully general two-operand expander, controlled by a predicate, * With the extra float_status parameter. */ diff --git a/qemu/target/arm/translate-sve.c b/qemu/target/arm/translate-sve.c index 6dae90f7..7aa9641c 100644 --- a/qemu/target/arm/translate-sve.c +++ b/qemu/target/arm/translate-sve.c @@ -3567,6 +3567,54 @@ DO_FP3(FRSQRTS, rsqrts) #undef DO_FP3 +/* + *** SVE Floating Point Arithmetic - Predicated Group + */ + +static bool do_zpzz_fp(DisasContext *s, arg_rprr_esz *a, + gen_helper_gvec_4_ptr *fn) +{ + if (fn == NULL) { + return false; + } + if (sve_access_check(s)) { + TCGContext *tcg_ctx = s->uc->tcg_ctx; + unsigned vsz = vec_full_reg_size(s); + TCGv_ptr status = get_fpstatus_ptr(tcg_ctx, a->esz == MO_16); + tcg_gen_gvec_4_ptr(tcg_ctx, vec_full_reg_offset(s, a->rd), + vec_full_reg_offset(s, a->rn), + vec_full_reg_offset(s, a->rm), + pred_full_reg_offset(s, a->pg), + status, vsz, vsz, 0, fn); + tcg_temp_free_ptr(tcg_ctx, status); + } + return true; +} + +#define DO_FP3(NAME, name) \ +static bool trans_##NAME(DisasContext *s, arg_rprr_esz *a, uint32_t insn) \ +{ \ + static gen_helper_gvec_4_ptr * const fns[4] = { \ + NULL, gen_helper_sve_##name##_h, \ + gen_helper_sve_##name##_s, gen_helper_sve_##name##_d \ + }; \ + return do_zpzz_fp(s, a, fns[a->esz]); \ +} + +DO_FP3(FADD_zpzz, fadd) +DO_FP3(FSUB_zpzz, fsub) +DO_FP3(FMUL_zpzz, fmul) +DO_FP3(FMIN_zpzz, fmin) +DO_FP3(FMAX_zpzz, fmax) +DO_FP3(FMINNM_zpzz, fminnum) +DO_FP3(FMAXNM_zpzz, fmaxnum) +DO_FP3(FABD, fabd) +DO_FP3(FSCALE, fscalbn) +DO_FP3(FDIV, fdiv) +DO_FP3(FMULX, fmulx) + +#undef DO_FP3 + /* *** SVE Floating Point Unary Operations Predicated Group */