target/arm: Implement SVE2 FLOGB
Signed-off-by: Stephen Long <steplong@quicinc.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20210525010358.152808-76-richard.henderson@linaro.org Message-Id: <20200430191405.21641-1-steplong@quicinc.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
9536527731
commit
631be02e29
@ -2754,3 +2754,7 @@ DEF_HELPER_FLAGS_5(sve2_fcvtlt_hs, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(sve2_fcvtlt_sd, TCG_CALL_NO_RWG,
|
||||
void, ptr, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_5(flogb_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(flogb_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_5(flogb_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
|
||||
|
@ -1588,3 +1588,6 @@ FCVTNT_sh 01100100 10 0010 00 101 ... ..... ..... @rd_pg_rn_e0
|
||||
FCVTLT_hs 01100100 10 0010 01 101 ... ..... ..... @rd_pg_rn_e0
|
||||
FCVTNT_ds 01100100 11 0010 10 101 ... ..... ..... @rd_pg_rn_e0
|
||||
FCVTLT_sd 01100100 11 0010 11 101 ... ..... ..... @rd_pg_rn_e0
|
||||
|
||||
### SVE2 floating-point convert to integer
|
||||
FLOGB 01100101 00 011 esz:2 0101 pg:3 rn:5 rd:5 &rpr_esz
|
||||
|
@ -4729,6 +4729,94 @@ DO_ZPZ_FP(sve_ucvt_dh, uint64_t, , uint64_to_float16)
|
||||
DO_ZPZ_FP(sve_ucvt_ds, uint64_t, , uint64_to_float32)
|
||||
DO_ZPZ_FP(sve_ucvt_dd, uint64_t, , uint64_to_float64)
|
||||
|
||||
static int16_t do_float16_logb_as_int(float16 a, float_status *s)
|
||||
{
|
||||
/* Extract frac to the top of the uint32_t. */
|
||||
uint32_t frac = (uint32_t)a << (16 + 6);
|
||||
int16_t exp = extract32(a, 10, 5);
|
||||
|
||||
if (unlikely(exp == 0)) {
|
||||
if (frac != 0) {
|
||||
if (!get_flush_inputs_to_zero(s)) {
|
||||
/* denormal: bias - fractional_zeros */
|
||||
return -15 - clz32(frac);
|
||||
}
|
||||
/* flush to zero */
|
||||
float_raise(float_flag_input_denormal, s);
|
||||
}
|
||||
} else if (unlikely(exp == 0x1f)) {
|
||||
if (frac == 0) {
|
||||
return INT16_MAX; /* infinity */
|
||||
}
|
||||
} else {
|
||||
/* normal: exp - bias */
|
||||
return exp - 15;
|
||||
}
|
||||
/* nan or zero */
|
||||
float_raise(float_flag_invalid, s);
|
||||
return INT16_MIN;
|
||||
}
|
||||
|
||||
static int32_t do_float32_logb_as_int(float32 a, float_status *s)
|
||||
{
|
||||
/* Extract frac to the top of the uint32_t. */
|
||||
uint32_t frac = a << 9;
|
||||
int32_t exp = extract32(a, 23, 8);
|
||||
|
||||
if (unlikely(exp == 0)) {
|
||||
if (frac != 0) {
|
||||
if (!get_flush_inputs_to_zero(s)) {
|
||||
/* denormal: bias - fractional_zeros */
|
||||
return -127 - clz32(frac);
|
||||
}
|
||||
/* flush to zero */
|
||||
float_raise(float_flag_input_denormal, s);
|
||||
}
|
||||
} else if (unlikely(exp == 0xff)) {
|
||||
if (frac == 0) {
|
||||
return INT32_MAX; /* infinity */
|
||||
}
|
||||
} else {
|
||||
/* normal: exp - bias */
|
||||
return exp - 127;
|
||||
}
|
||||
/* nan or zero */
|
||||
float_raise(float_flag_invalid, s);
|
||||
return INT32_MIN;
|
||||
}
|
||||
|
||||
static int64_t do_float64_logb_as_int(float64 a, float_status *s)
|
||||
{
|
||||
/* Extract frac to the top of the uint64_t. */
|
||||
uint64_t frac = a << 12;
|
||||
int64_t exp = extract64(a, 52, 11);
|
||||
|
||||
if (unlikely(exp == 0)) {
|
||||
if (frac != 0) {
|
||||
if (!get_flush_inputs_to_zero(s)) {
|
||||
/* denormal: bias - fractional_zeros */
|
||||
return -1023 - clz64(frac);
|
||||
}
|
||||
/* flush to zero */
|
||||
float_raise(float_flag_input_denormal, s);
|
||||
}
|
||||
} else if (unlikely(exp == 0x7ff)) {
|
||||
if (frac == 0) {
|
||||
return INT64_MAX; /* infinity */
|
||||
}
|
||||
} else {
|
||||
/* normal: exp - bias */
|
||||
return exp - 1023;
|
||||
}
|
||||
/* nan or zero */
|
||||
float_raise(float_flag_invalid, s);
|
||||
return INT64_MIN;
|
||||
}
|
||||
|
||||
DO_ZPZ_FP(flogb_h, float16, H1_2, do_float16_logb_as_int)
|
||||
DO_ZPZ_FP(flogb_s, float32, H1_4, do_float32_logb_as_int)
|
||||
DO_ZPZ_FP(flogb_d, float64, , do_float64_logb_as_int)
|
||||
|
||||
#undef DO_ZPZ_FP
|
||||
|
||||
static void do_fmla_zpzzz_h(void *vd, void *vn, void *vm, void *va, void *vg,
|
||||
|
@ -8307,3 +8307,27 @@ static bool trans_FCVTXNT_ds(DisasContext *s, arg_rpr_esz *a)
|
||||
}
|
||||
return do_frint_mode(s, a, float_round_to_odd, gen_helper_sve2_fcvtnt_ds);
|
||||
}
|
||||
|
||||
static bool trans_FLOGB(DisasContext *s, arg_rpr_esz *a)
|
||||
{
|
||||
static gen_helper_gvec_3_ptr * const fns[] = {
|
||||
NULL, gen_helper_flogb_h,
|
||||
gen_helper_flogb_s, gen_helper_flogb_d
|
||||
};
|
||||
|
||||
if (!dc_isar_feature(aa64_sve2, s) || fns[a->esz] == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (sve_access_check(s)) {
|
||||
TCGv_ptr status =
|
||||
fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
|
||||
unsigned vsz = vec_full_reg_size(s);
|
||||
|
||||
tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
|
||||
vec_full_reg_offset(s, a->rn),
|
||||
pred_full_reg_offset(s, a->pg),
|
||||
status, vsz, vsz, 0, fns[a->esz]);
|
||||
tcg_temp_free_ptr(status);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user