All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/6] softfloat 128-bit integer support
@ 2022-03-28 20:14 matheus.ferst
  2022-03-28 20:14 ` [RFC PATCH 1/6] softfloat: add uint128_to_float* conversion methods matheus.ferst
                   ` (6 more replies)
  0 siblings, 7 replies; 15+ messages in thread
From: matheus.ferst @ 2022-03-28 20:14 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc
  Cc: danielhb413, richard.henderson, groug, clg, Matheus Ferst, david

From: Matheus Ferst <matheus.ferst@eldorado.org.br>

This RFC is a first attempt at implementing the 128-bit integer
conversion routines in softfloat, as required by the xscv[su]qqp and
xscvqp[su]qz instructions of PowerISA v3.1.

Instead of using int128.h, int-to-float routines receive the 128-bit
numbers through a pair of 64-bit values, and float-to-int conversions
use a pointer to return the lower half of the result.

We only need the parts128 methods, but since the difference to parts64
ones seemed minor, I included both in this patch.

RFC:
 - Should we use struct Int128 instead of 64-bit value pairs?
 - I've not tested the float64 methods since the PPC instructions only
   use the quad-precision routines. Should we keep them in the final
   version?

Matheus Ferst (6):
  softfloat: add uint128_to_float* conversion methods
  softfloat: add int128_to_float* conversion methods
  softfloat: add float*_to_uint128 conversion methods
  softfloat: add float*_to_int128 conversion methods
  target/ppc: implement xscv[su]qqp
  target/ppc: implement xscvqp[su]qz

 fpu/softfloat-parts.c.inc           | 202 ++++++++++++++++++++++++++++
 fpu/softfloat.c                     | 161 ++++++++++++++++++++++
 include/fpu/softfloat.h             |  23 ++++
 target/ppc/fpu_helper.c             |  34 +++++
 target/ppc/helper.h                 |   4 +
 target/ppc/insn32.decode            |   7 +
 target/ppc/translate/vsx-impl.c.inc |  22 +++
 7 files changed, 453 insertions(+)

-- 
2.25.1



^ permalink raw reply	[flat|nested] 15+ messages in thread

* [RFC PATCH 1/6] softfloat: add uint128_to_float* conversion methods
  2022-03-28 20:14 [RFC PATCH 0/6] softfloat 128-bit integer support matheus.ferst
@ 2022-03-28 20:14 ` matheus.ferst
  2022-03-29 11:28   ` Richard Henderson
  2022-03-28 20:14 ` [RFC PATCH 2/6] softfloat: add int128_to_float* " matheus.ferst
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: matheus.ferst @ 2022-03-28 20:14 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc
  Cc: Peter Maydell, Alex Bennée, danielhb413, richard.henderson,
	groug, clg, Matheus Ferst, Aurelien Jarno, david

From: Matheus Ferst <matheus.ferst@eldorado.org.br>

Based on parts_uint_to_float, implements parts_uint_to_float2 that
receives a 128-bit integer through a pair of uint64_t values.

Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
---
 fpu/softfloat-parts.c.inc | 19 +++++++++++++++++++
 fpu/softfloat.c           | 30 ++++++++++++++++++++++++++++++
 include/fpu/softfloat.h   |  4 ++++
 3 files changed, 53 insertions(+)

diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index db3e1f393d..0bbecf835f 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -1219,6 +1219,25 @@ static void partsN(uint_to_float)(FloatPartsN *p, uint64_t a,
     }
 }
 
+static void partsN(uint_to_float2)(FloatPartsN *p, uint64_t hi, uint64_t lo,
+                                   int scale, float_status *status)
+{
+
+    if (hi == 0) {
+        parts_uint_to_float(p, lo, scale, status);
+    } else {
+        int shift = clz64(hi);
+        memset(p, 0, sizeof(*p));
+        scale = MIN(MAX(scale, -0x10000), 0x10000);
+        p->cls = float_class_normal;
+        p->exp = 127 - shift + scale;
+        p->frac_hi = shl_double(hi, lo, shift);
+        if (N > 64) {
+            p->frac_lo = shl_double(lo, 0, shift);
+        }
+    }
+}
+
 /*
  * Float min/max.
  */
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 7f524d4377..980ddfe5a1 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -866,6 +866,14 @@ static void parts128_uint_to_float(FloatParts128 *p, uint64_t a,
 #define parts_uint_to_float(P, I, Z, S) \
     PARTS_GENERIC_64_128(uint_to_float, P)(P, I, Z, S)
 
+static void parts64_uint_to_float2(FloatParts64 *p, uint64_t hi, uint64_t lo,
+                                   int scale, float_status *s);
+static void parts128_uint_to_float2(FloatParts128 *p, uint64_t hi, uint64_t lo,
+                                    int scale, float_status *s);
+
+#define parts_uint_to_float2(P, H, L, Z, S) \
+    PARTS_GENERIC_64_128(uint_to_float2, P)(P, H, L, Z, S)
+
 static FloatParts64 *parts64_minmax(FloatParts64 *a, FloatParts64 *b,
                                     float_status *s, int flags);
 static FloatParts128 *parts128_minmax(FloatParts128 *a, FloatParts128 *b,
@@ -3888,6 +3896,15 @@ float32 uint16_to_float32(uint16_t a, float_status *status)
     return uint64_to_float32_scalbn(a, 0, status);
 }
 
+float64 uint128_to_float64_scalbn(uint64_t hi, uint64_t lo, int scale,
+                                  float_status *status)
+{
+    FloatParts64 p;
+
+    parts_uint_to_float2(&p, hi, lo, scale, status);
+    return float64_round_pack_canonical(&p, status);
+}
+
 float64 uint64_to_float64_scalbn(uint64_t a, int scale, float_status *status)
 {
     FloatParts64 p;
@@ -3913,6 +3930,11 @@ float64 uint16_to_float64_scalbn(uint16_t a, int scale, float_status *status)
     return uint64_to_float64_scalbn(a, scale, status);
 }
 
+float64 uint128_to_float64(uint64_t hi, uint64_t lo, float_status *status)
+{
+    return uint128_to_float64_scalbn(hi, lo, 0, status);
+}
+
 float64 uint64_to_float64(uint64_t a, float_status *status)
 {
     return uint64_to_float64_scalbn(a, 0, status);
@@ -3969,6 +3991,14 @@ float128 uint64_to_float128(uint64_t a, float_status *status)
     return float128_round_pack_canonical(&p, status);
 }
 
+float128 uint128_to_float128(uint64_t hi, uint64_t lo, float_status *status)
+{
+    FloatParts128 p;
+
+    parts128_uint_to_float2(&p, hi, lo, 0, status);
+    return float128_round_pack_canonical(&p, status);
+}
+
 /*
  * Minimum and maximum
  */
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index d34b2c44d2..2ef4fec3d0 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -169,6 +169,8 @@ float64 int64_to_float64_scalbn(int64_t, int, float_status *status);
 float64 uint16_to_float64_scalbn(uint16_t, int, float_status *status);
 float64 uint32_to_float64_scalbn(uint32_t, int, float_status *status);
 float64 uint64_to_float64_scalbn(uint64_t, int, float_status *status);
+float64 uint128_to_float64_scalbn(uint64_t, uint64_t, int,
+                                  float_status *status);
 
 float64 int16_to_float64(int16_t, float_status *status);
 float64 int32_to_float64(int32_t, float_status *status);
@@ -176,6 +178,7 @@ float64 int64_to_float64(int64_t, float_status *status);
 float64 uint16_to_float64(uint16_t, float_status *status);
 float64 uint32_to_float64(uint32_t, float_status *status);
 float64 uint64_to_float64(uint64_t, float_status *status);
+float64 uint128_to_float64(uint64_t, uint64_t, float_status *status);
 
 floatx80 int32_to_floatx80(int32_t, float_status *status);
 floatx80 int64_to_floatx80(int64_t, float_status *status);
@@ -183,6 +186,7 @@ floatx80 int64_to_floatx80(int64_t, float_status *status);
 float128 int32_to_float128(int32_t, float_status *status);
 float128 int64_to_float128(int64_t, float_status *status);
 float128 uint64_to_float128(uint64_t, float_status *status);
+float128 uint128_to_float128(uint64_t, uint64_t, float_status *status);
 
 /*----------------------------------------------------------------------------
 | Software half-precision conversion routines.
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC PATCH 2/6] softfloat: add int128_to_float* conversion methods
  2022-03-28 20:14 [RFC PATCH 0/6] softfloat 128-bit integer support matheus.ferst
  2022-03-28 20:14 ` [RFC PATCH 1/6] softfloat: add uint128_to_float* conversion methods matheus.ferst
