diff mbox series

[v2,03/28] softfloat: Move uint_to_float to softfloat-parts.c.inc

Message ID 20210525150706.294968-4-richard.henderson@linaro.org (mailing list archive)
State New, archived
Headers show
Series Convert floatx80 and float128 to FloatParts | expand

Commit Message

Richard Henderson May 25, 2021, 3:06 p.m. UTC
Rename to parts$N_uint_to_float.
Reimplement uint64_to_float128 with FloatParts128.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 fpu/softfloat.c           | 83 ++++++++++++++++-----------------------
 fpu/softfloat-parts.c.inc | 23 +++++++++++
 2 files changed, 56 insertions(+), 50 deletions(-)

Comments

David Hildenbrand May 26, 2021, 1:36 p.m. UTC | #1
On 25.05.21 17:06, Richard Henderson wrote:
> Rename to parts$N_uint_to_float.
> Reimplement uint64_to_float128 with FloatParts128.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   fpu/softfloat.c           | 83 ++++++++++++++++-----------------------
>   fpu/softfloat-parts.c.inc | 23 +++++++++++
>   2 files changed, 56 insertions(+), 50 deletions(-)
> 
> diff --git a/fpu/softfloat.c b/fpu/softfloat.c
> index 6404a2997f..db14bd09aa 100644
> --- a/fpu/softfloat.c
> +++ b/fpu/softfloat.c
> @@ -857,6 +857,14 @@ static void parts128_sint_to_float(FloatParts128 *p, int64_t a,
>   #define parts_sint_to_float(P, I, Z, S) \
>       PARTS_GENERIC_64_128(sint_to_float, P)(P, I, Z, S)
>   
> +static void parts64_uint_to_float(FloatParts64 *p, uint64_t a,
> +                                  int scale, float_status *s);
> +static void parts128_uint_to_float(FloatParts128 *p, uint64_t a,
> +                                   int scale, float_status *s);
> +
> +#define parts_uint_to_float(P, I, Z, S) \
> +    PARTS_GENERIC_64_128(uint_to_float, P)(P, I, Z, S)
> +
>   /*
>    * Helper functions for softfloat-parts.c.inc, per-size operations.
>    */
> @@ -3102,35 +3110,15 @@ float128 int32_to_float128(int32_t a, float_status *status)
>   }
>   
>   /*
> - * Unsigned Integer to float conversions
> - *
> - * Returns the result of converting the unsigned integer `a' to the
> - * floating-point format. The conversion is performed according to the
> - * IEC/IEEE Standard for Binary Floating-Point Arithmetic.
> + * Unsigned Integer to floating-point conversions
>    */
>   
> -static FloatParts64 uint_to_float(uint64_t a, int scale, float_status *status)
> -{
> -    FloatParts64 r = { .sign = false };
> -    int shift;
> -
> -    if (a == 0) {
> -        r.cls = float_class_zero;
> -    } else {
> -        scale = MIN(MAX(scale, -0x10000), 0x10000);
> -        shift = clz64(a);
> -        r.cls = float_class_normal;
> -        r.exp = DECOMPOSED_BINARY_POINT - shift + scale;
> -        r.frac = a << shift;
> -    }
> -
> -    return r;
> -}
> -
>   float16 uint64_to_float16_scalbn(uint64_t a, int scale, float_status *status)
>   {
> -    FloatParts64 pa = uint_to_float(a, scale, status);
> -    return float16_round_pack_canonical(&pa, status);
> +    FloatParts64 p;
> +
> +    parts_uint_to_float(&p, a, scale, status);
> +    return float16_round_pack_canonical(&p, status);
>   }
>   
>   float16 uint32_to_float16_scalbn(uint32_t a, int scale, float_status *status)
> @@ -3165,8 +3153,10 @@ float16 uint8_to_float16(uint8_t a, float_status *status)
>   
>   float32 uint64_to_float32_scalbn(uint64_t a, int scale, float_status *status)
>   {
> -    FloatParts64 pa = uint_to_float(a, scale, status);
> -    return float32_round_pack_canonical(&pa, status);
> +    FloatParts64 p;
> +
> +    parts_uint_to_float(&p, a, scale, status);
> +    return float32_round_pack_canonical(&p, status);
>   }
>   
>   float32 uint32_to_float32_scalbn(uint32_t a, int scale, float_status *status)
> @@ -3196,8 +3186,10 @@ float32 uint16_to_float32(uint16_t a, float_status *status)
>   
>   float64 uint64_to_float64_scalbn(uint64_t a, int scale, float_status *status)
>   {
> -    FloatParts64 pa = uint_to_float(a, scale, status);
> -    return float64_round_pack_canonical(&pa, status);
> +    FloatParts64 p;
> +
> +    parts_uint_to_float(&p, a, scale, status);
> +    return float64_round_pack_canonical(&p, status);
>   }
>   
>   float64 uint32_to_float64_scalbn(uint32_t a, int scale, float_status *status)
> @@ -3225,15 +3217,12 @@ float64 uint16_to_float64(uint16_t a, float_status *status)
>       return uint64_to_float64_scalbn(a, 0, status);
>   }
>   
> -/*
> - * Returns the result of converting the unsigned integer `a' to the
> - * bfloat16 format.
> - */
> -
>   bfloat16 uint64_to_bfloat16_scalbn(uint64_t a, int scale, float_status *status)
>   {
> -    FloatParts64 pa = uint_to_float(a, scale, status);
> -    return bfloat16_round_pack_canonical(&pa, status);
> +    FloatParts64 p;
> +
> +    parts_uint_to_float(&p, a, scale, status);
> +    return bfloat16_round_pack_canonical(&p, status);
>   }
>   
>   bfloat16 uint32_to_bfloat16_scalbn(uint32_t a, int scale, float_status *status)
> @@ -3261,6 +3250,14 @@ bfloat16 uint16_to_bfloat16(uint16_t a, float_status *status)
>       return uint64_to_bfloat16_scalbn(a, 0, status);
>   }
>   
> +float128 uint64_to_float128(uint64_t a, float_status *status)
> +{
> +    FloatParts128 p;
> +
> +    parts_uint_to_float(&p, a, 0, status);
> +    return float128_round_pack_canonical(&p, status);
> +}
> +
>   /* Float Min/Max */
>   /* min() and max() functions. These can't be implemented as
>    * 'compare and pick one input' because that would mishandle
> @@ -4972,20 +4969,6 @@ floatx80 int64_to_floatx80(int64_t a, float_status *status)
>   
>   }
>   
> -/*----------------------------------------------------------------------------
> -| Returns the result of converting the 64-bit unsigned integer `a'
> -| to the quadruple-precision floating-point format.  The conversion is performed
> -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
> -*----------------------------------------------------------------------------*/
> -
> -float128 uint64_to_float128(uint64_t a, float_status *status)
> -{
> -    if (a == 0) {
> -        return float128_zero;
> -    }
> -    return normalizeRoundAndPackFloat128(0, 0x406E, 0, a, status);
> -}
> -
>   /*----------------------------------------------------------------------------
>   | Returns the result of converting the single-precision floating-point value
>   | `a' to the extended double-precision floating-point format.  The conversion
> diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
> index 8102de1307..f3c4f8c8d2 100644
> --- a/fpu/softfloat-parts.c.inc
> +++ b/fpu/softfloat-parts.c.inc
> @@ -913,3 +913,26 @@ static void partsN(sint_to_float)(FloatPartsN *p, int64_t a,
>       p->exp = DECOMPOSED_BINARY_POINT - shift + scale;
>       p->frac_hi = f << shift;
>   }
> +
> +/*
> + * Unsigned Integer to float conversions
> + *
> + * Returns the result of converting the unsigned integer `a' to the
> + * floating-point format. The conversion is performed according to the
> + * IEC/IEEE Standard for Binary Floating-Point Arithmetic.
> + */
> +static void partsN(uint_to_float)(FloatPartsN *p, uint64_t a,
> +                                  int scale, float_status *status)
> +{
> +    memset(p, 0, sizeof(*p));
> +
> +    if (a == 0) {
> +        p->cls = float_class_zero;
> +    } else {
> +        int shift = clz64(a);
> +        scale = MIN(MAX(scale, -0x10000), 0x10000);
> +        p->cls = float_class_normal;
> +        p->exp = DECOMPOSED_BINARY_POINT - shift + scale;
> +        p->frac_hi = a << shift;
> +    }
> +}
> 

