diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 7d4d0fc5..8c786b33 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -3507,6 +3507,9 @@ #define helper_sve_fadda_d helper_sve_fadda_d_aarch64 #define helper_sve_fadda_h helper_sve_fadda_h_aarch64 #define helper_sve_fadda_s helper_sve_fadda_s_aarch64 +#define helper_sve_fadds_d helper_sve_fadds_d_aarch64 +#define helper_sve_fadds_h helper_sve_fadds_h_aarch64 +#define helper_sve_fadds_s helper_sve_fadds_s_aarch64 #define helper_sve_facge_d helper_sve_facge_d_aarch64 #define helper_sve_facge_h helper_sve_facge_h_aarch64 #define helper_sve_facge_s helper_sve_facge_s_aarch64 @@ -3537,12 +3540,24 @@ #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_fmaxs_d helper_sve_fmaxs_d_aarch64 +#define helper_sve_fmaxs_h helper_sve_fmaxs_h_aarch64 +#define helper_sve_fmaxs_s helper_sve_fmaxs_s_aarch64 +#define helper_sve_fmaxnms_d helper_sve_fmaxnms_d_aarch64 +#define helper_sve_fmaxnms_h helper_sve_fmaxnms_h_aarch64 +#define helper_sve_fmaxnms_s helper_sve_fmaxnms_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_fmins_d helper_sve_fmins_d_aarch64 +#define helper_sve_fmins_h helper_sve_fmins_h_aarch64 +#define helper_sve_fmins_s helper_sve_fmins_s_aarch64 +#define helper_sve_fminnms_d helper_sve_fminnms_d_aarch64 +#define helper_sve_fminnms_h helper_sve_fminnms_h_aarch64 +#define helper_sve_fminnms_s helper_sve_fminnms_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 @@ -3555,6 +3570,9 @@ #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_fmuls_d helper_sve_fmuls_d_aarch64 +#define helper_sve_fmuls_h helper_sve_fmuls_h_aarch64 +#define helper_sve_fmuls_s helper_sve_fmuls_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 @@ -3573,6 +3591,12 @@ #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_fsubrs_d helper_sve_fsubrs_d_aarch64 +#define helper_sve_fsubrs_h helper_sve_fsubrs_h_aarch64 +#define helper_sve_fsubrs_s helper_sve_fsubrs_s_aarch64 +#define helper_sve_fsubs_d helper_sve_fsubs_d_aarch64 +#define helper_sve_fsubs_h helper_sve_fsubs_h_aarch64 +#define helper_sve_fsubs_s helper_sve_fsubs_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 acac3d83..3859d86d 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -3507,6 +3507,9 @@ #define helper_sve_fadda_d helper_sve_fadda_d_aarch64eb #define helper_sve_fadda_h helper_sve_fadda_h_aarch64eb #define helper_sve_fadda_s helper_sve_fadda_s_aarch64eb +#define helper_sve_fadds_d helper_sve_fadds_d_aarch64eb +#define helper_sve_fadds_h helper_sve_fadds_h_aarch64eb +#define helper_sve_fadds_s helper_sve_fadds_s_aarch64eb #define helper_sve_facge_d helper_sve_facge_d_aarch64eb #define helper_sve_facge_h helper_sve_facge_h_aarch64eb #define helper_sve_facge_s helper_sve_facge_s_aarch64eb @@ -3537,12 +3540,24 @@ #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_fmaxs_d helper_sve_fmaxs_d_aarch64eb +#define helper_sve_fmaxs_h helper_sve_fmaxs_h_aarch64eb +#define helper_sve_fmaxs_s helper_sve_fmaxs_s_aarch64eb +#define helper_sve_fmaxnms_d helper_sve_fmaxnms_d_aarch64eb +#define helper_sve_fmaxnms_h helper_sve_fmaxnms_h_aarch64eb +#define helper_sve_fmaxnms_s helper_sve_fmaxnms_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_fmins_d helper_sve_fmins_d_aarch64eb +#define helper_sve_fmins_h helper_sve_fmins_h_aarch64eb +#define helper_sve_fmins_s helper_sve_fmins_s_aarch64eb +#define helper_sve_fminnms_d helper_sve_fminnms_d_aarch64eb +#define helper_sve_fminnms_h helper_sve_fminnms_h_aarch64eb +#define helper_sve_fminnms_s helper_sve_fminnms_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 @@ -3555,6 +3570,9 @@ #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_fmuls_d helper_sve_fmuls_d_aarch64eb +#define helper_sve_fmuls_h helper_sve_fmuls_h_aarch64eb +#define helper_sve_fmuls_s helper_sve_fmuls_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 @@ -3573,6 +3591,12 @@ #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_fsubrs_d helper_sve_fsubrs_d_aarch64eb +#define helper_sve_fsubrs_h helper_sve_fsubrs_h_aarch64eb +#define helper_sve_fsubrs_s helper_sve_fsubrs_s_aarch64eb +#define helper_sve_fsubs_d helper_sve_fsubs_d_aarch64eb +#define helper_sve_fsubs_h helper_sve_fsubs_h_aarch64eb +#define helper_sve_fsubs_s helper_sve_fsubs_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 d0ca7a81..b87857ad 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -3528,6 +3528,9 @@ aarch64_symbols = ( 'helper_sve_fadda_d', 'helper_sve_fadda_h', 'helper_sve_fadda_s', + 'helper_sve_fadds_d', + 'helper_sve_fadds_h', + 'helper_sve_fadds_s', 'helper_sve_facge_d', 'helper_sve_facge_h', 'helper_sve_facge_s', @@ -3558,12 +3561,24 @@ aarch64_symbols = ( 'helper_sve_fmax_d', 'helper_sve_fmax_h', 'helper_sve_fmax_s', + 'helper_sve_fmaxs_d', + 'helper_sve_fmaxs_h', + 'helper_sve_fmaxs_s', + 'helper_sve_fmaxnms_d', + 'helper_sve_fmaxnms_h', + 'helper_sve_fmaxnms_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_fmins_d', + 'helper_sve_fmins_h', + 'helper_sve_fmins_s', + 'helper_sve_fminnms_d', + 'helper_sve_fminnms_h', + 'helper_sve_fminnms_s', 'helper_sve_fminnum_d', 'helper_sve_fminnum_h', 'helper_sve_fminnum_s', @@ -3576,6 +3591,9 @@ aarch64_symbols = ( 'helper_sve_fmul_d', 'helper_sve_fmul_h', 'helper_sve_fmul_s', + 'helper_sve_fmuls_d', + 'helper_sve_fmuls_h', + 'helper_sve_fmuls_s', 'helper_sve_fmulx_d', 'helper_sve_fmulx_h', 'helper_sve_fmulx_s', @@ -3594,6 +3612,12 @@ aarch64_symbols = ( 'helper_sve_fsub_d', 'helper_sve_fsub_h', 'helper_sve_fsub_s', + 'helper_sve_fsubrs_d', + 'helper_sve_fsubrs_h', + 'helper_sve_fsubrs_s', + 'helper_sve_fsubs_d', + 'helper_sve_fsubs_h', + 'helper_sve_fsubs_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 6089b3a5..087819ec 100644 --- a/qemu/target/arm/helper-sve.h +++ b/qemu/target/arm/helper-sve.h @@ -809,6 +809,62 @@ DEF_HELPER_FLAGS_6(sve_fmulx_s, TCG_CALL_NO_RWG, DEF_HELPER_FLAGS_6(sve_fmulx_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fadds_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fadds_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fadds_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) + +DEF_HELPER_FLAGS_6(sve_fsubs_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fsubs_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fsubs_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) + +DEF_HELPER_FLAGS_6(sve_fmuls_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmuls_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmuls_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) + +DEF_HELPER_FLAGS_6(sve_fsubrs_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fsubrs_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fsubrs_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) + +DEF_HELPER_FLAGS_6(sve_fmaxnms_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmaxnms_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmaxnms_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) + +DEF_HELPER_FLAGS_6(sve_fminnms_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fminnms_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fminnms_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) + +DEF_HELPER_FLAGS_6(sve_fmaxs_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmaxs_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmaxs_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) + +DEF_HELPER_FLAGS_6(sve_fmins_h, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmins_s, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, ptr, i32) +DEF_HELPER_FLAGS_6(sve_fmins_d, TCG_CALL_NO_RWG, + void, ptr, ptr, ptr, i64, 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 5ad20bea..27e9966e 100644 --- a/qemu/target/arm/sve.decode +++ b/qemu/target/arm/sve.decode @@ -160,6 +160,10 @@ @rdn_pg4 ........ esz:2 .. pg:4 ... ........ rd:5 \ &rpri_esz rn=%reg_movprfx +# Two register operand, one one-bit floating-point operand. +@rdn_i1 ........ esz:2 ......... pg:3 .... imm:1 rd:5 \ + &rpri_esz rn=%reg_movprfx + # Two register operand, one encoded bitmask. @rdn_dbm ........ .. .... dbm:13 rd:5 \ &rr_dbm rn=%reg_movprfx @@ -335,6 +339,16 @@ FCMUO_ppzz 01100101 .. 0 ..... 110 ... ..... 0 .... @pd_pg_rn_rm FACGE_ppzz 01100101 .. 0 ..... 110 ... ..... 1 .... @pd_pg_rn_rm FACGT_ppzz 01100101 .. 0 ..... 111 ... ..... 1 .... @pd_pg_rn_rm +# SVE floating-point arithmetic with immediate (predicated) +FADD_zpzi 01100101 .. 011 000 100 ... 0000 . ..... @rdn_i1 +FSUB_zpzi 01100101 .. 011 001 100 ... 0000 . ..... @rdn_i1 +FMUL_zpzi 01100101 .. 011 010 100 ... 0000 . ..... @rdn_i1 +FSUBR_zpzi 01100101 .. 011 011 100 ... 0000 . ..... @rdn_i1 +FMAXNM_zpzi 01100101 .. 011 100 100 ... 0000 . ..... @rdn_i1 +FMINNM_zpzi 01100101 .. 011 101 100 ... 0000 . ..... @rdn_i1 +FMAX_zpzi 01100101 .. 011 110 100 ... 0000 . ..... @rdn_i1 +FMIN_zpzi 01100101 .. 011 111 100 ... 0000 . ..... @rdn_i1 + ### SVE Integer Multiply-Add Group # SVE integer multiply-add writing addend (predicated) diff --git a/qemu/target/arm/sve_helper.c b/qemu/target/arm/sve_helper.c index 36e82516..6302def4 100644 --- a/qemu/target/arm/sve_helper.c +++ b/qemu/target/arm/sve_helper.c @@ -3737,6 +3737,75 @@ DO_ZPZZ_FP(sve_fmulx_d, uint64_t, , helper_vfp_mulxd) #undef DO_ZPZZ_FP +/* Three-operand expander, with one scalar operand, controlled by + * a predicate, with the extra float_status parameter. + */ +#define DO_ZPZS_FP(NAME, TYPE, H, OP) \ +void HELPER(NAME)(void *vd, void *vn, void *vg, uint64_t scalar, \ + void *status, uint32_t desc) \ +{ \ + intptr_t i = simd_oprsz(desc); \ + uint64_t *g = vg; \ + TYPE mm = scalar; \ + 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 *)(vd + H(i)) = OP(nn, mm, status); \ + } \ + } while (i & 63); \ + } while (i != 0); \ +} + +DO_ZPZS_FP(sve_fadds_h, float16, H1_2, float16_add) +DO_ZPZS_FP(sve_fadds_s, float32, H1_4, float32_add) +DO_ZPZS_FP(sve_fadds_d, float64, , float64_add) + +DO_ZPZS_FP(sve_fsubs_h, float16, H1_2, float16_sub) +DO_ZPZS_FP(sve_fsubs_s, float32, H1_4, float32_sub) +DO_ZPZS_FP(sve_fsubs_d, float64, , float64_sub) + +DO_ZPZS_FP(sve_fmuls_h, float16, H1_2, float16_mul) +DO_ZPZS_FP(sve_fmuls_s, float32, H1_4, float32_mul) +DO_ZPZS_FP(sve_fmuls_d, float64, , float64_mul) + +static inline float16 subr_h(float16 a, float16 b, float_status *s) +{ + return float16_sub(b, a, s); +} + +static inline float32 subr_s(float32 a, float32 b, float_status *s) +{ + return float32_sub(b, a, s); +} + +static inline float64 subr_d(float64 a, float64 b, float_status *s) +{ + return float64_sub(b, a, s); +} + +DO_ZPZS_FP(sve_fsubrs_h, float16, H1_2, subr_h) +DO_ZPZS_FP(sve_fsubrs_s, float32, H1_4, subr_s) +DO_ZPZS_FP(sve_fsubrs_d, float64, , subr_d) + +DO_ZPZS_FP(sve_fmaxnms_h, float16, H1_2, float16_maxnum) +DO_ZPZS_FP(sve_fmaxnms_s, float32, H1_4, float32_maxnum) +DO_ZPZS_FP(sve_fmaxnms_d, float64, , float64_maxnum) + +DO_ZPZS_FP(sve_fminnms_h, float16, H1_2, float16_minnum) +DO_ZPZS_FP(sve_fminnms_s, float32, H1_4, float32_minnum) +DO_ZPZS_FP(sve_fminnms_d, float64, , float64_minnum) + +DO_ZPZS_FP(sve_fmaxs_h, float16, H1_2, float16_max) +DO_ZPZS_FP(sve_fmaxs_s, float32, H1_4, float32_max) +DO_ZPZS_FP(sve_fmaxs_d, float64, , float64_max) + +DO_ZPZS_FP(sve_fmins_h, float16, H1_2, float16_min) +DO_ZPZS_FP(sve_fmins_s, float32, H1_4, float32_min) +DO_ZPZS_FP(sve_fmins_d, float64, , float64_min) + /* 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 c0d5f662..19e917d4 100644 --- a/qemu/target/arm/translate-sve.c +++ b/qemu/target/arm/translate-sve.c @@ -29,6 +29,7 @@ #include "exec/helper-proto.h" #include "exec/helper-gen.h" #include "translate-a64.h" +#include "fpu/softfloat.h" typedef void GVecGen2sFn(TCGContext *, unsigned, uint32_t, uint32_t, TCGv_i64, uint32_t, uint32_t); @@ -3679,6 +3680,82 @@ DO_FP3(FMULX, fmulx) #undef DO_FP3 +typedef void gen_helper_sve_fp2scalar(TCGContext *, TCGv_ptr, TCGv_ptr, TCGv_ptr, + TCGv_i64, TCGv_ptr, TCGv_i32); + +static void do_fp_scalar(DisasContext *s, int zd, int zn, int pg, bool is_fp16, + TCGv_i64 scalar, gen_helper_sve_fp2scalar *fn) +{ + TCGContext *tcg_ctx = s->uc->tcg_ctx; + unsigned vsz = vec_full_reg_size(s); + TCGv_ptr t_zd, t_zn, t_pg, status; + TCGv_i32 desc; + + t_zd = tcg_temp_new_ptr(tcg_ctx); + t_zn = tcg_temp_new_ptr(tcg_ctx); + t_pg = tcg_temp_new_ptr(tcg_ctx); + tcg_gen_addi_ptr(tcg_ctx, t_zd, tcg_ctx->cpu_env, vec_full_reg_offset(s, zd)); + tcg_gen_addi_ptr(tcg_ctx, t_zn, tcg_ctx->cpu_env, vec_full_reg_offset(s, zn)); + tcg_gen_addi_ptr(tcg_ctx, t_pg, tcg_ctx->cpu_env, pred_full_reg_offset(s, pg)); + + status = get_fpstatus_ptr(tcg_ctx, is_fp16); + desc = tcg_const_i32(tcg_ctx, simd_desc(vsz, vsz, 0)); + fn(tcg_ctx, t_zd, t_zn, t_pg, scalar, status, desc); + + tcg_temp_free_i32(tcg_ctx, desc); + tcg_temp_free_ptr(tcg_ctx, status); + tcg_temp_free_ptr(tcg_ctx, t_pg); + tcg_temp_free_ptr(tcg_ctx, t_zn); + tcg_temp_free_ptr(tcg_ctx, t_zd); +} + +static void do_fp_imm(DisasContext *s, arg_rpri_esz *a, uint64_t imm, + gen_helper_sve_fp2scalar *fn) +{ + TCGContext *tcg_ctx = s->uc->tcg_ctx; + TCGv_i64 temp = tcg_const_i64(tcg_ctx, imm); + do_fp_scalar(s, a->rd, a->rn, a->pg, a->esz == MO_16, temp, fn); + tcg_temp_free_i64(tcg_ctx, temp); +} + +#define DO_FP_IMM(NAME, name, const0, const1) \ +static bool trans_##NAME##_zpzi(DisasContext *s, arg_rpri_esz *a, \ + uint32_t insn) \ +{ \ + static gen_helper_sve_fp2scalar * const fns[3] = { \ + gen_helper_sve_##name##_h, \ + gen_helper_sve_##name##_s, \ + gen_helper_sve_##name##_d \ + }; \ + static uint64_t const val[3][2] = { \ + { float16_##const0, float16_##const1 }, \ + { float32_##const0, float32_##const1 }, \ + { float64_##const0, float64_##const1 }, \ + }; \ + if (a->esz == 0) { \ + return false; \ + } \ + if (sve_access_check(s)) { \ + do_fp_imm(s, a, val[a->esz - 1][a->imm], fns[a->esz - 1]); \ + } \ + return true; \ +} + +#define float16_two make_float16(0x4000) +#define float32_two make_float32(0x40000000) +#define float64_two make_float64(0x4000000000000000ULL) + +DO_FP_IMM(FADD, fadds, half, one) +DO_FP_IMM(FSUB, fsubs, half, one) +DO_FP_IMM(FMUL, fmuls, half, two) +DO_FP_IMM(FSUBR, fsubrs, half, one) +DO_FP_IMM(FMAXNM, fmaxnms, zero, one) +DO_FP_IMM(FMINNM, fminnms, zero, one) +DO_FP_IMM(FMAX, fmaxs, zero, one) +DO_FP_IMM(FMIN, fmins, zero, one) + +#undef DO_FP_IMM + static bool do_fp_cmp(DisasContext *s, arg_rprr_esz *a, gen_helper_gvec_4_ptr *fn) {