Browse Source

target/arm: Implement SME2 FCLAMP, SCLAMP, UCLAMP

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250704142112.1018902-67-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
pull/294/head
Richard Henderson 1 year ago
committed by Peter Maydell
parent
commit
8b61eff8e7
  1. 15
      target/arm/tcg/helper-sme.h
  2. 17
      target/arm/tcg/sme.decode
  3. 56
      target/arm/tcg/sme_helper.c
  4. 75
      target/arm/tcg/translate-sme.c

15
target/arm/tcg/helper-sme.h

@ -298,3 +298,18 @@ DEF_HELPER_FLAGS_3(sme2_sqrshrun_sb, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(sme2_sqrshrn_dh, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(sme2_uqrshrn_dh, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(sme2_sqrshrun_dh, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(sme2_sclamp_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(sme2_sclamp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(sme2_sclamp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(sme2_sclamp_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(sme2_uclamp_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(sme2_uclamp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(sme2_uclamp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(sme2_uclamp_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(sme2_fclamp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
DEF_HELPER_FLAGS_5(sme2_fclamp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
DEF_HELPER_FLAGS_5(sme2_fclamp_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
DEF_HELPER_FLAGS_5(sme2_bfclamp, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)

17
target/arm/tcg/sme.decode

@ -860,3 +860,20 @@ UZP_2 11000001 esz:2 1 zm:5 110100 zn:5 .... 1 \
&zzz_e zd=%zd_ax2
UZP_2 11000001 00 1 zm:5 110101 zn:5 .... 1 \
&zzz_e zd=%zd_ax2 esz=4
&zzz_en zd zn zm esz n
FCLAMP 11000001 esz:2 1 zm:5 110000 zn:5 .... 0 \
&zzz_en zd=%zd_ax2 n=2
FCLAMP 11000001 esz:2 1 zm:5 110010 zn:5 ...0 0 \
&zzz_en zd=%zd_ax4 n=4
SCLAMP 11000001 esz:2 1 zm:5 110001 zn:5 .... 0 \
&zzz_en zd=%zd_ax2 n=2
SCLAMP 11000001 esz:2 1 zm:5 110011 zn:5 ...0 0 \
&zzz_en zd=%zd_ax4 n=4
UCLAMP 11000001 esz:2 1 zm:5 110001 zn:5 .... 1 \
&zzz_en zd=%zd_ax2 n=2
UCLAMP 11000001 esz:2 1 zm:5 110011 zn:5 ...0 1 \
&zzz_en zd=%zd_ax4 n=4

56
target/arm/tcg/sme_helper.c

@ -2062,3 +2062,59 @@ UZP4(sme2_uzp4_d, uint64_t, )
UZP4(sme2_uzp4_q, Int128, )
#undef UZP4
#define ICLAMP(NAME, TYPE, H) \
void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
{ \
size_t stride = sizeof(ARMVectorReg) / sizeof(TYPE); \
size_t elements = simd_oprsz(desc) / sizeof(TYPE); \
size_t nreg = simd_data(desc); \
TYPE *d = vd, *n = vn, *m = vm; \
for (size_t e = 0; e < elements; e++) { \
TYPE nn = n[H(e)], mm = m[H(e)]; \
for (size_t r = 0; r < nreg; r++) { \
TYPE *dd = &d[r * stride + H(e)]; \
*dd = MIN(MAX(*dd, nn), mm); \
} \
} \
}
ICLAMP(sme2_sclamp_b, int8_t, H1)
ICLAMP(sme2_sclamp_h, int16_t, H2)
ICLAMP(sme2_sclamp_s, int32_t, H4)
ICLAMP(sme2_sclamp_d, int64_t, H8)
ICLAMP(sme2_uclamp_b, uint8_t, H1)
ICLAMP(sme2_uclamp_h, uint16_t, H2)
ICLAMP(sme2_uclamp_s, uint32_t, H4)
ICLAMP(sme2_uclamp_d, uint64_t, H8)
#undef ICLAMP
/*
* Note the argument ordering to minnum and maxnum must match
* the ARM pseudocode so that NaNs are propagated properly.
*/
#define FCLAMP(NAME, TYPE, H) \
void HELPER(NAME)(void *vd, void *vn, void *vm, \
float_status *fpst, uint32_t desc) \
{ \
size_t stride = sizeof(ARMVectorReg) / sizeof(TYPE); \
size_t elements = simd_oprsz(desc) / sizeof(TYPE); \
size_t nreg = simd_data(desc); \
TYPE *d = vd, *n = vn, *m = vm; \
for (size_t e = 0; e < elements; e++) { \
TYPE nn = n[H(e)], mm = m[H(e)]; \
for (size_t r = 0; r < nreg; r++) { \
TYPE *dd = &d[r * stride + H(e)]; \
*dd = TYPE##_minnum(TYPE##_maxnum(nn, *dd, fpst), mm, fpst); \
} \
} \
}
FCLAMP(sme2_fclamp_h, float16, H2)
FCLAMP(sme2_fclamp_s, float32, H4)
FCLAMP(sme2_fclamp_d, float64, H8)
FCLAMP(sme2_bfclamp, bfloat16, H2)
#undef FCLAMP

75
target/arm/tcg/translate-sme.c

@ -1547,3 +1547,78 @@ static gen_helper_gvec_3 * const uzp2_fns[] = {
gen_helper_sme2_uzp2_q,
};
TRANS_FEAT(UZP_2, aa64_sme2, do_zipuzp_2, a, uzp2_fns)
static bool trans_FCLAMP(DisasContext *s, arg_zzz_en *a)
{
static gen_helper_gvec_3_ptr * const fn[] = {
gen_helper_sme2_bfclamp,
gen_helper_sme2_fclamp_h,
gen_helper_sme2_fclamp_s,
gen_helper_sme2_fclamp_d,
};
TCGv_ptr fpst;
int vl;
if (!dc_isar_feature(aa64_sme2, s)) {
return false;
}
/* This insn uses MO_8 to encode BFloat16. */
if (a->esz == MO_8 && !dc_isar_feature(aa64_sme_b16b16, s)) {
return false;
}
if (!sme_sm_enabled_check(s)) {
return true;
}
fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_A64_F16 : FPST_A64);
vl = vec_full_reg_size(s);
tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->zd),
vec_full_reg_offset(s, a->zn),
vec_full_reg_offset(s, a->zm),
fpst, vl, vl, a->n, fn[a->esz]);
return true;
}
static bool do_clamp(DisasContext *s, arg_zzz_en *a,
gen_helper_gvec_3 * const fn[4])
{
int vl;
if (!dc_isar_feature(aa64_sme2, s)) {
return false;
}
if (!sme_sm_enabled_check(s)) {
return true;
}
/*
* Clamp is just a min+max, easily supported by most host
* vector operations -- we already have such an expansion in
* translate-sve.c for a single output.
* TODO: Add support in gvec for multiple simultaneous output,
* and/or copy to temporary upon overlap.
*/
vl = vec_full_reg_size(s);
tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->zd),
vec_full_reg_offset(s, a->zn),
vec_full_reg_offset(s, a->zm),
vl, vl, a->n, fn[a->esz]);
return true;
}
static gen_helper_gvec_3 * const sclamp_fns[] = {
gen_helper_sme2_sclamp_b,
gen_helper_sme2_sclamp_h,
gen_helper_sme2_sclamp_s,
gen_helper_sme2_sclamp_d,
};
TRANS(SCLAMP, do_clamp, a, sclamp_fns)
static gen_helper_gvec_3 * const uclamp_fns[] = {
gen_helper_sme2_uclamp_b,
gen_helper_sme2_uclamp_h,
gen_helper_sme2_uclamp_s,
gen_helper_sme2_uclamp_d,
};
TRANS(UCLAMP, do_clamp, a, uclamp_fns)

Loading…
Cancel
Save