@ 2022-03-28 20:14 ` matheus.ferst
  2022-03-29 11:40   ` Richard Henderson
  2022-03-28 20:14 ` [RFC PATCH 3/6] softfloat: add float*_to_uint128 " matheus.ferst
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: matheus.ferst @ 2022-03-28 20:14 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc
  Cc: Peter Maydell, Alex Bennée, danielhb413, richard.henderson,
	groug, clg, Matheus Ferst, Aurelien Jarno, david

From: Matheus Ferst <matheus.ferst@eldorado.org.br>

Based on parts_sint_to_float, implements parts_sint_to_float2 that
receives a 128-bit signed integer via int64_t and uint64_t arguments.

Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
---
 fpu/softfloat-parts.c.inc | 37 +++++++++++++++++++++++++++++++++++++
 fpu/softfloat.c           | 30 ++++++++++++++++++++++++++++++
 include/fpu/softfloat.h   |  3 +++
 3 files changed, 70 insertions(+)

diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 0bbecf835f..5f7f107a0d 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -1196,6 +1196,43 @@ static void partsN(sint_to_float)(FloatPartsN *p, int64_t a,
     p->frac_hi = f << shift;
 }
 
+static void partsN(sint_to_float2)(FloatPartsN *p, int64_t hi, uint64_t lo,
+                                   int scale, float_status *status)
+{
+    uint64_t f = hi;
+    int shift;
+
+    if (hi == 0) {
+        parts_uint_to_float(p, lo, scale, status);
+    } else {
+        memset(p, 0, sizeof(*p));
+        p->cls = float_class_normal;
+        if (hi < 0) {
+            lo = -lo;
+            f = ~f + !lo;
+            p->sign = true;
+        }
+        if (f != 0) {
+            shift = clz64(f);
+        } else {
+            shift = 64 + clz64(lo);
+        }
+        scale = MIN(MAX(scale, -0x10000), 0x10000);
+
+        p->exp = 127 - shift + scale;
+
+        if (shift >= 64) {
+            f = lo;
+            lo = 0;
+            shift -= 64;
+        }
+        p->frac_hi = shl_double(f, lo, shift);
+        if (N > 64) {
+            p->frac_lo = shl_double(lo, 0, shift);
+        }
+    }
+}
+
 /*
  * Unsigned Integer to float conversions
  *
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 980ddfe5a1..ac3d6f5ab0 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -858,6 +858,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_sint_to_float2(FloatParts64 *p, int64_t hi, uint64_t lo,
+                                   int scale, float_status *s);
+static void parts128_sint_to_float2(FloatParts128 *p, int64_t hi, uint64_t lo,
+                                    int scale, float_status *s);
+
+#define parts_sint_to_float2(P, H, L, Z, S) \
+    PARTS_GENERIC_64_128(sint_to_float2, P)(P, H, L, 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,
@@ -3715,6 +3723,15 @@ float32 int16_to_float32(int16_t a, float_status *status)
     return int64_to_float32_scalbn(a, 0, status);
 }
 
+float64 int128_to_float64_scalbn(int64_t hi, uint64_t lo, int scale,
+                                 float_status *status)
+{
+    FloatParts64 p;
+
+    parts_sint_to_float2(&p, hi, lo, scale, status);
+    return float64_round_pack_canonical(&p, status);
+}
+
 float64 int64_to_float64_scalbn(int64_t a, int scale, float_status *status)
 {
     FloatParts64 p;
@@ -3740,6 +3757,11 @@ float64 int16_to_float64_scalbn(int16_t a, int scale, float_status *status)
     return int64_to_float64_scalbn(a, scale, status);
 }
 
+float64 int128_to_float64(int64_t hi, uint64_t lo, float_status *status)
+{
+    return int128_to_float64_scalbn(hi, lo, 0, status);
+}
+
 float64 int64_to_float64(int64_t a, float_status *status)
 {
     return int64_to_float64_scalbn(a, 0, status);
@@ -3788,6 +3810,14 @@ bfloat16 int16_to_bfloat16(int16_t a, float_status *status)
     return int64_to_bfloat16_scalbn(a, 0, status);
 }
 
+float128 int128_to_float128(int64_t hi, uint64_t lo, float_status *status)
+{
+    FloatParts128 p;
+
+    parts_sint_to_float2(&p, hi, lo, 0, status);
+    return float128_round_pack_canonical(&p, status);
+}
+
 float128 int64_to_float128(int64_t a, float_status *status)
 {
     FloatParts128 p;
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 2ef4fec3d0..5a2165a187 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -166,6 +166,7 @@ float32 uint64_to_float32(uint64_t, float_status *status);
 float64 int16_to_float64_scalbn(int16_t, int, float_status *status);
 float64 int32_to_float64_scalbn(int32_t, int, float_status *status);
 float64 int64_to_float64_scalbn(int64_t, int, float_status *status);
+float64 int128_to_float64_scalbn(int64_t, uint64_t, int, float_status *status);
 float64 uint16_to_float64_scalbn(uint16_t, int, float_status *status);
 float64 uint32_to_float64_scalbn(uint32_t, int, float_status *status);
 float64 uint64_to_float64_scalbn(uint64_t, int, float_status *status);
@@ -175,6 +176,7 @@ float64 uint128_to_float64_scalbn(uint64_t, uint64_t, int,
 float64 int16_to_float64(int16_t, float_status *status);
 float64 int32_to_float64(int32_t, float_status *status);
 float64 int64_to_float64(int64_t, float_status *status);
+float64 int128_to_float64(int64_t, uint64_t, float_status *status);
 float64 uint16_to_float64(uint16_t, float_status *status);
 float64 uint32_to_float64(uint32_t, float_status *status);
 float64 uint64_to_float64(uint64_t, float_status *status);
@@ -185,6 +187,7 @@ floatx80 int64_to_floatx80(int64_t, float_status *status);
 
 float128 int32_to_float128(int32_t, float_status *status);
 float128 int64_to_float128(int64_t, float_status *status);
+float128 int128_to_float128(int64_t, uint64_t, float_status *status);
 float128 uint64_to_float128(uint64_t, float_status *status);
 float128 uint128_to_float128(uint64_t, uint64_t, float_status *status);
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC PATCH 3/6] softfloat: add float*_to_uint128 conversion methods
  2022-03-28 20:14 [RFC PATCH 0/6] softfloat 128-bit integer support matheus.ferst
  2022-03-28 20:14 ` [RFC PATCH 1/6] softfloat: add uint128_to_float* conversion methods matheus.ferst
  2022-03-28 20:14 ` [RFC PATCH 2/6] softfloat: add int128_to_float* " matheus.ferst
@ 2022-03-28 20:14 ` matheus.ferst
  2022-03-29 11:48   ` Richard Henderson
  2022-03-28 20:14 ` [RFC PATCH 4/6] softfloat: add float*_to_int128 " matheus.ferst
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: matheus.ferst @ 2022-03-28 20:14 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc
  Cc: Peter Maydell, Alex Bennée, danielhb413, richard.henderson,
	groug, clg, Matheus Ferst, Aurelien Jarno, david

From: Matheus Ferst <matheus.ferst@eldorado.org.br>

Implements parts_float_to_uint2 based on parts_float_to_uint logic. The
new methods return the lower part of the result through the "lo"
pointer.

Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
---
 fpu/softfloat-parts.c.inc | 71 +++++++++++++++++++++++++++++++++++++++
 fpu/softfloat.c           | 51 ++++++++++++++++++++++++++++
 include/fpu/softfloat.h   |  8 +++++
 3 files changed, 130 insertions(+)

diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 5f7f107a0d..2767aeac03 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -1164,6 +1164,77 @@ static uint64_t partsN(float_to_uint)(FloatPartsN *p, FloatRoundMode rmode,
     return r;
 }
 
+static uint64_t partsN(float_to_uint2)(FloatPartsN *p, FloatRoundMode rmode,
+                                       int scale, float_status *s, uint64_t *lo)
+{
+    int flags = 0;
+    uint64_t hi;
+
+    switch (p->cls) {
+    case float_class_snan:
+        flags |= float_flag_invalid_snan;
+        /* fall through */
+    case float_class_qnan:
+        flags |= float_flag_invalid;
+        hi = UINT64_MAX;
+        *lo = UINT64_MAX;
+        break;
+
+    case float_class_inf:
+        flags = float_flag_invalid | float_flag_invalid_cvti;
+        if (p->sign) {
+            hi = 0;
+            *lo = 0;
+        } else {
+            hi = UINT64_MAX;
+            *lo = UINT64_MAX;
+        }
+        break;
+
+    case float_class_zero:
+        *lo = 0;
+        return 0;
+
+    case float_class_normal:
+        if (parts_round_to_int_normal(p, rmode, scale, N - 2)) {
+            flags = float_flag_inexact;
+            if (p->cls == float_class_zero) {
+                hi = 0;
+                *lo = 0;
+                break;
+            }
+        }
+
+        if (p->sign) {
+            flags = float_flag_invalid | float_flag_invalid_cvti;
+            hi = 0;
+            *lo = 0;
+        } else if (p->exp <= DECOMPOSED_BINARY_POINT) {
+            hi = 0;
+            *lo = p->frac_hi >> (DECOMPOSED_BINARY_POINT - p->exp);
+        } else if (p->exp <= 127) {
+            int shift = 127 - p->exp;
+            hi = shr_double(0, p->frac_hi, shift);
+            if (N > 64) {
+                *lo = shr_double(p->frac_hi, p->frac_lo, shift);
+            } else {
+                *lo = shr_double(p->frac_hi, 0, shift);
+            }
+        } else {
+            flags = float_flag_invalid | float_flag_invalid_cvti;
+            hi = UINT64_MAX;
+            *lo = UINT64_MAX;
+        }
+        break;
+
+    default:
+        g_assert_not_reached();
+    }
+
+    float_raise(flags, s);
+    return hi;
+}
+
 /*
  * Integer to float conversions
  *
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index ac3d6f5ab0..fe4320060c 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -850,6 +850,16 @@ static uint64_t parts128_float_to_uint(FloatParts128 *p, FloatRoundMode rmode,
 #define parts_float_to_uint(P, R, Z, M, S) \
     PARTS_GENERIC_64_128(float_to_uint, P)(P, R, Z, M, S)
 
+static uint64_t parts64_float_to_uint2(FloatParts64 *p, FloatRoundMode rmode,
+                                       int scale, float_status *s,
+                                       uint64_t *lo);
+static uint64_t parts128_float_to_uint2(FloatParts128 *p, FloatRoundMode rmode,
+                                        int scale, float_status *s,
+                                        uint64_t *lo);
+
+#define parts_float_to_uint2(P, R, Z, S, H) \
+    PARTS_GENERIC_64_128(float_to_uint2, P)(P, R, Z, S, H)
+
 static void parts64_sint_to_float(FloatParts64 *p, int64_t a,
                                   int scale, float_status *s);
 static void parts128_sint_to_float(FloatParts128 *p, int64_t a,
@@ -3451,6 +3461,15 @@ uint64_t float64_to_uint64_scalbn(float64 a, FloatRoundMode rmode, int scale,
     return parts_float_to_uint(&p, rmode, scale, UINT64_MAX, s);
 }
 
+uint64_t float64_to_uint128_scalbn(float64 a, FloatRoundMode rmode, int scale,
+                                   float_status *s, uint64_t *lo)
+{
+    FloatParts64 p;
+
+    float64_unpack_canonical(&p, a, s);
+    return parts_float_to_uint2(&p, rmode, scale, s, lo);
+}
+
 uint16_t bfloat16_to_uint16_scalbn(bfloat16 a, FloatRoundMode rmode,
                                    int scale, float_status *s)
 {
@@ -3496,6 +3515,16 @@ static uint64_t float128_to_uint64_scalbn(float128 a, FloatRoundMode rmode,
     return parts_float_to_uint(&p, rmode, scale, UINT64_MAX, s);
 }
 
+static uint64_t float128_to_uint128_scalbn(float128 a, FloatRoundMode rmode,
+                                           int scale, float_status *s,
+                                           uint64_t *lo)
+{
+    FloatParts128 p;
+
+    float128_unpack_canonical(&p, a, s);
+    return parts_float_to_uint2(&p, rmode, scale, s, lo);
+}
+
 uint8_t float16_to_uint8(float16 a, float_status *s)
 {
     return float16_to_uint8_scalbn(a, s->float_rounding_mode, 0, s);
@@ -3546,6 +3575,11 @@ uint64_t float64_to_uint64(float64 a, float_status *s)
     return float64_to_uint64_scalbn(a, s->float_rounding_mode, 0, s);
 }
 
+uint64_t float64_to_uint128(float64 a, float_status *s, uint64_t *lo)
+{
+    return float64_to_uint128_scalbn(a, s->float_rounding_mode, 0, s, lo);
+}
+
 uint32_t float128_to_uint32(float128 a, float_status *s)
 {
     return float128_to_uint32_scalbn(a, s->float_rounding_mode, 0, s);
@@ -3556,6 +3590,11 @@ uint64_t float128_to_uint64(float128 a, float_status *s)
     return float128_to_uint64_scalbn(a, s->float_rounding_mode, 0, s);
 }
 
+uint64_t float128_to_uint128(float128 a, float_status *s, uint64_t *lo)
+{
+    return float128_to_uint128_scalbn(a, s->float_rounding_mode, 0, s, lo);
+}
+
 uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *s)
 {
     return float16_to_uint16_scalbn(a, float_round_to_zero, 0, s);
@@ -3601,6 +3640,12 @@ uint64_t float64_to_uint64_round_to_zero(float64 a, float_status *s)
     return float64_to_uint64_scalbn(a, float_round_to_zero, 0, s);
 }
 
+uint64_t float64_to_uint128_round_to_zero(float64 a, float_status *s,
+                                          uint64_t *lo)
+{
+    return float64_to_uint128_scalbn(a, float_round_to_zero, 0, s, lo);
+}
+
 uint32_t float128_to_uint32_round_to_zero(float128 a, float_status *s)
 {
     return float128_to_uint32_scalbn(a, float_round_to_zero, 0, s);
@@ -3611,6 +3656,12 @@ uint64_t float128_to_uint64_round_to_zero(float128 a, float_status *s)
     return float128_to_uint64_scalbn(a, float_round_to_zero, 0, s);
 }
 
+uint64_t float128_to_uint128_round_to_zero(float128 a, float_status *s,
+                                           uint64_t *lo)
+{
+    return float128_to_uint128_scalbn(a, float_round_to_zero, 0, s, lo);
+}
+
 uint16_t bfloat16_to_uint16(bfloat16 a, float_status *s)
 {
     return bfloat16_to_uint16_scalbn(a, s->float_rounding_mode, 0, s);
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 5a2165a187..01d8edbc73 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -758,14 +758,19 @@ int64_t float64_to_int64_round_to_zero(float64, float_status *status);
 uint16_t float64_to_uint16_scalbn(float64, FloatRoundMode, int, float_status *);
 uint32_t float64_to_uint32_scalbn(float64, FloatRoundMode, int, float_status *);
 uint64_t float64_to_uint64_scalbn(float64, FloatRoundMode, int, float_status *);
+uint64_t float64_to_uint128_scalbn(float64, FloatRoundMode, int, float_status *,
+                                   uint64_t *);
 
 uint16_t float64_to_uint16(float64, float_status *status);
 uint32_t float64_to_uint32(float64, float_status *status);
 uint64_t float64_to_uint64(float64, float_status *status);
+uint64_t float64_to_uint128(float64, float_status *status, uint64_t *lo);
 
 uint16_t float64_to_uint16_round_to_zero(float64, float_status *status);
 uint32_t float64_to_uint32_round_to_zero(float64, float_status *status);
 uint64_t float64_to_uint64_round_to_zero(float64, float_status *status);
+uint64_t float64_to_uint128_round_to_zero(float64, float_status *status,
+                                          uint64_t *lo);
 
 float32 float64_to_float32(float64, float_status *status);
 floatx80 float64_to_floatx80(float64, float_status *status);
@@ -1210,7 +1215,10 @@ int32_t float128_to_int32_round_to_zero(float128, float_status *status);
 int64_t float128_to_int64(float128, float_status *status);
 int64_t float128_to_int64_round_to_zero(float128, float_status *status);
 uint64_t float128_to_uint64(float128, float_status *status);
+uint64_t float128_to_uint128(float128, float_status *status, uint64_t *lo);
 uint64_t float128_to_uint64_round_to_zero(float128, float_status *status);
+uint64_t float128_to_uint128_round_to_zero(float128, float_status *status,
+                                           uint64_t *lo);
 uint32_t float128_to_uint32(float128, float_status *status);
 uint32_t float128_to_uint32_round_to_zero(float128, float_status *status);
 float32 float128_to_float32(float128, float_status *status);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC PATCH 4/6] softfloat: add float*_to_int128 conversion methods
  2022-03-28 20:14 [RFC PATCH 0/6] softfloat 128-bit integer support matheus.ferst
                   ` (2 preceding siblings ...)
  2022-03-28 20:14 ` [RFC PATCH 3/6] softfloat: add float*_to_uint128 " matheus.ferst
@ 2022-03-28 20:14 ` matheus.ferst
  2022-03-29 12:10   ` Richard Henderson
  2022-03-28 20:14 ` [RFC PATCH 5/6] target/ppc: implement xscv[su]qqp matheus.ferst
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: matheus.ferst @ 2022-03-28 20:14 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc
  Cc: Peter Maydell, Alex Bennée, danielhb413, richard.henderson,
	groug, clg, Matheus Ferst, Aurelien Jarno, david

From: Matheus Ferst <matheus.ferst@eldorado.org.br>

Implements parts_float_to_int2 based on parts_float_to_int logic. The
new methods return the lower part of the result through the "lo"
pointer.

Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
---
 fpu/softfloat-parts.c.inc | 75 +++++++++++++++++++++++++++++++++++++++
 fpu/softfloat.c           | 50 ++++++++++++++++++++++++++
 include/fpu/softfloat.h   |  8 +++++
 3 files changed, 133 insertions(+)

diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 2767aeac03..344df52e5f 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -1096,6 +1096,81 @@ static int64_t partsN(float_to_sint)(FloatPartsN *p, FloatRoundMode rmode,
     return r;
 }
 
+static int64_t partsN(float_to_sint2)(FloatPartsN *p, FloatRoundMode rmode,
+                                      int scale, float_status *s, uint64_t *lo)
+{
+    int flags = 0;
+    uint64_t hi;
+
+    switch (p->cls) {
+    case float_class_snan:
+        flags |= float_flag_invalid_snan;
+        /* fall through */
+    case float_class_qnan:
+        flags |= float_flag_invalid;
+        hi = UINT64_MAX;
+        *lo = UINT64_MAX;
+        break;
+
+    case float_class_inf:
+        flags = float_flag_invalid | float_flag_invalid_cvti;
+        if (p->sign) {
+            hi = INT64_MIN;
+            *lo = 0;
+        } else {
+            hi = INT64_MAX;
+            *lo = UINT64_MAX;
+        }
+        break;
+
+    case float_class_zero:
+        *lo = 0;
+        return 0;
+
+    case float_class_normal:
+        if (parts_round_to_int_normal(p, rmode, scale, N - 2)) {
+            flags = float_flag_inexact;
+        }
+
+        if (p->exp <= DECOMPOSED_BINARY_POINT) {
+            hi = 0;
+            *lo = p->frac_hi >> (DECOMPOSED_BINARY_POINT - p->exp);
+        } else if (p->exp <= 127) {
+            int shift = 127 - p->exp;
+            hi = shr_double(0, p->frac_hi, shift);
+            if (N > 64) {
+                *lo = shr_double(p->frac_hi, p->frac_lo, shift);
+            } else {
+                *lo = shr_double(p->frac_hi, 0, shift);
+            }
+        } else {
+            hi = UINT64_MAX;
+            *lo = UINT64_MAX;
+        }
+        if (p->sign) {
+            if (hi < INT64_MIN || (hi == INT64_MIN && *lo == 0)) {
+                *lo = -*lo;
+                hi = ~hi + !*lo;
+            } else {
+                flags = float_flag_invalid | float_flag_invalid_cvti;
+                hi = INT64_MIN;
+                *lo = 0;
+            }
+        } else if (hi > INT64_MAX) {
+            flags = float_flag_invalid | float_flag_invalid_cvti;
+            hi = INT64_MAX;
+            *lo = UINT64_MAX;
+        }
+        break;
+
+    default:
+        g_assert_not_reached();
+    }
+
+    float_raise(flags, s);
+    return hi;
+}
+
 /*
  *  Returns the result of converting the floating-point value `a' to
  *  the unsigned integer format. The conversion is performed according
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index fe4320060c..41a18f86df 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -840,6 +840,15 @@ static int64_t parts128_float_to_sint(FloatParts128 *p, FloatRoundMode rmode,
 #define parts_float_to_sint(P, R, Z, MN, MX, S) \
     PARTS_GENERIC_64_128(float_to_sint, P)(P, R, Z, MN, MX, S)
 
+static int64_t parts64_float_to_sint2(FloatParts64 *p, FloatRoundMode rmode,
+                                      int scale, float_status *s, uint64_t *lo);
+static int64_t parts128_float_to_sint2(FloatParts128 *p, FloatRoundMode rmode,
+                                       int scale, float_status *s,
+                                       uint64_t *lo);
+
+#define parts_float_to_sint2(P, R, Z, S, H) \
+    PARTS_GENERIC_64_128(float_to_sint2, P)(P, R, Z, S, H)
+
 static uint64_t parts64_float_to_uint(FloatParts64 *p, FloatRoundMode rmode,
                                       int scale, uint64_t max,
                                       float_status *s);
@@ -3135,6 +3144,15 @@ int64_t float64_to_int64_scalbn(float64 a, FloatRoundMode rmode, int scale,
     return parts_float_to_sint(&p, rmode, scale, INT64_MIN, INT64_MAX, s);
 }
 
+int64_t float64_to_int128_scalbn(float64 a, FloatRoundMode rmode, int scale,
+                                 float_status *s, uint64_t *lo)
+{
+    FloatParts64 p;
+
+    float64_unpack_canonical(&p, a, s);
+    return parts_float_to_sint2(&p, rmode, scale, s, lo);
+}
+
 int16_t bfloat16_to_int16_scalbn(bfloat16 a, FloatRoundMode rmode, int scale,
                                  float_status *s)
 {
@@ -3180,6 +3198,16 @@ static int64_t float128_to_int64_scalbn(float128 a, FloatRoundMode rmode,
     return parts_float_to_sint(&p, rmode, scale, INT64_MIN, INT64_MAX, s);
 }
 
+static int64_t float128_to_int128_scalbn(float128 a, FloatRoundMode rmode,
+                                         int scale, float_status *s,
+                                         uint64_t *lo)
+{
+    FloatParts128 p;
+
+    float128_unpack_canonical(&p, a, s);
+    return parts_float_to_sint2(&p, rmode, scale, s, lo);
+}
+
 static int32_t floatx80_to_int32_scalbn(floatx80 a, FloatRoundMode rmode,
                                         int scale, float_status *s)
 {
@@ -3252,6 +3280,11 @@ int64_t float64_to_int64(float64 a, float_status *s)
     return float64_to_int64_scalbn(a, s->float_rounding_mode, 0, s);
 }
 
+int64_t float64_to_int128(float64 a, float_status *s, uint64_t *lo)
+{
+    return float64_to_int128_scalbn(a, s->float_rounding_mode, 0, s, lo);
+}
+
 int32_t float128_to_int32(float128 a, float_status *s)
 {
     return float128_to_int32_scalbn(a, s->float_rounding_mode, 0, s);
@@ -3262,6 +3295,11 @@ int64_t float128_to_int64(float128 a, float_status *s)
     return float128_to_int64_scalbn(a, s->float_rounding_mode, 0, s);
 }
 
+int64_t float128_to_int128(float128 a, float_status *s, uint64_t *lo)
+{
+    return float128_to_int128_scalbn(a, s->float_rounding_mode, 0, s, lo);
+}
+
 int32_t floatx80_to_int32(floatx80 a, float_status *s)
 {
     return floatx80_to_int32_scalbn(a, s->float_rounding_mode, 0, s);
@@ -3317,6 +3355,12 @@ int64_t float64_to_int64_round_to_zero(float64 a, float_status *s)
     return float64_to_int64_scalbn(a, float_round_to_zero, 0, s);
 }
 
+int64_t float64_to_int128_round_to_zero(float64 a, float_status *s,
+                                        uint64_t *lo)
+{
+    return float64_to_int128_scalbn(a, float_round_to_zero, 0, s, lo);
+}
+
 int32_t float128_to_int32_round_to_zero(float128 a, float_status *s)
 {
     return float128_to_int32_scalbn(a, float_round_to_zero, 0, s);
@@ -3327,6 +3371,12 @@ int64_t float128_to_int64_round_to_zero(float128 a, float_status *s)
     return float128_to_int64_scalbn(a, float_round_to_zero, 0, s);
 }
 
+int64_t float128_to_int128_round_to_zero(float128 a, float_status *s,
+                                         uint64_t *lo)
+{
+    return float128_to_int128_scalbn(a, float_round_to_zero, 0, s, lo);
+}
+
 int32_t floatx80_to_int32_round_to_zero(floatx80 a, float_status *s)
 {
     return floatx80_to_int32_scalbn(a, float_round_to_zero, 0, s);
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 01d8edbc73..8d6d2ee62b 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -746,14 +746,19 @@ float32 float32_default_nan(float_status *status);
 int16_t float64_to_int16_scalbn(float64, FloatRoundMode, int, float_status *);
 int32_t float64_to_int32_scalbn(float64, FloatRoundMode, int, float_status *);
 int64_t float64_to_int64_scalbn(float64, FloatRoundMode, int, float_status *);
+int64_t float64_to_int128_scalbn(float64, FloatRoundMode, int, float_status *,
+                                 uint64_t *);
 
 int16_t float64_to_int16(float64, float_status *status);
 int32_t float64_to_int32(float64, float_status *status);
 int64_t float64_to_int64(float64, float_status *status);
+int64_t float64_to_int128(float64, float_status *status, uint64_t *lo);
 
 int16_t float64_to_int16_round_to_zero(float64, float_status *status);
 int32_t float64_to_int32_round_to_zero(float64, float_status *status);
 int64_t float64_to_int64_round_to_zero(float64, float_status *status);
+int64_t float64_to_int128_round_to_zero(float64, float_status *status,
+                                        uint64_t *lo);
 
 uint16_t float64_to_uint16_scalbn(float64, FloatRoundMode, int, float_status *);
 uint32_t float64_to_uint32_scalbn(float64, FloatRoundMode, int, float_status *);
@@ -1213,7 +1218,10 @@ floatx80 floatx80_default_nan(float_status *status);
 int32_t float128_to_int32(float128, float_status *status);
 int32_t float128_to_int32_round_to_zero(float128, float_status *status);
 int64_t float128_to_int64(float128, float_status *status);
+int64_t float128_to_int128(float128, float_status *status, uint64_t *lo);
 int64_t float128_to_int64_round_to_zero(float128, float_status *status);
+int64_t float128_to_int128_round_to_zero(float128, float_status *status,
+                                         uint64_t *lo);
 uint64_t float128_to_uint64(float128, float_status *status);
 uint64_t float128_to_uint128(float128, float_status *status, uint64_t *lo);
 uint64_t float128_to_uint64_round_to_zero(float128, float_status *status);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC PATCH 5/6] target/ppc: implement xscv[su]qqp
  2022-03-28 20:14 [RFC PATCH 0/6] softfloat 128-bit integer support matheus.ferst
                   ` (3 preceding siblings ...)
  2022-03-28 20:14 ` [RFC PATCH 4/6] softfloat: add float*_to_int128 " matheus.ferst
@ 2022-03-28 20:14 ` matheus.ferst
  2022-03-29 12:16   ` Richard Henderson
  2022-03-28 20:14 ` [RFC PATCH 6/6] target/ppc: implement xscvqp[su]qz matheus.ferst
  2022-03-29  3:38 ` [RFC PATCH 0/6] softfloat 128-bit integer support Richard Henderson
  6 siblings, 1 reply; 15+ messages in thread
From: matheus.ferst @ 2022-03-28 20:14 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc
  Cc: danielhb413, richard.henderson, groug, clg, Matheus Ferst, david

From: Matheus Ferst <matheus.ferst@eldorado.org.br>

Implement the following PowerISA v3.1 instructions:
xscvsqqp: VSX Scalar Convert with round Signed Quadword to
          Quad-Precision
xscvuqqp: VSX Scalar Convert with round Unsigned Quadword to
          Quad-Precision format

Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
---
 target/ppc/fpu_helper.c             | 11 +++++++++++
 target/ppc/helper.h                 |  2 ++
 target/ppc/insn32.decode            |  5 +++++
 target/ppc/translate/vsx-impl.c.inc | 20 ++++++++++++++++++++
 4 files changed, 38 insertions(+)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 7e8be99cc0..5101ba92ae 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -3058,6 +3058,17 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb)        \
 VSX_CVT_INT_TO_FP2(xvcvsxdsp, int64, float32)
 VSX_CVT_INT_TO_FP2(xvcvuxdsp, uint64, float32)
 
+#define VSX_CVT_INT128_TO_FP(op, tp)                                        \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb)            \
+{                                                                           \
+    xt->f128 = tp##_to_float128(xb->VsrD(0), xb->VsrD(1), &env->fp_status); \
+    helper_compute_fprf_float128(env, xt->f128);                            \
+    do_float_check_status(env, GETPC());                                    \
+}
+
+VSX_CVT_INT128_TO_FP(XSCVUQQP, uint128);
+VSX_CVT_INT128_TO_FP(XSCVSQQP, int128);
+
 /*
  * VSX_CVT_INT_TO_FP_VECTOR - VSX integer to floating point conversion
  *   op    - instruction mnemonic
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 57da11c77e..7df0c01819 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -388,6 +388,8 @@ DEF_HELPER_4(xscvqpsdz, void, env, i32, vsr, vsr)
 DEF_HELPER_4(xscvqpswz, void, env, i32, vsr, vsr)
 DEF_HELPER_4(xscvqpudz, void, env, i32, vsr, vsr)
 DEF_HELPER_4(xscvqpuwz, void, env, i32, vsr, vsr)
+DEF_HELPER_3(XSCVUQQP, void, env, vsr, vsr)
+DEF_HELPER_3(XSCVSQQP, void, env, vsr, vsr)
 DEF_HELPER_3(xscvhpdp, void, env, vsr, vsr)
 DEF_HELPER_4(xscvsdqp, void, env, i32, vsr, vsr)
 DEF_HELPER_3(xscvspdp, void, env, vsr, vsr)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index ac2d3da9a7..6fb568c1fe 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -91,6 +91,9 @@
 
 @X_tp_a_bp_rc   ...... ....0 ra:5 ....0 .......... rc:1         &X_rc rt=%x_frtp rb=%x_frbp
 
+&X_tb           rt rb
+@X_tb           ...... rt:5 ..... rb:5 .......... .             &X_tb
+
 &X_tb_rc        rt rb rc:bool
 @X_tb_rc        ...... rt:5 ..... rb:5 .......... rc:1          &X_tb_rc
 
@@ -692,6 +695,8 @@ XSCMPGTQP       111111 ..... ..... ..... 0011100100 -   @X
 ## VSX Binary Floating-Point Convert Instructions
 
 XSCVQPDP        111111 ..... 10100 ..... 1101000100 .   @X_tb_rc
+XSCVUQQP        111111 ..... 00011 ..... 1101000100 -   @X_tb
+XSCVSQQP        111111 ..... 01011 ..... 1101000100 -   @X_tb
 XVCVBF16SPN     111100 ..... 10000 ..... 111011011 ..   @XX2
 XVCVSPBF16      111100 ..... 10001 ..... 111011011 ..   @XX2
 
diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc
index d1f6333314..a305579ecc 100644
--- a/target/ppc/translate/vsx-impl.c.inc
+++ b/target/ppc/translate/vsx-impl.c.inc
@@ -838,6 +838,26 @@ static bool trans_XSCVQPDP(DisasContext *ctx, arg_X_tb_rc *a)
     return true;
 }
 
+static bool do_helper_env_X_tb(DisasContext *ctx, arg_X_tb *a,
+                               void (*gen_helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr))
+{
+    TCGv_ptr xt, xb;
+
+    REQUIRE_INSNS_FLAGS2(ctx, ISA310);
+    REQUIRE_VSX(ctx);
+
+    xt = gen_avr_ptr(a->rt);
+    xb = gen_avr_ptr(a->rb);
+    gen_helper(cpu_env, xt, xb);
+    tcg_temp_free_ptr(xt);
+    tcg_temp_free_ptr(xb);
+
+    return true;
+}
+
+TRANS(XSCVUQQP, do_helper_env_X_tb, gen_helper_XSCVUQQP)
+TRANS(XSCVSQQP, do_helper_env_X_tb, gen_helper_XSCVSQQP)
+
 #define GEN_VSX_HELPER_2(name, op1, op2, inval, type)                         \
 static void gen_##name(DisasContext *ctx)                                     \
 {                                                                             \
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC PATCH 6/6] target/ppc: implement xscvqp[su]qz
  2022-03-28 20:14 [RFC PATCH 0/6] softfloat 128-bit integer support matheus.ferst
                   ` (4 preceding siblings ...)
  2022-03-28 20:14 ` [RFC PATCH 5/6] target/ppc: implement xscv[su]qqp matheus.ferst
@ 2022-03-28 20:14 ` matheus.ferst
  2022-03-29 12:18   ` Richard Henderson
  2022-03-29  3:38 ` [RFC PATCH 0/6] softfloat 128-bit integer support Richard Henderson
  6 siblings, 1 reply; 15+ messages in thread
From: matheus.ferst @ 2022-03-28 20:14 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc
  Cc: danielhb413, richard.henderson, groug, clg, Matheus Ferst, david

From: Matheus Ferst <matheus.ferst@eldorado.org.br>

Implement the following PowerISA v3.1 instructions:
xscvqpsqz: VSX Scalar Convert with round to zero Quad-Precision to
           Signed Quadword
xscvqpuqz: VSX Scalar Convert with round to zero Quad-Precision to
           Unsigned Quadword

Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
---
 target/ppc/fpu_helper.c             | 23 +++++++++++++++++++++++
 target/ppc/helper.h                 |  2 ++
 target/ppc/insn32.decode            |  2 ++
 target/ppc/translate/vsx-impl.c.inc |  2 ++
 4 files changed, 29 insertions(+)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 5101ba92ae..712306b5a1 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -2925,6 +2925,29 @@ VSX_CVT_FP_TO_INT(xvcvspsxws, 4, float32, int32, VsrW(i), VsrW(i), 0x80000000U)
 VSX_CVT_FP_TO_INT(xvcvspuxds, 2, float32, uint64, VsrW(2 * i), VsrD(i), 0ULL)
 VSX_CVT_FP_TO_INT(xvcvspuxws, 4, float32, uint32, VsrW(i), VsrW(i), 0U)
 
+#define VSX_CVT_FP_TO_INT128(op, tp, rnan)                                  \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb)            \
+{                                                                           \
+    ppc_vsr_t t;                                                            \
+    int flags;                                                              \
+                                                                            \
+    helper_reset_fpstatus(env);                                             \
+    t.VsrD(0) = float128_to_##tp##_round_to_zero(xb->f128, &env->fp_status, \
+                                                 &t.VsrD(1));               \
+    flags = get_float_exception_flags(&env->fp_status);                     \
+    if (unlikely(flags & float_flag_invalid)) {                             \
+        t.VsrD(0) = float_invalid_cvt(env, flags, t.VsrD(0), rnan, 0,       \
+                                                  GETPC());                 \
+        t.VsrD(1) = -(t.VsrD(0) & 1);                                       \
+    }                                                                       \
+                                                                            \
+    *xt = t;                                                                \
+    do_float_check_status(env, GETPC());                                    \
+}
+
+VSX_CVT_FP_TO_INT128(XSCVQPUQZ, uint128, 0)
+VSX_CVT_FP_TO_INT128(XSCVQPSQZ, int128, 0x8000000000000000ULL);
+
 /*
  * Likewise, except that the result is duplicated into both subwords.
  * Power ISA v3.1 has Programming Notes for these insns:
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 7df0c01819..aa6773c4a5 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -388,6 +388,8 @@ DEF_HELPER_4(xscvqpsdz, void, env, i32, vsr, vsr)
 DEF_HELPER_4(xscvqpswz, void, env, i32, vsr, vsr)
 DEF_HELPER_4(xscvqpudz, void, env, i32, vsr, vsr)
 DEF_HELPER_4(xscvqpuwz, void, env, i32, vsr, vsr)
+DEF_HELPER_3(XSCVQPUQZ, void, env, vsr, vsr)
+DEF_HELPER_3(XSCVQPSQZ, void, env, vsr, vsr)
 DEF_HELPER_3(XSCVUQQP, void, env, vsr, vsr)
 DEF_HELPER_3(XSCVSQQP, void, env, vsr, vsr)
 DEF_HELPER_3(xscvhpdp, void, env, vsr, vsr)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 6fb568c1fe..39372fe673 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -695,6 +695,8 @@ XSCMPGTQP       111111 ..... ..... ..... 0011100100 -   @X
 ## VSX Binary Floating-Point Convert Instructions
 
 XSCVQPDP        111111 ..... 10100 ..... 1101000100 .   @X_tb_rc
+XSCVQPUQZ       111111 ..... 00000 ..... 1101000100 -   @X_tb
+XSCVQPSQZ       111111 ..... 01000 ..... 1101000100 -   @X_tb
 XSCVUQQP        111111 ..... 00011 ..... 1101000100 -   @X_tb
 XSCVSQQP        111111 ..... 01011 ..... 1101000100 -   @X_tb
 XVCVBF16SPN     111100 ..... 10000 ..... 111011011 ..   @XX2
diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc
index a305579ecc..5cc006d715 100644
--- a/target/ppc/translate/vsx-impl.c.inc
+++ b/target/ppc/translate/vsx-impl.c.inc
@@ -855,6 +855,8 @@ static bool do_helper_env_X_tb(DisasContext *ctx, arg_X_tb *a,
     return true;
 }
 
+TRANS(XSCVQPUQZ, do_helper_env_X_tb, gen_helper_XSCVQPUQZ)
+TRANS(XSCVQPSQZ, do_helper_env_X_tb, gen_helper_XSCVQPSQZ)
 TRANS(XSCVUQQP, do_helper_env_X_tb, gen_helper_XSCVUQQP)
 TRANS(XSCVSQQP, do_helper_env_X_tb, gen_helper_XSCVSQQP)
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 0/6] softfloat 128-bit integer support
  2022-03-28 20:14 [RFC PATCH 0/6] softfloat 128-bit integer support matheus.ferst
                   ` (5 preceding siblings ...)
  2022-03-28 20:14 ` [RFC PATCH 6/6] target/ppc: implement xscvqp[su]qz matheus.ferst
@ 2022-03-29  3:38 ` Richard Henderson
  2022-03-30 17:59   ` Matheus K. Ferst
  6 siblings, 1 reply; 15+ messages in thread
From: Richard Henderson @ 2022-03-29  3:38 UTC (permalink / raw)
  To: matheus.ferst, qemu-devel, qemu-ppc; +Cc: groug, danielhb413, clg, david

On 3/28/22 14:14, matheus.ferst@eldorado.org.br wrote:
> From: Matheus Ferst <matheus.ferst@eldorado.org.br>
> 
> This RFC is a first attempt at implementing the 128-bit integer
> conversion routines in softfloat, as required by the xscv[su]qqp and
> xscvqp[su]qz instructions of PowerISA v3.1.
> 
> Instead of using int128.h, int-to-float routines receive the 128-bit
> numbers through a pair of 64-bit values, and float-to-int conversions
> use a pointer to return the lower half of the result.
> 
> We only need the parts128 methods, but since the difference to parts64
> ones seemed minor, I included both in this patch.
> 
> RFC:
>   - Should we use struct Int128 instead of 64-bit value pairs?

I think so.  We have it, and it makes the interface more obvious.

>   - I've not tested the float64 methods since the PPC instructions only
>     use the quad-precision routines. Should we keep them in the final
>     version?

Let's not add anything that we don't have a need for.
It may eventually be needed by RISC-V RV128, but we can add it then.


r~


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 1/6] softfloat: add uint128_to_float* conversion methods
  2022-03-28 20:14 ` [RFC PATCH 1/6] softfloat: add uint128_to_float* conversion methods matheus.ferst
@ 2022-03-29 11:28   ` Richard Henderson
  0 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2022-03-29 11:28 UTC (permalink / raw)
  To: matheus.ferst, qemu-devel, qemu-ppc
  Cc: Peter Maydell, danielhb413, groug, clg, Alex Bennée,
	Aurelien Jarno, david

On 3/28/22 14:14, matheus.ferst@eldorado.org.br wrote:
> +        p->frac_hi = shl_double(hi, lo, shift);
> +        if (N > 64) {
> +            p->frac_lo = shl_double(lo, 0, shift);
> +        }

shl_double(x, 0, n) -> x << n.

You could also assign to frac_lo before frac_hi and drop the N > 64 test, though I'm not 
sure if that reads better or not.

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 2/6] softfloat: add int128_to_float* conversion methods
  2022-03-28 20:14 ` [RFC PATCH 2/6] softfloat: add int128_to_float* " matheus.ferst
@ 2022-03-29 11:40   ` Richard Henderson
  0 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2022-03-29 11:40 UTC (permalink / raw)
  To: matheus.ferst, qemu-devel, qemu-ppc
  Cc: Peter Maydell, danielhb413, groug, clg, Alex Bennée,
	Aurelien Jarno, david

On 3/28/22 14:14, matheus.ferst@eldorado.org.br wrote:
> From: Matheus Ferst <matheus.ferst@eldorado.org.br>
> 
> Based on parts_sint_to_float, implements parts_sint_to_float2 that
> receives a 128-bit signed integer via int64_t and uint64_t arguments.
> 
> Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
> ---
>   fpu/softfloat-parts.c.inc | 37 +++++++++++++++++++++++++++++++++++++
>   fpu/softfloat.c           | 30 ++++++++++++++++++++++++++++++
>   include/fpu/softfloat.h   |  3 +++
>   3 files changed, 70 insertions(+)
> 
> diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
> index 0bbecf835f..5f7f107a0d 100644
> --- a/fpu/softfloat-parts.c.inc
> +++ b/fpu/softfloat-parts.c.inc
> @@ -1196,6 +1196,43 @@ static void partsN(sint_to_float)(FloatPartsN *p, int64_t a,
>       p->frac_hi = f << shift;
>   }
>   
> +static void partsN(sint_to_float2)(FloatPartsN *p, int64_t hi, uint64_t lo,
> +                                   int scale, float_status *status)
> +{
> +    uint64_t f = hi;
> +    int shift;
> +
> +    if (hi == 0) {
> +        parts_uint_to_float(p, lo, scale, status);
> +    } else {

We should also defer "small" negative numbers.

        if (hi == -1) {
            parts_uint_to_float(p, -lo, scale, status);
            p->sign = true;
            return;
        }

That should ensure...

> +        memset(p, 0, sizeof(*p));
> +        p->cls = float_class_normal;
> +        if (hi < 0) {
> +            lo = -lo;
> +            f = ~f + !lo;
> +            p->sign = true;
> +        }
> +        if (f != 0) {
> +            shift = clz64(f);
> +        } else {
> +            shift = 64 + clz64(lo);
> +        }

this case

> +        scale = MIN(MAX(scale, -0x10000), 0x10000);
> +
> +        p->exp = 127 - shift + scale;
> +
> +        if (shift >= 64) {
> +            f = lo;
> +            lo = 0;
> +            shift -= 64;
> +        }

and this case don't happen.

> +        p->frac_hi = shl_double(f, lo, shift);
> +        if (N > 64) {
> +            p->frac_lo = shl_double(lo, 0, shift);

Same comment about shl_double w/ 0.

Alternately, rewrite the whole thing in terms of uint_to_float2:

     if (hi >= 0) {
         uint_to_float2(p, hi, lo, scale, status);
     } else {
         lo = -lo;
         hi = ~hi + !lo;
         uint_to_float2(p, hi, lo, scale, status);
         p->sign = true;
     }


r~


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 3/6] softfloat: add float*_to_uint128 conversion methods
  2022-03-28 20:14 ` [RFC PATCH 3/6] softfloat: add float*_to_uint128 " matheus.ferst
@ 2022-03-29 11:48   ` Richard Henderson
  0 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2022-03-29 11:48 UTC (permalink / raw)
  To: matheus.ferst, qemu-devel, qemu-ppc
  Cc: Peter Maydell, danielhb413, groug, clg, Alex Bennée,
	Aurelien Jarno, david

On 3/28/22 14:14, matheus.ferst@eldorado.org.br wrote:
> +static uint64_t partsN(float_to_uint2)(FloatPartsN *p, FloatRoundMode rmode,
> +                                       int scale, float_status *s, uint64_t *lo)
> +{
> +    int flags = 0;
> +    uint64_t hi;

I think most of this would read cleaner with 'lo' as a local variable, assigned to *plo at 
the end (or, at the end, combined into the Int128 return value).

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 4/6] softfloat: add float*_to_int128 conversion methods
  2022-03-28 20:14 ` [RFC PATCH 4/6] softfloat: add float*_to_int128 " matheus.ferst
@ 2022-03-29 12:10   ` Richard Henderson
  0 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2022-03-29 12:10 UTC (permalink / raw)
  To: matheus.ferst, qemu-devel, qemu-ppc
  Cc: Peter Maydell, danielhb413, groug, clg, Alex Bennée,
	Aurelien Jarno, david

On 3/28/22 14:14, matheus.ferst@eldorado.org.br wrote:
> +static int64_t partsN(float_to_sint2)(FloatPartsN *p, FloatRoundMode rmode,
> +                                      int scale, float_status *s, uint64_t *lo)
> +{
> +    int flags = 0;
> +    uint64_t hi;

Similar comment about 'lo' vs '*lo'.

> +        if (p->exp <= DECOMPOSED_BINARY_POINT) {
> +            hi = 0;
> +            *lo = p->frac_hi >> (DECOMPOSED_BINARY_POINT - p->exp);
> +        } else if (p->exp <= 127) {
> +            int shift = 127 - p->exp;
> +            hi = shr_double(0, p->frac_hi, shift);

Same comment about double-shift w/ 0.

> +            if (N > 64) {
> +                *lo = shr_double(p->frac_hi, p->frac_lo, shift);
> +            } else {
> +                *lo = shr_double(p->frac_hi, 0, shift);
> +            }
> +        } else {
> +            hi = UINT64_MAX;
> +            *lo = UINT64_MAX;
> +        }
> +        if (p->sign) {
> +            if (hi < INT64_MIN || (hi == INT64_MIN && *lo == 0)) {
> +                *lo = -*lo;
> +                hi = ~hi + !*lo;
> +            } else {
> +                flags = float_flag_invalid | float_flag_invalid_cvti;
> +                hi = INT64_MIN;
> +                *lo = 0;
> +            }
> +        } else if (hi > INT64_MAX) {
> +            flags = float_flag_invalid | float_flag_invalid_cvti;
> +            hi = INT64_MAX;
> +            *lo = UINT64_MAX;
> +        }

Hmm.  It seemed easy to arrange the code this way with just a uint64_t, but here I think 
it might be worth detecting overflow earlier, via exp.

     if (p->exp < 127) {
         /* No overflow possible */
         int shift = 127 - p->exp;
         if (shift >= 64) {
             hi = 0;
             lo = p->frac_hi >> (shift - 64);
         } else {
             hi = p->frac_hi >> shift;
             lo = shr_double(p->frac_hi, N > 64 ? p->frac_lo : 0, shift);
         }
         if (p->sign) {
             lo = -lo;
             hi = ~hi + !lo;
         }
         break;
     }
     /* The only valid 127-bit number is UINT128_MIN. */
     if (p->exp == 127 &&
         p->sign &&
         p->frac_hi == DECOMPOSED_IMPLICIT_BIT &&
         (N <= 64 || p->frac_lo == 0)) {
         hi = INT64_MIN;
         lo = 0;
         break;
     }
     /* Overflow. */
     flags = ...;
     if (p->sign)
         ...


