@samitouri / QOSamiQemu / commits / a309e51cef

target/arm: Implement BF1CVT, BF1CVTLT, BF2CVT, BF2CVTLT for SVE

Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260609192110.752384-9-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Richard Henderson committed Jun 9, 2026 at 12:20 UTC a309e51cefce692d94c159aea5fc8377341825aa
5 files changed +52
target/arm/cpu-features.h
+6
@@ -1668,6 +1668,12 @@ isar_feature_aa64_sme2_or_sve2_faminmax(const ARMISARegisters *id)
1668 return isar_feature_aa64_sme2_or_sve2(id) && isar_feature_aa64_faminmax(id);
1669 }
1670
1671 +static inline bool
1672 +isar_feature_aa64_sme2_or_sve2_f8cvt(const ARMISARegisters *id)
1673 +{
1674 + return isar_feature_aa64_sme2_or_sve2(id) && isar_feature_aa64_f8cvt(id);
1675 +}
1676 +
1677 /*
1678 * Feature tests for "does this exist in either 32-bit or 64-bit?"
1679 */
target/arm/tcg/fp8_helper.c
+16
@@ -122,3 +122,19 @@ void HELPER(advsimd_bfcvtl)(void *vd, void *vn, CPUARMState *env, uint32_t desc)
122 fp8_cvt_finish(env, &ctx);
123 clear_tail(vd, 16, simd_maxsz(desc));
124 }
125 +
126 +void HELPER(sve2_bfcvt)(void *vd, void *vn, CPUARMState *env, uint32_t desc)
127 +{
128 + FP8Context ctx = fp8_src_start(env, desc, 0x3f);
129 + fp8_input_fn *input_fmt = fp8_input_fmt[ctx.f8fmt];
130 + uint8_t *n = vn;
131 + uint16_t *d = vd;
132 + size_t nelem = simd_oprsz(desc) / 2;
133 +
134 + for (size_t i = 0; i < nelem; ++i) {
135 + d[H2(i)] = fcvt_fp8_to_b16(n[H1(2 * i + ctx.high)],
136 + input_fmt, ctx.scale, &ctx.stat);
137 + }
138 +
139 + fp8_cvt_finish(env, &ctx);
140 +}
target/arm/tcg/helper-fp8-defs.h
+1
@@ -4,3 +4,4 @@
4 */
5
6 DEF_HELPER_FLAGS_4(advsimd_bfcvtl, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
7 +DEF_HELPER_FLAGS_4(sve2_bfcvt, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
target/arm/tcg/sve.decode
+6
@@ -108,6 +108,7 @@
108 # Two operand
109 @pd_pn ........ esz:2 .. .... ....... rn:4 . rd:4 &rr_esz
110 @rd_rn ........ esz:2 ...... ...... rn:5 rd:5 &rr_esz
111 +@rd_rn_e0 ........ .. ...... ...... rn:5 rd:5 &rr_esz esz=0
112 @rd_rnx2 ........ ... ..... ...... ..... rd:5 &rr_esz rn=%rn_ax2
113
114 # Two operand with governing predicate, flags setting
@@ -1090,6 +1091,11 @@ FMINQV 01100100 .. 010 111 101 ... ..... ..... @rd_pg_rn
1091 FRECPE 01100101 .. 001 110 001100 ..... ..... @rd_rn
1092 FRSQRTE 01100101 .. 001 111 001100 ..... ..... @rd_rn
1093
1094 +BF1CVT 01100101 00 001 000 001110 ..... ..... @rd_rn_e0
1095 +BF2CVT 01100101 00 001 000 001111 ..... ..... @rd_rn_e0
1096 +BF1CVTLT 01100101 00 001 001 001110 ..... ..... @rd_rn_e0
1097 +BF2CVTLT 01100101 00 001 001 001111 ..... ..... @rd_rn_e0
1098 +
1099 ### SVE FP Compare with Zero Group
1100
1101 FCMGE_ppz0 01100101 .. 0100 00 001 ... ..... 0 .... @pd_pg_rn
target/arm/tcg/translate-sve.c
+23
@@ -21,6 +21,7 @@
21 #include "cpu.h"
22 #include "helper-sme.h"
23 #include "helper-sve.h"
24 +#include "helper-fp8.h"
25 #include "translate.h"
26 #include "translate-a64.h"
27 #include "tcg/tcg-op.h"
@@ -4068,6 +4069,28 @@ TRANS_FEAT(FRSQRTE, aa64_sme_or_sve, gen_gvec_fpst_ah_arg_zz,
4069 s->fpcr_ah && dc_isar_feature(aa64_rpres, s) ?
4070 frsqrte_rpres_fns[a->esz] : frsqrte_fns[a->esz], a, 0)
4071
4072 +static bool do_f8cvt(DisasContext *s, arg_rr_esz *a,
4073 + gen_helper_gvec_2_ptr *fn, bool issrc2, bool isodd)
4074 +{
4075 + if (fpmr_access_check(s) && sve_access_check(s)) {
4076 + unsigned vsz = vec_full_reg_size(s);
4077 + tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, a->rd),
4078 + vec_full_reg_offset(s, a->rn),
4079 + tcg_env, vsz, vsz,
4080 + issrc2 | (isodd << 1) | (FPST_A64 << 2), fn);
4081 + }
4082 + return true;
4083 +}
4084 +
4085 +TRANS_FEAT_STREAMING_IF(BF1CVT, aa64_sme2_or_sve2_f8cvt, aa64_sme2,
4086 + do_f8cvt, a, gen_helper_sve2_bfcvt, false, false)
4087 +TRANS_FEAT_STREAMING_IF(BF2CVT, aa64_sme2_or_sve2_f8cvt, aa64_sme2,
4088 + do_f8cvt, a, gen_helper_sve2_bfcvt, true, false)
4089 +TRANS_FEAT_STREAMING_IF(BF1CVTLT, aa64_sme2_or_sve2_f8cvt, aa64_sme2,
4090 + do_f8cvt, a, gen_helper_sve2_bfcvt, false, true)
4091 +TRANS_FEAT_STREAMING_IF(BF2CVTLT, aa64_sme2_or_sve2_f8cvt, aa64_sme2,
4092 + do_f8cvt, a, gen_helper_sve2_bfcvt, true, true)
4093 +
4094 /*
4095 *** SVE Floating Point Compare with Zero Group
4096 */