Reviewed-by: David Hildenbrand <david@redhat.com>
Alex Bennée June 2, 2021, 11:31 a.m. UTC | #2
Richard Henderson <richard.henderson@linaro.org> writes:

> Rename to parts$N_uint_to_float.
> Reimplement uint64_to_float128 with FloatParts128.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  fpu/softfloat.c           | 83 ++++++++++++++++-----------------------
>  fpu/softfloat-parts.c.inc | 23 +++++++++++
>  2 files changed, 56 insertions(+), 50 deletions(-)
>
> diff --git a/fpu/softfloat.c b/fpu/softfloat.c
> index 6404a2997f..db14bd09aa 100644
> --- a/fpu/softfloat.c
> +++ b/fpu/softfloat.c
> @@ -857,6 +857,14 @@ static void parts128_sint_to_float(FloatParts128 *p, int64_t a,
>  #define parts_sint_to_float(P, I, Z, S) \
>      PARTS_GENERIC_64_128(sint_to_float, P)(P, I, Z, S)
>  
> +static void parts64_uint_to_float(FloatParts64 *p, uint64_t a,
> +                                  int scale, float_status *s);
> +static void parts128_uint_to_float(FloatParts128 *p, uint64_t a,
> +                                   int scale, float_status *s);
> +
> +#define parts_uint_to_float(P, I, Z, S) \
> +    PARTS_GENERIC_64_128(uint_to_float, P)(P, I, Z, S)
> +
>  /*
>   * Helper functions for softfloat-parts.c.inc, per-size operations.
>   */
> @@ -3102,35 +3110,15 @@ float128 int32_to_float128(int32_t a, float_status *status)
>  }
>  
>  /*
> - * Unsigned Integer to float conversions
> - *
> - * Returns the result of converting the unsigned integer `a' to the
> - * floating-point format. The conversion is performed according to the
> - * IEC/IEEE Standard for Binary Floating-Point Arithmetic.
> + * Unsigned Integer to floating-point conversions
>   */
>  
> -static FloatParts64 uint_to_float(uint64_t a, int scale, float_status *status)
> -{
> -    FloatParts64 r = { .sign = false };
> -    int shift;
> -
> -    if (a == 0) {
> -        r.cls = float_class_zero;
> -    } else {
> -        scale = MIN(MAX(scale, -0x10000), 0x10000);

I realise this is translated to:

> +
> +/*
> + * Unsigned Integer to float conversions
> + *
> + * Returns the result of converting the unsigned integer `a' to the
> + * floating-point format. The conversion is performed according to the
> + * IEC/IEEE Standard for Binary Floating-Point Arithmetic.
> + */
> +static void partsN(uint_to_float)(FloatPartsN *p, uint64_t a,
> +                                  int scale, float_status *status)
> +{
> +    memset(p, 0, sizeof(*p));
> +
> +    if (a == 0) {
> +        p->cls = float_class_zero;
> +    } else {
> +        int shift = clz64(a);
> +        scale = MIN(MAX(scale, -0x10000), 0x10000);

here but it does seem weird to have an arbitrary limit here 

> +        p->cls = float_class_normal;
> +        p->exp = DECOMPOSED_BINARY_POINT - shift + scale;

where it's really a limit on fmt->exp_max. Are we just limiting it to
something sane and relying on the eventual repack to detect and overflow
condition?

> +        p->frac_hi = a << shift;
> +    }
> +}

Otherwise:

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Richard Henderson June 2, 2021, 4:28 p.m. UTC | #3
On 6/2/21 4:31 AM, Alex Bennée wrote:
>> +        scale = MIN(MAX(scale, -0x10000), 0x10000);
> 
> here but it does seem weird to have an arbitrary limit here
> 
>> +        p->cls = float_class_normal;
>> +        p->exp = DECOMPOSED_BINARY_POINT - shift + scale;
> 
> where it's really a limit on fmt->exp_max. Are we just limiting it to
> something sane and relying on the eventual repack to detect and overflow
> condition?

Yep.  This is before and after, mind.

r~
diff mbox series

Patch

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 6404a2997f..db14bd09aa 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -857,6 +857,14 @@  static void parts128_sint_to_float(FloatParts128 *p, int64_t a,
 #define parts_sint_to_float(P, I, Z, S) \
     PARTS_GENERIC_64_128(sint_to_float, P)(P, I, Z, S)
 
+static void parts64_uint_to_float(FloatParts64 *p, uint64_t a,
+                                  int scale, float_status *s);
+static void parts128_uint_to_float(FloatParts128 *p, uint64_t a,
+                                   int scale, float_status *s);
+
+#define parts_uint_to_float(P, I, Z, S) \
+    PARTS_GENERIC_64_128(uint_to_float, P)(P, I, Z, S)
+
 /*
  * Helper functions for softfloat-parts.c.inc, per-size operations.
  */
@@ -3102,35 +3110,15 @@  float128 int32_to_float128(int32_t a, float_status *status)
 }
 
 /*
- * Unsigned Integer to float conversions
- *
- * Returns the result of converting the unsigned integer `a' to the
- * floating-point format. The conversion is performed according to the
- * IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+ * Unsigned Integer to floating-point conversions
  */
 
-static FloatParts64 uint_to_float(uint64_t a, int scale, float_status *status)
-{
-    FloatParts64 r = { .sign = false };
-    int shift;
-
-    if (a == 0) {
-        r.cls = float_class_zero;
-    } else {
-        scale = MIN(MAX(scale, -0x10000), 0x10000);
-        shift = clz64(a);
-        r.cls = float_class_normal;
-        r.exp = DECOMPOSED_BINARY_POINT - shift + scale;
-        r.frac = a << shift;
-    }
-
-    return r;
-}
-
 float16 uint64_to_float16_scalbn(uint64_t a, int scale, float_status *status)
 {
-    FloatParts64 pa = uint_to_float(a, scale, status);
-    return float16_round_pack_canonical(&pa, status);
+    FloatParts64 p;
+
+    parts_uint_to_float(&p, a, scale, status);
+    return float16_round_pack_canonical(&p, status);
 }
 
 float16 uint32_to_float16_scalbn(uint32_t a, int scale, float_status *status)
@@ -3165,8 +3153,10 @@  float16 uint8_to_float16(uint8_t a, float_status *status)
 
 float32 uint64_to_float32_scalbn(uint64_t a, int scale, float_status *status)
 {
-    FloatParts64 pa = uint_to_float(a, scale, status);
-    return float32_round_pack_canonical(&pa, status);
+    FloatParts64 p;
+
+    parts_uint_to_float(&p, a, scale, status);
+    return float32_round_pack_canonical(&p, status);
 }
 
 float32 uint32_to_float32_scalbn(uint32_t a, int scale, float_status *status)
@@ -3196,8 +3186,10 @@  float32 uint16_to_float32(uint16_t a, float_status *status)
 
 float64 uint64_to_float64_scalbn(uint64_t a, int scale, float_status *status)
 {
-    FloatParts64 pa = uint_to_float(a, scale, status);
-    return float64_round_pack_canonical(&pa, status);
+    FloatParts64 p;
+
+    parts_uint_to_float(&p, a, scale, status);
+    return float64_round_pack_canonical(&p, status);
 }
 
 float64 uint32_to_float64_scalbn(uint32_t a, int scale, float_status *status)
@@ -3225,15 +3217,12 @@  float64 uint16_to_float64(uint16_t a, float_status *status)
     return uint64_to_float64_scalbn(a, 0, status);
 }
 
-/*
- * Returns the result of converting the unsigned integer `a' to the
- * bfloat16 format.
- */
-
 bfloat16 uint64_to_bfloat16_scalbn(uint64_t a, int scale, float_status *status)
 {
-    FloatParts64 pa = uint_to_float(a, scale, status);
-    return bfloat16_round_pack_canonical(&pa, status);
+    FloatParts64 p;
+
+    parts_uint_to_float(&p, a, scale, status);
+    return bfloat16_round_pack_canonical(&p, status);
 }
 
 bfloat16 uint32_to_bfloat16_scalbn(uint32_t a, int scale, float_status *status)
@@ -3261,6 +3250,14 @@  bfloat16 uint16_to_bfloat16(uint16_t a, float_status *status)
     return uint64_to_bfloat16_scalbn(a, 0, status);
 }
 