r~


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 5/6] target/ppc: implement xscv[su]qqp
  2022-03-28 20:14 ` [RFC PATCH 5/6] target/ppc: implement xscv[su]qqp matheus.ferst
@ 2022-03-29 12:16   ` Richard Henderson
  0 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2022-03-29 12:16 UTC (permalink / raw)
  To: matheus.ferst, qemu-devel, qemu-ppc; +Cc: groug, danielhb413, clg, david

On 3/28/22 14:14, matheus.ferst@eldorado.org.br wrote:
> From: Matheus Ferst <matheus.ferst@eldorado.org.br>
> 
> Implement the following PowerISA v3.1 instructions:
> xscvsqqp: VSX Scalar Convert with round Signed Quadword to
>            Quad-Precision
> xscvuqqp: VSX Scalar Convert with round Unsigned Quadword to
>            Quad-Precision format
> 
> Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
> ---
>   target/ppc/fpu_helper.c             | 11 +++++++++++
>   target/ppc/helper.h                 |  2 ++
>   target/ppc/insn32.decode            |  5 +++++
>   target/ppc/translate/vsx-impl.c.inc | 20 ++++++++++++++++++++
>   4 files changed, 38 insertions(+)
> 
> diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
> index 7e8be99cc0..5101ba92ae 100644
> --- a/target/ppc/fpu_helper.c
> +++ b/target/ppc/fpu_helper.c
> @@ -3058,6 +3058,17 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb)        \
>   VSX_CVT_INT_TO_FP2(xvcvsxdsp, int64, float32)
>   VSX_CVT_INT_TO_FP2(xvcvuxdsp, uint64, float32)
>   
> +#define VSX_CVT_INT128_TO_FP(op, tp)                                        \
> +void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb)            \
> +{                                                                           \
> +    xt->f128 = tp##_to_float128(xb->VsrD(0), xb->VsrD(1), &env->fp_status); \
> +    helper_compute_fprf_float128(env, xt->f128);                            \
> +    do_float_check_status(env, GETPC());                                    \
> +}

