* [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.