softfloat: Split float_to_float

Split out parts_float_to_ahp and parts_float_to_float.
Convert to pointers.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2020-11-13 17:43:41 -08:00
parent ec961b81b4
commit c3f1875ea3

View file

@ -2037,83 +2037,105 @@ float128_div(float128 a, float128 b, float_status *status)
* conversion is performed according to the IEC/IEEE Standard for * conversion is performed according to the IEC/IEEE Standard for
* Binary Floating-Point Arithmetic. * Binary Floating-Point Arithmetic.
* *
* The float_to_float helper only needs to take care of raising * Usually this only needs to take care of raising invalid exceptions
* invalid exceptions and handling the conversion on NaNs. * and handling the conversion on NaNs.
*/ */
static FloatParts64 float_to_float(FloatParts64 a, const FloatFmt *dstf, static void parts_float_to_ahp(FloatParts64 *a, float_status *s)
float_status *s)
{ {
if (dstf->arm_althp) { switch (a->cls) {
switch (a.cls) { case float_class_qnan:
case float_class_qnan: case float_class_snan:
case float_class_snan: /*
/* There is no NaN in the destination format. Raise Invalid * There is no NaN in the destination format. Raise Invalid
* and return a zero with the sign of the input NaN. * and return a zero with the sign of the input NaN.
*/ */
float_raise(float_flag_invalid, s); float_raise(float_flag_invalid, s);
a.cls = float_class_zero; a->cls = float_class_zero;
a.frac = 0; break;
a.exp = 0;
break;
case float_class_inf: case float_class_inf:
/* There is no Inf in the destination format. Raise Invalid /*
* and return the maximum normal with the correct sign. * There is no Inf in the destination format. Raise Invalid
*/ * and return the maximum normal with the correct sign.
float_raise(float_flag_invalid, s); */
a.cls = float_class_normal; float_raise(float_flag_invalid, s);
a.exp = dstf->exp_max; a->cls = float_class_normal;
a.frac = ((1ull << dstf->frac_size) - 1) << dstf->frac_shift; a->exp = float16_params_ahp.exp_max;
break; a->frac = MAKE_64BIT_MASK(float16_params_ahp.frac_shift,
float16_params_ahp.frac_size + 1);
break;
default: case float_class_normal:
break; case float_class_zero:
} break;
} else if (is_nan(a.cls)) {
parts_return_nan(&a, s); default:
g_assert_not_reached();
} }
return a;
} }
static void parts64_float_to_float(FloatParts64 *a, float_status *s)
{
if (is_nan(a->cls)) {
parts_return_nan(a, s);
}
}
static void parts128_float_to_float(FloatParts128 *a, float_status *s)
{
if (is_nan(a->cls)) {
parts_return_nan(a, s);
}
}
#define parts_float_to_float(P, S) \
PARTS_GENERIC_64_128(float_to_float, P)(P, S)
float32 float16_to_float32(float16 a, bool ieee, float_status *s) float32 float16_to_float32(float16 a, bool ieee, float_status *s)
{ {
const FloatFmt *fmt16 = ieee ? &float16_params : &float16_params_ahp; const FloatFmt *fmt16 = ieee ? &float16_params : &float16_params_ahp;
FloatParts64 pa, pr; FloatParts64 p;
float16a_unpack_canonical(&pa, a, s, fmt16); float16a_unpack_canonical(&p, a, s, fmt16);
pr = float_to_float(pa, &float32_params, s); parts_float_to_float(&p, s);
return float32_round_pack_canonical(&pr, s); return float32_round_pack_canonical(&p, s);
} }
float64 float16_to_float64(float16 a, bool ieee, float_status *s) float64 float16_to_float64(float16 a, bool ieee, float_status *s)
{ {
const FloatFmt *fmt16 = ieee ? &float16_params : &float16_params_ahp; const FloatFmt *fmt16 = ieee ? &float16_params : &float16_params_ahp;
FloatParts64 pa, pr; FloatParts64 p;
float16a_unpack_canonical(&pa, a, s, fmt16); float16a_unpack_canonical(&p, a, s, fmt16);
pr = float_to_float(pa, &float64_params, s); parts_float_to_float(&p, s);
return float64_round_pack_canonical(&pr, s); return float64_round_pack_canonical(&p, s);
} }
float16 float32_to_float16(float32 a, bool ieee, float_status *s) float16 float32_to_float16(float32 a, bool ieee, float_status *s)
{ {
const FloatFmt *fmt16 = ieee ? &float16_params : &float16_params_ahp; FloatParts64 p;
FloatParts64 pa, pr; const FloatFmt *fmt;
float32_unpack_canonical(&pa, a, s); float32_unpack_canonical(&p, a, s);
pr = float_to_float(pa, fmt16, s); if (ieee) {
return float16a_round_pack_canonical(&pr, s, fmt16); parts_float_to_float(&p, s);
fmt = &float16_params;
} else {
parts_float_to_ahp(&p, s);
fmt = &float16_params_ahp;
}
return float16a_round_pack_canonical(&p, s, fmt);
} }
static float64 QEMU_SOFTFLOAT_ATTR static float64 QEMU_SOFTFLOAT_ATTR
soft_float32_to_float64(float32 a, float_status *s) soft_float32_to_float64(float32 a, float_status *s)
{ {
FloatParts64 pa, pr; FloatParts64 p;
float32_unpack_canonical(&pa, a, s); float32_unpack_canonical(&p, a, s);
pr = float_to_float(pa, &float64_params, s); parts_float_to_float(&p, s);
return float64_round_pack_canonical(&pr, s); return float64_round_pack_canonical(&p, s);
} }
float64 float32_to_float64(float32 a, float_status *s) float64 float32_to_float64(float32 a, float_status *s)
@ -2134,57 +2156,63 @@ float64 float32_to_float64(float32 a, float_status *s)
float16 float64_to_float16(float64 a, bool ieee, float_status *s) float16 float64_to_float16(float64 a, bool ieee, float_status *s)
{ {
const FloatFmt *fmt16 = ieee ? &float16_params : &float16_params_ahp; FloatParts64 p;
FloatParts64 pa, pr; const FloatFmt *fmt;
float64_unpack_canonical(&pa, a, s); float64_unpack_canonical(&p, a, s);
pr = float_to_float(pa, fmt16, s); if (ieee) {
return float16a_round_pack_canonical(&pr, s, fmt16); parts_float_to_float(&p, s);
fmt = &float16_params;
} else {
parts_float_to_ahp(&p, s);
fmt = &float16_params_ahp;
}
return float16a_round_pack_canonical(&p, s, fmt);
} }
float32 float64_to_float32(float64 a, float_status *s) float32 float64_to_float32(float64 a, float_status *s)
{ {
FloatParts64 pa, pr; FloatParts64 p;
float64_unpack_canonical(&pa, a, s); float64_unpack_canonical(&p, a, s);
pr = float_to_float(pa, &float32_params, s); parts_float_to_float(&p, s);
return float32_round_pack_canonical(&pr, s); return float32_round_pack_canonical(&p, s);
} }
float32 bfloat16_to_float32(bfloat16 a, float_status *s) float32 bfloat16_to_float32(bfloat16 a, float_status *s)
{ {
FloatParts64 pa, pr; FloatParts64 p;
bfloat16_unpack_canonical(&pa, a, s); bfloat16_unpack_canonical(&p, a, s);
pr = float_to_float(pa, &float32_params, s); parts_float_to_float(&p, s);
return float32_round_pack_canonical(&pr, s); return float32_round_pack_canonical(&p, s);
} }
float64 bfloat16_to_float64(bfloat16 a, float_status *s) float64 bfloat16_to_float64(bfloat16 a, float_status *s)
{ {
FloatParts64 pa, pr; FloatParts64 p;
bfloat16_unpack_canonical(&pa, a, s); bfloat16_unpack_canonical(&p, a, s);
pr = float_to_float(pa, &float64_params, s); parts_float_to_float(&p, s);
return float64_round_pack_canonical(&pr, s); return float64_round_pack_canonical(&p, s);
} }
bfloat16 float32_to_bfloat16(float32 a, float_status *s) bfloat16 float32_to_bfloat16(float32 a, float_status *s)
{ {
FloatParts64 pa, pr; FloatParts64 p;
float32_unpack_canonical(&pa, a, s); float32_unpack_canonical(&p, a, s);
pr = float_to_float(pa, &bfloat16_params, s); parts_float_to_float(&p, s);
return bfloat16_round_pack_canonical(&pr, s); return bfloat16_round_pack_canonical(&p, s);
} }
bfloat16 float64_to_bfloat16(float64 a, float_status *s) bfloat16 float64_to_bfloat16(float64 a, float_status *s)
{ {
FloatParts64 pa, pr; FloatParts64 p;
float64_unpack_canonical(&pa, a, s); float64_unpack_canonical(&p, a, s);
pr = float_to_float(pa, &bfloat16_params, s); parts_float_to_float(&p, s);
return bfloat16_round_pack_canonical(&pr, s); return bfloat16_round_pack_canonical(&p, s);
} }
/* /*