There seems to be some lack of reset_fpstatus all through the conversion routines.
Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 6/6] target/ppc: implement xscvqp[su]qz
  2022-03-28 20:14 ` [RFC PATCH 6/6] target/ppc: implement xscvqp[su]qz matheus.ferst
@ 2022-03-29 12:18   ` Richard Henderson
  0 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2022-03-29 12:18 UTC (permalink / raw)
  To: matheus.ferst, qemu-devel, qemu-ppc; +Cc: groug, danielhb413, clg, david

On 3/28/22 14:14, matheus.ferst@eldorado.org.br wrote:
> From: Matheus Ferst<matheus.ferst@eldorado.org.br>
> 
> Implement the following PowerISA v3.1 instructions:
> xscvqpsqz: VSX Scalar Convert with round to zero Quad-Precision to
>             Signed Quadword
> xscvqpuqz: VSX Scalar Convert with round to zero Quad-Precision to
>             Unsigned Quadword
> 
> Signed-off-by: Matheus Ferst<matheus.ferst@eldorado.org.br>
> ---
>   target/ppc/fpu_helper.c             | 23 +++++++++++++++++++++++
>   target/ppc/helper.h                 |  2 ++
>   target/ppc/insn32.decode            |  2 ++
>   target/ppc/translate/vsx-impl.c.inc |  2 ++
>   4 files changed, 29 insertions(+)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 0/6] softfloat 128-bit integer support
  2022-03-29  3:38 ` [RFC PATCH 0/6] softfloat 128-bit integer support Richard Henderson
@ 2022-03-30 17:59   ` Matheus K. Ferst
  0 siblings, 0 replies; 15+ messages in thread
