@samitouri / QOSamiQemu / commits / 467e3d1e42

target/arm: Implement LUTI4 (four registers, 8-bit)

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

Richard Henderson committed Jun 9, 2026 at 12:20 UTC 467e3d1e422df7f08c70e4be6b12e932b50afa59
5 files changed +32
target/arm/cpu-features.h
+5
@@ -1668,6 +1668,11 @@ static inline bool isar_feature_aa64_sme2_f8cvt(const ARMISARegisters *id)
1668 return isar_feature_aa64_sme2(id) && isar_feature_aa64_f8cvt(id);
1669 }
1670
1671 +static inline bool isar_feature_aa64_sme2p1_lutv2(const ARMISARegisters *id)
1672 +{
1673 + return isar_feature_aa64_sme2p1(id) && isar_feature_aa64_sme_lutv2(id);
1674 +}
1675 +
1676 static inline bool isar_feature_aa64_sve_i8mm(const ARMISARegisters *id)
1677 {
1678 return isar_feature_aa64_sve(id) && isar_feature_aa64_sme_sve_i8mm(id);
target/arm/tcg/helper-defs.h
+1
@@ -1120,6 +1120,7 @@ DEF_HELPER_FLAGS_4(sme2_luti4_2b, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
1120 DEF_HELPER_FLAGS_4(sme2_luti4_2h, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
1121 DEF_HELPER_FLAGS_4(sme2_luti4_2s, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
1122
1123 +DEF_HELPER_FLAGS_4(sme2_luti4_4b, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
1124 DEF_HELPER_FLAGS_4(sme2_luti4_4h, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
1125 DEF_HELPER_FLAGS_4(sme2_luti4_4s, TCG_CALL_NO_RWG, void, ptr, ptr, env, i32)
1126
target/arm/tcg/sme.decode
+6
@@ -1014,8 +1014,14 @@ LUTI4_c_2s 1100 0000 1000 101 idx:2 1 10 00 zn:5 .... 0 &lut zd=%zd_ax2
1014 LUTI4_c_4h 1100 0000 1000 101 idx:1 10 01 00 zn:5 ... 00 &lut zd=%zd_ax4
1015 LUTI4_c_4s 1100 0000 1000 101 idx:1 10 10 00 zn:5 ... 00 &lut zd=%zd_ax4
1016
1017 +LUTI4_c_4b 1100 0000 1000 101 1 00 00 00 ....0 ...00 \
1018 + &lut zd=%zd_ax4 zn=%zn_ax2 idx=0
1019 +
1020 # LUTI4, strided (must check zd alignment)
1021 LUTI4_s_2b 1100 0000 1001 101 idx:2 1 00 00 zn:5 zd:5 &lut
1022 LUTI4_s_2h 1100 0000 1001 101 idx:2 1 01 00 zn:5 zd:5 &lut
1023
1024 LUTI4_s_4h 1100 0000 1001 101 idx:1 10 01 00 zn:5 zd:5 &lut
1025 +
1026 +LUTI4_s_4b 1100 0000 1001 101 1 00 00 00 ....0 zd:5 \
1027 + &lut zn=%zn_ax2 idx=0
target/arm/tcg/translate-sme.c
+6
@@ -1846,6 +1846,9 @@ TRANS_FEAT(LUTI4_c_2s, aa64_sme2, do_lut, a, gen_helper_sme2_luti4_2s, false)
1846 TRANS_FEAT(LUTI4_c_4h, aa64_sme2, do_lut, a, gen_helper_sme2_luti4_4h, false)
1847 TRANS_FEAT(LUTI4_c_4s, aa64_sme2, do_lut, a, gen_helper_sme2_luti4_4s, false)
1848
1849 +TRANS_FEAT(LUTI4_c_4b, aa64_sme_lutv2, do_lut, a,
1850 + gen_helper_sme2_luti4_4b, false)
1851 +
1852 static bool do_lut_s4(DisasContext *s, arg_lut *a, gen_helper_gvec_2_ptr *fn)
1853 {
1854 return !(a->zd & 0b01100) && do_lut(s, a, fn, true);
@@ -1866,3 +1869,6 @@ TRANS_FEAT(LUTI4_s_2b, aa64_sme2p1, do_lut_s8, a, gen_helper_sme2_luti4_2b)
1869 TRANS_FEAT(LUTI4_s_2h, aa64_sme2p1, do_lut_s8, a, gen_helper_sme2_luti4_2h)
1870
1871 TRANS_FEAT(LUTI4_s_4h, aa64_sme2p1, do_lut_s4, a, gen_helper_sme2_luti4_4h)
1872 +
1873 +TRANS_FEAT(LUTI4_s_4b, aa64_sme2p1_lutv2, do_lut_s4, a,
1874 + gen_helper_sme2_luti4_4b)
target/arm/tcg/vec_helper.c
+14
@@ -3345,6 +3345,20 @@ DO_SME2_LUT(4,4,s, 4)
3345
3346 #undef DO_SME2_LUT
3347
3348 +void helper_sme2_luti4_4b(void *zd, void *zn, CPUARMState *env, uint32_t desc)
3349 +{
3350 + unsigned vl = simd_oprsz(desc);
3351 + unsigned strided = extract32(desc, SIMD_DATA_SHIFT, 1);
3352 + unsigned dstride = !strided ? 1 : 4;
3353 + uint64_t indexes[ARM_MAX_VQ * 4];
3354 +
3355 + memcpy(&indexes, zn, vl);
3356 + memcpy((void *)&indexes + vl, zn + sizeof(ARMVectorReg), vl);
3357 +
3358 + do_lut_b(zd, indexes, (void *)env->za_state.zt0, vl, 0,
3359 + dstride * sizeof(ARMVectorReg), 4, 32, 4);
3360 +}
3361 +
3362 void HELPER(gvec_luti2_b)(void *vd, void *vn, void *vm, uint32_t desc)
3363 {
3364 unsigned part = simd_data(desc);