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
State Superseded
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(-)

-- 
2.25.1

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>


-- 
Thanks,

David / dhildenb
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>


-- 
Alex Bennée
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;
+    }
+}