From: Matheus K. Ferst @ 2022-03-30 17:59 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-ppc; +Cc: groug, danielhb413, clg, david

On 29/03/2022 00:38, Richard Henderson wrote:
> On 3/28/22 14:14, matheus.ferst@eldorado.org.br wrote:
>> From: Matheus Ferst <matheus.ferst@eldorado.org.br>
>>
>> This RFC is a first attempt at implementing the 128-bit integer
>> conversion routines in softfloat, as required by the xscv[su]qqp and
>> xscvqp[su]qz instructions of PowerISA v3.1.
>>
>> Instead of using int128.h, int-to-float routines receive the 128-bit
>> numbers through a pair of 64-bit values, and float-to-int conversions
>> use a pointer to return the lower half of the result.
>>
>> We only need the parts128 methods, but since the difference to parts64
>> ones seemed minor, I included both in this patch.
>>
>> RFC:
>>   - Should we use struct Int128 instead of 64-bit value pairs?
> 
> I think so.  We have it, and it makes the interface more obvious.
> 
>>   - I've not tested the float64 methods since the PPC instructions only
>>     use the quad-precision routines. Should we keep them in the final
>>     version?
> 
> Let's not add anything that we don't have a need for.
> It may eventually be needed by RISC-V RV128, but we can add it then.
> 
> 
> r~