+float128 uint64_to_float128(uint64_t a, float_status *status)
+{
+    FloatParts128 p;
+
+    parts_uint_to_float(&p, a, 0, status);
+    return float128_round_pack_canonical(&p, status);
+}
+
 /* Float Min/Max */
 /* min() and max() functions. These can't be implemented as
  * 'compare and pick one input' because that would mishandle
@@ -4972,20 +4969,6 @@  floatx80 int64_to_floatx80(int64_t a, float_status *status)
 
 }
 
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 64-bit unsigned integer `a'
-| to the quadruple-precision floating-point format.  The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 uint64_to_float128(uint64_t a, float_status *status)
-{
-    if (a == 0) {
-        return float128_zero;
-    }
-    return normalizeRoundAndPackFloat128(0, 0x406E, 0, a, status);
-}
-
 /*----------------------------------------------------------------------------
 | Returns the result of converting the single-precision floating-point value
 | `a' to the extended double-precision floating-point format.  The conversion
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 8102de1307..f3c4f8c8d2 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -913,3 +913,26 @@  static void partsN(sint_to_float)(FloatPartsN *p, int64_t a,
     p->exp = DECOMPOSED_BINARY_POINT - shift + scale;
     p->frac_hi = f << shift;
 }
+
+/*
+ * Unsigned Integer to float conversions
+ *
+ * Returns the result of converting the unsigned integer `a' to the
+ * floating-point format. The conversion is performed according to the
+ * IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+ */
+static void partsN(uint_to_float)(FloatPartsN *p, uint64_t a,
+                                  int scale, float_status *status)
+{
+    memset(p, 0, sizeof(*p));
+
+    if (a == 0) {
+        p->cls = float_class_zero;
+    } else {
+        int shift = clz64(a);
+        scale = MIN(MAX(scale, -0x10000), 0x10000);
+        p->cls = float_class_normal;
+        p->exp = DECOMPOSED_BINARY_POINT - shift + scale;
+        p->frac_hi = a << shift;
+    }
+}