aboutsummaryrefslogtreecommitdiff
path: root/fpu/softfloat-parts.c.inc
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2020-11-08 13:01:55 -0800
committerRichard Henderson <richard.henderson@linaro.org>2021-05-16 07:13:51 -0500
commitd46975bce10e163b9f10a7f569d3e046114d8580 (patch)
tree5a3f93fc9c854c766d21f2e97a84cd5dbbc59d12 /fpu/softfloat-parts.c.inc
parent979582d07115ff3c5c0c1f2bed90a2db91191281 (diff)
softfloat: Move sf_canonicalize to softfloat-parts.c.inc
At the same time, convert to pointers, rename to parts$N_canonicalize and define a macro for parts_canonicalize using QEMU_GENERIC. Rearrange the cases to recognize float_class_normal as early as possible. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'fpu/softfloat-parts.c.inc')
-rw-r--r--fpu/softfloat-parts.c.inc33
1 files changed, 33 insertions, 0 deletions
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index a78d61ea07..25bf99bd0f 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -100,3 +100,36 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
}
return a;
}
+
+/*
+ * Canonicalize the FloatParts structure. Determine the class,
+ * unbias the exponent, and normalize the fraction.
+ */
+static void partsN(canonicalize)(FloatPartsN *p, float_status *status,
+ const FloatFmt *fmt)
+{
+ if (unlikely(p->exp == 0)) {
+ if (likely(frac_eqz(p))) {
+ p->cls = float_class_zero;
+ } else if (status->flush_inputs_to_zero) {
+ float_raise(float_flag_input_denormal, status);
+ p->cls = float_class_zero;
+ frac_clear(p);
+ } else {
+ int shift = frac_normalize(p);
+ p->cls = float_class_normal;
+ p->exp = fmt->frac_shift - fmt->exp_bias - shift + 1;
+ }
+ } else if (likely(p->exp < fmt->exp_max) || fmt->arm_althp) {
+ p->cls = float_class_normal;
+ p->exp -= fmt->exp_bias;
+ frac_shl(p, fmt->frac_shift);
+ p->frac_hi |= DECOMPOSED_IMPLICIT_BIT;
+ } else if (likely(frac_eqz(p))) {
+ p->cls = float_class_inf;
+ } else {
+ frac_shl(p, fmt->frac_shift);
+ p->cls = (parts_is_snan_frac(p->frac_hi, status)
+ ? float_class_snan : float_class_qnan);
+ }
+}