Thanks for your comments and review. I'll send an alternative version of 
this RFC using Int128.

-- 
Matheus K. Ferst
Instituto de Pesquisas ELDORADO <http://www.eldorado.org.br/>
Analista de Software
Aviso Legal - Disclaimer <https://www.eldorado.org.br/disclaimer.html>

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2022-03-30 18:03 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-28 20:14 [RFC PATCH 0/6] softfloat 128-bit integer support matheus.ferst
2022-03-28 20:14 ` [RFC PATCH 1/6] softfloat: add uint128_to_float* conversion methods matheus.ferst
2022-03-29 11:28   ` Richard Henderson
2022-03-28 20:14 ` [RFC PATCH 2/6] softfloat: add int128_to_float* " matheus.ferst
2022-03-29 11:40   ` Richard Henderson
2022-03-28 20:14 ` [RFC PATCH 3/6] softfloat: add float*_to_uint128 " matheus.ferst
2022-03-29 11:48   ` Richard Henderson
2022-03-28 20:14 ` [RFC PATCH 4/6] softfloat: add float*_to_int128 " matheus.ferst
2022-03-29 12:10   ` Richard Henderson
2022-03-28 20:14 ` [RFC PATCH 5/6] target/ppc: implement xscv[su]qqp matheus.ferst
2022-03-29 12:16   ` Richard Henderson
2022-03-28 20:14 ` [RFC PATCH 6/6] target/ppc: implement xscvqp[su]qz matheus.ferst
2022-03-29 12:18   ` Richard Henderson
2022-03-29  3:38 ` [RFC PATCH 0/6] softfloat 128-bit integer support Richard Henderson
2022-03-30 17:59   ` Matheus K. Ferst

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.