Signed-off-by: Stephen Long <stepl...@quicinc.com> --- I made the changes Richard requested. I took out the status field for the helper function.
include/fpu/softfloat.h | 5 +++ target/arm/helper-sve.h | 4 +++ target/arm/sve.decode | 4 +++ target/arm/sve_helper.c | 63 ++++++++++++++++++++++++++++++++++++++ target/arm/translate-sve.c | 9 ++++++ 5 files changed, 85 insertions(+) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index ecb8ba0114..275d138145 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -260,6 +260,11 @@ static inline int float16_is_zero_or_denormal(float16 a) return (float16_val(a) & 0x7c00) == 0; } +static inline bool float16_is_normal(float16 a) +{ + return (((float16_val(a) >> 10) + 1) & 0x1f) >= 2; +} + static inline float16 float16_abs(float16 a) { /* Note that abs does *not* handle NaN specially, nor does diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h index 0a62eef94e..4a7b322f15 100644 --- a/target/arm/helper-sve.h +++ b/target/arm/helper-sve.h @@ -2731,3 +2731,7 @@ DEF_HELPER_FLAGS_5(sve2_sqrdcmlah_idx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) DEF_HELPER_FLAGS_5(sve2_sqrdcmlah_idx_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32) + +DEF_HELPER_FLAGS_4(flogb_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(flogb_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(flogb_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) diff --git a/target/arm/sve.decode b/target/arm/sve.decode index 3cf824bac5..dcb095bb5d 100644 --- a/target/arm/sve.decode +++ b/target/arm/sve.decode @@ -1568,3 +1568,7 @@ SM4E 01000101 00 10001 1 11100 0 ..... ..... @rdn_rm_e0 # SVE2 crypto constructive binary operations SM4EKEY 01000101 00 1 ..... 11110 0 ..... ..... @rd_rn_rm_e0 RAX1 01000101 00 1 ..... 11110 1 ..... ..... @rd_rn_rm_e0 + +### SVE2 floating-point convert to integer + +FLOGB 01100101 00 011 esz:2 0101 pg:3 rn:5 rd:5 &rpr_esz diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c index aa94df302a..33fea27cb7 100644 --- a/target/arm/sve_helper.c +++ b/target/arm/sve_helper.c @@ -7622,3 +7622,66 @@ void HELPER(fmmla_d)(void *vd, void *va, void *vn, void *vm, d[3] = float64_add(a[3], float64_add(p0, p1, status), status); } } + +#define DO_ZPZW_UNOP(NAME, TYPE, TYPEW, H, OP) \ +void HELPER(NAME)(void *vd, void *vn, void *vg, 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)); \ + *(TYPEW *)(vd + H(i)) = OP(nn); \ + } \ + } while (i & 63); \ + } while (i != 0); \ +} + +static int16_t do_float16_logb_as_int(float16 a) +{ + if (float16_is_normal(a)) { + return extract16(a, 10, 5) - 15; + } else if (float16_is_infinity(a)) { + return INT16_MAX; + } else if (float16_is_any_nan(a) || float16_is_zero(a)) { + return INT16_MIN; + } + // denormal + int shift = 6 - clz32(extract16(a, 0, 10)) - 16; + return -15 - shift + 1; +} + +static int32_t do_float32_logb_as_int(float32 a) +{ + if (float32_is_normal(a)) { + return extract32(a, 23, 8) - 127; + } else if (float32_is_infinity(a)) { + return INT32_MAX; + } else if (float32_is_any_nan(a) || float32_is_zero(a)) { + return INT32_MIN; + } + // denormal + int shift = 9 - clz32(extract32(a, 0, 23)); + return -127 - shift + 1; +} + +static int64_t do_float64_logb_as_int(float64 a) +{ + if (float64_is_normal(a)) { + return extract64(a, 52, 11) - 1023; + } else if (float64_is_infinity(a)) { + return INT64_MAX; + } else if (float64_is_any_nan(a) || float64_is_zero(a)) { + return INT64_MIN; + } + // denormal + int shift = 12 - clz64(extract64(a, 0, 52)); + return -1023 - shift + 1; +} + +DO_ZPZW_UNOP(flogb_h, float16, int16_t, H1_2, do_float16_logb_as_int) +DO_ZPZW_UNOP(flogb_s, float32, int32_t, H1_4, do_float32_logb_as_int) +DO_ZPZW_UNOP(flogb_d, float64, int64_t, , do_float64_logb_as_int) diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c index a8e57ea5f4..68157b892b 100644 --- a/target/arm/translate-sve.c +++ b/target/arm/translate-sve.c @@ -8253,3 +8253,12 @@ static bool trans_RAX1(DisasContext *s, arg_rrr_esz *a) } return true; } + +static bool trans_FLOGB(DisasContext *s, arg_rpr_esz *a) +{ + static gen_helper_gvec_3 * const fns[] = { + NULL, gen_helper_flogb_h, + gen_helper_flogb_s, gen_helper_flogb_d + }; + return do_sve2_zpz_ool(s, a, fns[a->esz - 1]); +} -- 2.17.1