* [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14
@ 2021-05-17 14:27 David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 01/26] s390x/tcg: Fix FP CONVERT TO (LOGICAL) FIXED NaN handling David Hildenbrand
` (25 more replies)
0 siblings, 26 replies; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
This series adds support for the "Vector enhancements facility" and bumps
the qemu CPU model to a stripped-down z14.
I tested most vector FP instructions by generating random instructions
and vectors, comparing the result with results on actual hardware. I did
not test instructions/instruction variants with (partial) undeterministic
behavior and exception handling.
Linux' also seems to boot/work fine with it. Howeever, while testing this
series I noticed that Linux checks for the wrong facility bit - see [1].
I tested by temporarily faking availability of the "wrong" facility bit.
[1] https://lkml.kernel.org/r/20210503121244.25232-1-david@redhat.com
v1 -> v2:
- Too much changed to spell it out explicitly. Mostly addressed feedback
from Richard, a couple of bugfixes found while testing, and some
simplifications/cleanups.
- Rebased on top of Richard's softfloat rework
Based-on: 20210508014802.892561-1-richard.henderson@linaro.org
Cc: qemu-s390x@nongnu.org
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Halil Pasic <pasic@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Thomas Huth <thuth@redhat.com>
Cc: Richard Henderson <richard.henderson@linaro.org>
David Hildenbrand (26):
s390x/tcg: Fix FP CONVERT TO (LOGICAL) FIXED NaN handling
s390x/tcg: Fix instruction name for VECTOR FP LOAD
(LENGTHENED|ROUNDED)
s390x/tcg: Simplify vop64_3() handling
s390x/tcg: Simplify vop64_2() handling
s390x/tcg: Simplify vfc64() handling
s390x/tcg: Simplify vftci64() handling
s390x/tcg: Simplify vfma64() handling
s390x/tcg: Simplify vfll32() handling
s390x/tcg: Simplify vflr64() handling
s390x/tcg: Simplify wfc64() handling
s390x/tcg: Implement VECTOR BIT PERMUTE
s390x/tcg: Implement VECTOR MULTIPLY SUM LOGICAL
s390x/tcg: Implement 32/128 bit for VECTOR FP
(ADD|DIVIDE|MULTIPLY|SUBTRACT)
s390x/tcg: Implement 32/128 bit for VECTOR (LOAD FP INTEGER|FP SQUARE
ROOT)
s390x/tcg: Implement 32/128 bit for VECTOR FP COMPARE *
s390x/tcg: Implement 32/128 bit for VECTOR FP COMPARE (AND SIGNAL)
SCALAR
s390x/tcg: Implement 64 bit for VECTOR FP LOAD LENGTHENED
s390x/tcg: Implement 128 bit for VECTOR FP LOAD ROUNDED
s390x/tcg: Implement 32/128 bit for VECTOR FP PERFORM SIGN OPERATION
s390x/tcg: Implement 32/128 bit for VECTOR FP TEST DATA CLASS
IMMEDIATE
s390x/tcg: Implement 32/128 bit for VECTOR FP MULTIPLY AND
(ADD|SUBTRACT)
s390x/tcg: Implement VECTOR FP NEGATIVE MULTIPLY AND (ADD|SUBTRACT)
softfloat: Implement
float128_(min|minnum|minnummag|max|maxnum|maxnummag)
s390x/tcg: Implement VECTOR FP (MAXIMUM|MINIMUM)
s390x/tcg: We support Vector enhancements facility
s390x/cpumodel: Bump up QEMU model to a stripped-down IBM z14 GA2
fpu/softfloat.c | 17 +
hw/s390x/s390-virtio-ccw.c | 3 +
include/fpu/softfloat.h | 6 +
target/s390x/cpu_models.c | 4 +-
target/s390x/fpu_helper.c | 41 +-
target/s390x/gen-features.c | 14 +-
target/s390x/helper.h | 70 +-
target/s390x/insn-data.def | 16 +-
target/s390x/internal.h | 9 +
target/s390x/translate_vx.c.inc | 633 ++++++++++++++----
target/s390x/vec_fpu_helper.c | 1114 ++++++++++++++++++++++---------
target/s390x/vec_helper.c | 22 +
12 files changed, 1478 insertions(+), 471 deletions(-)
--
2.31.1
^ permalink raw reply [flat|nested] 50+ messages in thread
* [PATCH v2 01/26] s390x/tcg: Fix FP CONVERT TO (LOGICAL) FIXED NaN handling
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-01 21:27 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 02/26] s390x/tcg: Fix instruction name for VECTOR FP LOAD (LENGTHENED|ROUNDED) David Hildenbrand
` (24 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
In case we encounter a NaN, we have to return the smallest possible
number, corresponding to either 0 or the maximum negative number. This
seems to differ from IEEE handling as implemented in softfloat, whereby
we return the biggest possible number.
While at it, use float32_to_uint64() in the CLGEB handler.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/fpu_helper.c | 41 +++++++++++++++++++++++++++++++----
target/s390x/vec_fpu_helper.c | 6 +++++
2 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/target/s390x/fpu_helper.c b/target/s390x/fpu_helper.c
index f155bc048c..13af158748 100644
--- a/target/s390x/fpu_helper.c
+++ b/target/s390x/fpu_helper.c
@@ -509,6 +509,9 @@ uint64_t HELPER(cgeb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
s390_restore_bfp_rounding_mode(env, old_mode);
handle_exceptions(env, xxc_from_m34(m34), GETPC());
+ if (float32_is_any_nan(v2)) {
+ return INT64_MIN;
+ }
return ret;
}
@@ -520,6 +523,9 @@ uint64_t HELPER(cgdb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
s390_restore_bfp_rounding_mode(env, old_mode);
handle_exceptions(env, xxc_from_m34(m34), GETPC());
+ if (float64_is_any_nan(v2)) {
+ return INT64_MIN;
+ }
return ret;
}
@@ -532,6 +538,9 @@ uint64_t HELPER(cgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
s390_restore_bfp_rounding_mode(env, old_mode);
handle_exceptions(env, xxc_from_m34(m34), GETPC());
+ if (float128_is_any_nan(v2)) {
+ return INT64_MIN;
+ }
return ret;
}
@@ -543,6 +552,9 @@ uint64_t HELPER(cfeb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
s390_restore_bfp_rounding_mode(env, old_mode);
handle_exceptions(env, xxc_from_m34(m34), GETPC());
+ if (float32_is_any_nan(v2)) {
+ return INT32_MIN;
+ }
return ret;
}
@@ -554,6 +566,9 @@ uint64_t HELPER(cfdb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
s390_restore_bfp_rounding_mode(env, old_mode);
handle_exceptions(env, xxc_from_m34(m34), GETPC());
+ if (float64_is_any_nan(v2)) {
+ return INT32_MIN;
+ }
return ret;
}
@@ -566,6 +581,9 @@ uint64_t HELPER(cfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
s390_restore_bfp_rounding_mode(env, old_mode);
handle_exceptions(env, xxc_from_m34(m34), GETPC());
+ if (float128_is_any_nan(v2)) {
+ return INT32_MIN;
+ }
return ret;
}
@@ -573,12 +591,12 @@ uint64_t HELPER(cfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
uint64_t HELPER(clgeb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
{
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
- uint64_t ret;
-
- v2 = float32_to_float64(v2, &env->fpu_status);
- ret = float64_to_uint64(v2, &env->fpu_status);
+ uint64_t ret = float32_to_uint64(v2, &env->fpu_status);
s390_restore_bfp_rounding_mode(env, old_mode);
handle_exceptions(env, xxc_from_m34(m34), GETPC());
+ if (float32_is_any_nan(v2)) {
+ return 0;
+ }
return ret;
}
@@ -590,6 +608,9 @@ uint64_t HELPER(clgdb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
s390_restore_bfp_rounding_mode(env, old_mode);
handle_exceptions(env, xxc_from_m34(m34), GETPC());
+ if (float64_is_any_nan(v2)) {
+ return 0;
+ }
return ret;
}
@@ -601,6 +622,9 @@ uint64_t HELPER(clgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
s390_restore_bfp_rounding_mode(env, old_mode);
handle_exceptions(env, xxc_from_m34(m34), GETPC());
+ if (float128_is_any_nan(make_float128(h, l))) {
+ return 0;
+ }
return ret;
}
@@ -612,6 +636,9 @@ uint64_t HELPER(clfeb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
s390_restore_bfp_rounding_mode(env, old_mode);
handle_exceptions(env, xxc_from_m34(m34), GETPC());
+ if (float32_is_any_nan(v2)) {
+ return 0;
+ }
return ret;
}
@@ -623,6 +650,9 @@ uint64_t HELPER(clfdb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
s390_restore_bfp_rounding_mode(env, old_mode);
handle_exceptions(env, xxc_from_m34(m34), GETPC());
+ if (float64_is_any_nan(v2)) {
+ return 0;
+ }
return ret;
}
@@ -634,6 +664,9 @@ uint64_t HELPER(clfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
s390_restore_bfp_rounding_mode(env, old_mode);
handle_exceptions(env, xxc_from_m34(m34), GETPC());
+ if (float128_is_any_nan(make_float128(h, l))) {
+ return 0;
+ }
return ret;
}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index c1564e819b..d485837930 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -326,6 +326,9 @@ void HELPER(gvec_vcdlg64s)(void *v1, const void *v2, CPUS390XState *env,
static uint64_t vcgd64(uint64_t a, float_status *s)
{
+ if (float64_is_any_nan(a)) {
+ return INT64_MIN;
+ }
return float64_to_int64(a, s);
}
@@ -349,6 +352,9 @@ void HELPER(gvec_vcgd64s)(void *v1, const void *v2, CPUS390XState *env,
static uint64_t vclgd64(uint64_t a, float_status *s)
{
+ if (float64_is_any_nan(a)) {
+ return 0;
+ }
return float64_to_uint64(a, s);
}
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 02/26] s390x/tcg: Fix instruction name for VECTOR FP LOAD (LENGTHENED|ROUNDED)
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 01/26] s390x/tcg: Fix FP CONVERT TO (LOGICAL) FIXED NaN handling David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-01 21:27 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 03/26] s390x/tcg: Simplify vop64_3() handling David Hildenbrand
` (23 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
Let's use the correct name.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/insn-data.def | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 0bb1886a2e..35a0086a85 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1245,9 +1245,9 @@
F(0xe7e5, VFD, VRR_c, V, 0, 0, 0, 0, vfa, 0, IF_VEC)
/* VECTOR LOAD FP INTEGER */
F(0xe7c7, VFI, VRR_a, V, 0, 0, 0, 0, vcdg, 0, IF_VEC)
-/* VECTOR LOAD LENGTHENED */
+/* VECTOR FP LOAD LENGTHENED */
F(0xe7c4, VFLL, VRR_a, V, 0, 0, 0, 0, vfll, 0, IF_VEC)
-/* VECTOR LOAD ROUNDED */
+/* VECTOR FP LOAD ROUNDED */
F(0xe7c5, VFLR, VRR_a, V, 0, 0, 0, 0, vcdg, 0, IF_VEC)
/* VECTOR FP MULTIPLY */
F(0xe7e7, VFM, VRR_c, V, 0, 0, 0, 0, vfa, 0, IF_VEC)
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 03/26] s390x/tcg: Simplify vop64_3() handling
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 01/26] s390x/tcg: Fix FP CONVERT TO (LOGICAL) FIXED NaN handling David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 02/26] s390x/tcg: Fix instruction name for VECTOR FP LOAD (LENGTHENED|ROUNDED) David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-03 17:10 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 04/26] s390x/tcg: Simplify vop64_2() handling David Hildenbrand
` (22 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
Let's simplify, reworking our handler generation, passing the whole "m5"
register content and not providing specialized handlers for "se", and
reading/writing proper float64 values using new helpers.
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 4 --
target/s390x/translate_vx.c.inc | 11 ++--
target/s390x/vec_fpu_helper.c | 94 +++++++++------------------------
3 files changed, 30 insertions(+), 79 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index d4e4f3388f..2344f81273 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -247,7 +247,6 @@ DEF_HELPER_6(gvec_vstrc_cc_rt32, void, ptr, cptr, cptr, cptr, env, i32)
/* === Vector Floating-Point Instructions */
DEF_HELPER_FLAGS_5(gvec_vfa64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
-DEF_HELPER_FLAGS_5(gvec_vfa64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_4(gvec_wfc64, void, cptr, cptr, env, i32)
DEF_HELPER_4(gvec_wfk64, void, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfce64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
@@ -271,7 +270,6 @@ DEF_HELPER_FLAGS_4(gvec_vcgd64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vclgd64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vclgd64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfd64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
-DEF_HELPER_FLAGS_5(gvec_vfd64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfi64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfi64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfll32, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
@@ -279,7 +277,6 @@ DEF_HELPER_FLAGS_4(gvec_vfll32s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vflr64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vflr64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
-DEF_HELPER_FLAGS_5(gvec_vfm64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfma64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfma64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfms64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
@@ -287,7 +284,6 @@ DEF_HELPER_FLAGS_6(gvec_vfms64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, en
DEF_HELPER_FLAGS_4(gvec_vfsq64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfsq64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfs64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
-DEF_HELPER_FLAGS_5(gvec_vfs64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_4(gvec_vftci64, void, ptr, cptr, env, i32)
DEF_HELPER_4(gvec_vftci64s, void, ptr, cptr, env, i32)
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index eb767f5288..2d3fbdfab2 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2443,7 +2443,6 @@ static DisasJumpType op_vfa(DisasContext *s, DisasOps *o)
{
const uint8_t fpf = get_field(s, m4);
const uint8_t m5 = get_field(s, m5);
- const bool se = extract32(m5, 3, 1);
gen_helper_gvec_3_ptr *fn;
if (fpf != FPF_LONG || extract32(m5, 0, 3)) {
@@ -2453,22 +2452,22 @@ static DisasJumpType op_vfa(DisasContext *s, DisasOps *o)
switch (s->fields.op2) {
case 0xe3:
- fn = se ? gen_helper_gvec_vfa64s : gen_helper_gvec_vfa64;
+ fn = gen_helper_gvec_vfa64;
break;
case 0xe5:
- fn = se ? gen_helper_gvec_vfd64s : gen_helper_gvec_vfd64;
+ fn = gen_helper_gvec_vfd64;
break;
case 0xe7:
- fn = se ? gen_helper_gvec_vfm64s : gen_helper_gvec_vfm64;
+ fn = gen_helper_gvec_vfm64;
break;
case 0xe2:
- fn = se ? gen_helper_gvec_vfs64s : gen_helper_gvec_vfs64;
+ fn = gen_helper_gvec_vfs64;
break;
default:
g_assert_not_reached();
}
gen_gvec_3_ptr(get_field(s, v1), get_field(s, v2),
- get_field(s, v3), cpu_env, 0, fn);
+ get_field(s, v3), cpu_env, m5, fn);
return DISAS_NEXT;
}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index d485837930..f33ee6e774 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -78,6 +78,16 @@ static void handle_ieee_exc(CPUS390XState *env, uint8_t vxc, uint8_t vec_exc,
}
}
+static float64 s390_vec_read_float64(const S390Vector *v, uint8_t enr)
+{
+ return make_float64(s390_vec_read_element64(v, enr));
+}
+
+static void s390_vec_write_float64(S390Vector *v, uint8_t enr, float64 data)
+{
+ return s390_vec_write_element64(v, enr, data);
+}
+
typedef uint64_t (*vop64_2_fn)(uint64_t a, float_status *s);
static void vop64_2(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
bool s, bool XxC, uint8_t erm, vop64_2_fn fn,
@@ -102,7 +112,7 @@ static void vop64_2(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
*v1 = tmp;
}
-typedef uint64_t (*vop64_3_fn)(uint64_t a, uint64_t b, float_status *s);
+typedef float64 (*vop64_3_fn)(float64 a, float64 b, float_status *s);
static void vop64_3(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
CPUS390XState *env, bool s, vop64_3_fn fn,
uintptr_t retaddr)
@@ -112,10 +122,10 @@ static void vop64_3(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
int i;
for (i = 0; i < 2; i++) {
- const uint64_t a = s390_vec_read_element64(v2, i);
- const uint64_t b = s390_vec_read_element64(v3, i);
+ const float64 a = s390_vec_read_float64(v2, i);
+ const float64 b = s390_vec_read_float64(v3, i);
- s390_vec_write_element64(&tmp, i, fn(a, b, &env->fpu_status));
+ s390_vec_write_float64(&tmp, i, fn(a, b, &env->fpu_status));
vxc = check_ieee_exc(env, i, false, &vec_exc);
if (s || vxc) {
break;
@@ -125,22 +135,19 @@ static void vop64_3(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
*v1 = tmp;
}
-static uint64_t vfa64(uint64_t a, uint64_t b, float_status *s)
-{
- return float64_add(a, b, s);
+#define DEF_GVEC_VOP3(NAME, OP) \
+void HELPER(gvec_##NAME##64)(void *v1, const void *v2, const void *v3, \
+ CPUS390XState *env, uint32_t desc) \
+{ \
+ const bool se = extract32(simd_data(desc), 3, 1); \
+ \
+ vop64_3(v1, v2, v3, env, se, float64_##OP, GETPC()); \
}
-void HELPER(gvec_vfa64)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- vop64_3(v1, v2, v3, env, false, vfa64, GETPC());
-}
-
-void HELPER(gvec_vfa64s)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- vop64_3(v1, v2, v3, env, true, vfa64, GETPC());
-}
+DEF_GVEC_VOP3(vfa, add)
+DEF_GVEC_VOP3(vfs, sub)
+DEF_GVEC_VOP3(vfd, div)
+DEF_GVEC_VOP3(vfm, mul)
static int wfc64(const S390Vector *v1, const S390Vector *v2,
CPUS390XState *env, bool signal, uintptr_t retaddr)
@@ -376,23 +383,6 @@ void HELPER(gvec_vclgd64s)(void *v1, const void *v2, CPUS390XState *env,
vop64_2(v1, v2, env, true, XxC, erm, vclgd64, GETPC());
}
-static uint64_t vfd64(uint64_t a, uint64_t b, float_status *s)
-{
- return float64_div(a, b, s);
-}
-
-void HELPER(gvec_vfd64)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- vop64_3(v1, v2, v3, env, false, vfd64, GETPC());
-}
-
-void HELPER(gvec_vfd64s)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- vop64_3(v1, v2, v3, env, true, vfd64, GETPC());
-}
-
static uint64_t vfi64(uint64_t a, float_status *s)
{
return float64_round_to_int(a, s);
@@ -494,23 +484,6 @@ void HELPER(gvec_vflr64s)(void *v1, const void *v2, CPUS390XState *env,
vflr64(v1, v2, env, true, XxC, erm, GETPC());
}
-static uint64_t vfm64(uint64_t a, uint64_t b, float_status *s)
-{
- return float64_mul(a, b, s);
-}
-
-void HELPER(gvec_vfm64)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- vop64_3(v1, v2, v3, env, false, vfm64, GETPC());
-}
-
-void HELPER(gvec_vfm64s)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- vop64_3(v1, v2, v3, env, true, vfm64, GETPC());
-}
-
static void vfma64(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
const S390Vector *v4, CPUS390XState *env, bool s, int flags,
uintptr_t retaddr)
@@ -576,23 +549,6 @@ void HELPER(gvec_vfsq64s)(void *v1, const void *v2, CPUS390XState *env,
vop64_2(v1, v2, env, true, false, 0, vfsq64, GETPC());
}
-static uint64_t vfs64(uint64_t a, uint64_t b, float_status *s)
-{
- return float64_sub(a, b, s);
-}
-
-void HELPER(gvec_vfs64)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- vop64_3(v1, v2, v3, env, false, vfs64, GETPC());
-}
-
-void HELPER(gvec_vfs64s)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- vop64_3(v1, v2, v3, env, true, vfs64, GETPC());
-}
-
static int vftci64(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
bool s, uint16_t i3)
{
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 04/26] s390x/tcg: Simplify vop64_2() handling
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (2 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 03/26] s390x/tcg: Simplify vop64_3() handling David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-03 17:16 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 05/26] s390x/tcg: Simplify vfc64() handling David Hildenbrand
` (21 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
Let's rework our macros and simplify. We still need helper functions in
most cases due to the different parameters types.
Next, we'll only have 32/128bit variants for vfi and vfsq, so special
case the others.
Note that for vfsq, the XxC and erm passed in the simd_data() will never be
set, resulting in the same behavior.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 6 -
target/s390x/translate_vx.c.inc | 18 ++-
target/s390x/vec_fpu_helper.c | 194 +++++++++-----------------------
3 files changed, 60 insertions(+), 158 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 2344f81273..4788c1ddaf 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -262,16 +262,11 @@ DEF_HELPER_FLAGS_5(gvec_vfche64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i3
DEF_HELPER_5(gvec_vfche64_cc, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_5(gvec_vfche64s_cc, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vcdg64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
-DEF_HELPER_FLAGS_4(gvec_vcdg64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vcdlg64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
-DEF_HELPER_FLAGS_4(gvec_vcdlg64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vcgd64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
-DEF_HELPER_FLAGS_4(gvec_vcgd64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vclgd64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
-DEF_HELPER_FLAGS_4(gvec_vclgd64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfd64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfi64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
-DEF_HELPER_FLAGS_4(gvec_vfi64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfll32, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfll32s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vflr64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
@@ -282,7 +277,6 @@ DEF_HELPER_FLAGS_6(gvec_vfma64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, en
DEF_HELPER_FLAGS_6(gvec_vfms64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfms64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfsq64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
-DEF_HELPER_FLAGS_4(gvec_vfsq64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfs64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_4(gvec_vftci64, void, ptr, cptr, env, i32)
DEF_HELPER_4(gvec_vftci64s, void, ptr, cptr, env, i32)
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 2d3fbdfab2..280d45bb19 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2558,19 +2558,19 @@ static DisasJumpType op_vcdg(DisasContext *s, DisasOps *o)
switch (s->fields.op2) {
case 0xc3:
- fn = se ? gen_helper_gvec_vcdg64s : gen_helper_gvec_vcdg64;
+ fn = gen_helper_gvec_vcdg64;
break;
case 0xc1:
- fn = se ? gen_helper_gvec_vcdlg64s : gen_helper_gvec_vcdlg64;
+ fn = gen_helper_gvec_vcdlg64;
break;
case 0xc2:
- fn = se ? gen_helper_gvec_vcgd64s : gen_helper_gvec_vcgd64;
+ fn = gen_helper_gvec_vcgd64;
break;
case 0xc0:
- fn = se ? gen_helper_gvec_vclgd64s : gen_helper_gvec_vclgd64;
+ fn = gen_helper_gvec_vclgd64;
break;
case 0xc7:
- fn = se ? gen_helper_gvec_vfi64s : gen_helper_gvec_vfi64;
+ fn = gen_helper_gvec_vfi64;
break;
case 0xc5:
fn = se ? gen_helper_gvec_vflr64s : gen_helper_gvec_vflr64;
@@ -2681,18 +2681,14 @@ static DisasJumpType op_vfsq(DisasContext *s, DisasOps *o)
{
const uint8_t fpf = get_field(s, m3);
const uint8_t m4 = get_field(s, m4);
- gen_helper_gvec_2_ptr *fn = gen_helper_gvec_vfsq64;
if (fpf != FPF_LONG || extract32(m4, 0, 3)) {
gen_program_exception(s, PGM_SPECIFICATION);
return DISAS_NORETURN;
}
- if (extract32(m4, 3, 1)) {
- fn = gen_helper_gvec_vfsq64s;
- }
- gen_gvec_2_ptr(get_field(s, v1), get_field(s, v2), cpu_env,
- 0, fn);
+ gen_gvec_2_ptr(get_field(s, v1), get_field(s, v2), cpu_env, m4,
+ gen_helper_gvec_vfsq64);
return DISAS_NEXT;
}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index f33ee6e774..da5862d6c6 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -88,7 +88,7 @@ static void s390_vec_write_float64(S390Vector *v, uint8_t enr, float64 data)
return s390_vec_write_element64(v, enr, data);
}
-typedef uint64_t (*vop64_2_fn)(uint64_t a, float_status *s);
+typedef float64 (*vop64_2_fn)(float64 a, float_status *s);
static void vop64_2(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
bool s, bool XxC, uint8_t erm, vop64_2_fn fn,
uintptr_t retaddr)
@@ -99,9 +99,9 @@ static void vop64_2(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
old_mode = s390_swap_bfp_rounding_mode(env, erm);
for (i = 0; i < 2; i++) {
- const uint64_t a = s390_vec_read_element64(v2, i);
+ const float64 a = s390_vec_read_float64(v2, i);
- s390_vec_write_element64(&tmp, i, fn(a, &env->fpu_status));
+ s390_vec_write_float64(&tmp, i, fn(a, &env->fpu_status));
vxc = check_ieee_exc(env, i, XxC, &vec_exc);
if (s || vxc) {
break;
@@ -112,6 +112,56 @@ static void vop64_2(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
*v1 = tmp;
}
+static float64 vcdg64(float64 a, float_status *s)
+{
+ return int64_to_float64(a, s);
+}
+
+static float64 vcdlg64(float64 a, float_status *s)
+{
+ return uint64_to_float64(a, s);
+}
+
+static float64 vcgd64(float64 a, float_status *s)
+{
+ if (float64_is_any_nan(a)) {
+ return INT64_MIN;
+ }
+ return float64_to_int64(a, s);
+}
+
+static float64 vclgd64(float64 a, float_status *s)
+{
+ if (float64_is_any_nan(a)) {
+ return 0;
+ }
+ return float64_to_uint64(a, s);
+}
+
+#define DEF_GVEC_VOP2_FN(NAME, FN, BITS) \
+void HELPER(gvec_##NAME##BITS)(void *v1, const void *v2, CPUS390XState *env, \
+ uint32_t desc) \
+{ \
+ const uint8_t erm = extract32(simd_data(desc), 4, 4); \
+ const uint8_t se = extract32(simd_data(desc), 3, 1); \
+ const bool XxC = extract32(simd_data(desc), 2, 1); \
+ \
+ vop##BITS##_2(v1, v2, env, se, XxC, erm, FN, GETPC()); \
+}
+
+#define DEF_GVEC_VOP2_64(NAME) \
+DEF_GVEC_VOP2_FN(NAME, NAME##64, 64)
+
+#define DEF_GVEC_VOP2(NAME, OP) \
+DEF_GVEC_VOP2_FN(NAME, float64_##OP, 64)
+
+DEF_GVEC_VOP2_64(vcdg)
+DEF_GVEC_VOP2_64(vcdlg)
+DEF_GVEC_VOP2_64(vcgd)
+DEF_GVEC_VOP2_64(vclgd)
+DEF_GVEC_VOP2(vfi, round_to_int)
+DEF_GVEC_VOP2(vfsq, sqrt)
+
typedef float64 (*vop64_3_fn)(float64 a, float64 b, float_status *s);
static void vop64_3(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
CPUS390XState *env, bool s, vop64_3_fn fn,
@@ -285,127 +335,6 @@ void HELPER(gvec_vfche64s_cc)(void *v1, const void *v2, const void *v3,
env->cc_op = vfc64(v1, v2, v3, env, true, float64_le_quiet, GETPC());
}
-static uint64_t vcdg64(uint64_t a, float_status *s)
-{
- return int64_to_float64(a, s);
-}
-
-void HELPER(gvec_vcdg64)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- const uint8_t erm = extract32(simd_data(desc), 4, 4);
- const bool XxC = extract32(simd_data(desc), 2, 1);
-
- vop64_2(v1, v2, env, false, XxC, erm, vcdg64, GETPC());
-}
-
-void HELPER(gvec_vcdg64s)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- const uint8_t erm = extract32(simd_data(desc), 4, 4);
- const bool XxC = extract32(simd_data(desc), 2, 1);
-
- vop64_2(v1, v2, env, true, XxC, erm, vcdg64, GETPC());
-}
-
-static uint64_t vcdlg64(uint64_t a, float_status *s)
-{
- return uint64_to_float64(a, s);
-}
-
-void HELPER(gvec_vcdlg64)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- const uint8_t erm = extract32(simd_data(desc), 4, 4);
- const bool XxC = extract32(simd_data(desc), 2, 1);
-
- vop64_2(v1, v2, env, false, XxC, erm, vcdlg64, GETPC());
-}
-
-void HELPER(gvec_vcdlg64s)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- const uint8_t erm = extract32(simd_data(desc), 4, 4);
- const bool XxC = extract32(simd_data(desc), 2, 1);
-
- vop64_2(v1, v2, env, true, XxC, erm, vcdlg64, GETPC());
-}
-
-static uint64_t vcgd64(uint64_t a, float_status *s)
-{
- if (float64_is_any_nan(a)) {
- return INT64_MIN;
- }
- return float64_to_int64(a, s);
-}
-
-void HELPER(gvec_vcgd64)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- const uint8_t erm = extract32(simd_data(desc), 4, 4);
- const bool XxC = extract32(simd_data(desc), 2, 1);
-
- vop64_2(v1, v2, env, false, XxC, erm, vcgd64, GETPC());
-}
-
-void HELPER(gvec_vcgd64s)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- const uint8_t erm = extract32(simd_data(desc), 4, 4);
- const bool XxC = extract32(simd_data(desc), 2, 1);
-
- vop64_2(v1, v2, env, true, XxC, erm, vcgd64, GETPC());
-}
-
-static uint64_t vclgd64(uint64_t a, float_status *s)
-{
- if (float64_is_any_nan(a)) {
- return 0;
- }
- return float64_to_uint64(a, s);
-}
-
-void HELPER(gvec_vclgd64)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- const uint8_t erm = extract32(simd_data(desc), 4, 4);
- const bool XxC = extract32(simd_data(desc), 2, 1);
-
- vop64_2(v1, v2, env, false, XxC, erm, vclgd64, GETPC());
-}
-
-void HELPER(gvec_vclgd64s)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- const uint8_t erm = extract32(simd_data(desc), 4, 4);
- const bool XxC = extract32(simd_data(desc), 2, 1);
-
- vop64_2(v1, v2, env, true, XxC, erm, vclgd64, GETPC());
-}
-
-static uint64_t vfi64(uint64_t a, float_status *s)
-{
- return float64_round_to_int(a, s);
-}
-
-void HELPER(gvec_vfi64)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- const uint8_t erm = extract32(simd_data(desc), 4, 4);
- const bool XxC = extract32(simd_data(desc), 2, 1);
-
- vop64_2(v1, v2, env, false, XxC, erm, vfi64, GETPC());
-}
-
-void HELPER(gvec_vfi64s)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- const uint8_t erm = extract32(simd_data(desc), 4, 4);
- const bool XxC = extract32(simd_data(desc), 2, 1);
-
- vop64_2(v1, v2, env, true, XxC, erm, vfi64, GETPC());
-}
-
static void vfll32(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
bool s, uintptr_t retaddr)
{
@@ -532,23 +461,6 @@ void HELPER(gvec_vfms64s)(void *v1, const void *v2, const void *v3,
vfma64(v1, v2, v3, v4, env, true, float_muladd_negate_c, GETPC());
}
-static uint64_t vfsq64(uint64_t a, float_status *s)
-{
- return float64_sqrt(a, s);
-}
-
-void HELPER(gvec_vfsq64)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- vop64_2(v1, v2, env, false, false, 0, vfsq64, GETPC());
-}
-
-void HELPER(gvec_vfsq64s)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- vop64_2(v1, v2, env, true, false, 0, vfsq64, GETPC());
-}
-
static int vftci64(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
bool s, uint16_t i3)
{
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 05/26] s390x/tcg: Simplify vfc64() handling
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (3 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 04/26] s390x/tcg: Simplify vop64_2() handling David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-03 17:18 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 06/26] s390x/tcg: Simplify vftci64() handling David Hildenbrand
` (20 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
Pass the m5 field via simd_data() and don't provide specialized handlers
for single-element variants.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 6 ---
target/s390x/translate_vx.c.inc | 45 +++++-----------
target/s390x/vec_fpu_helper.c | 94 +++++++++------------------------
3 files changed, 38 insertions(+), 107 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 4788c1ddaf..02a16924a7 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -250,17 +250,11 @@ DEF_HELPER_FLAGS_5(gvec_vfa64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_4(gvec_wfc64, void, cptr, cptr, env, i32)
DEF_HELPER_4(gvec_wfk64, void, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfce64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
-DEF_HELPER_FLAGS_5(gvec_vfce64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_5(gvec_vfce64_cc, void, ptr, cptr, cptr, env, i32)
-DEF_HELPER_5(gvec_vfce64s_cc, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfch64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
-DEF_HELPER_FLAGS_5(gvec_vfch64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_5(gvec_vfch64_cc, void, ptr, cptr, cptr, env, i32)
-DEF_HELPER_5(gvec_vfch64s_cc, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfche64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
-DEF_HELPER_FLAGS_5(gvec_vfche64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_5(gvec_vfche64_cc, void, ptr, cptr, cptr, env, i32)
-DEF_HELPER_5(gvec_vfche64s_cc, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vcdg64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vcdlg64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vcgd64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 280d45bb19..604ae11024 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2497,7 +2497,6 @@ static DisasJumpType op_vfc(DisasContext *s, DisasOps *o)
const uint8_t fpf = get_field(s, m4);
const uint8_t m5 = get_field(s, m5);
const uint8_t m6 = get_field(s, m6);
- const bool se = extract32(m5, 3, 1);
const bool cs = extract32(m6, 0, 1);
gen_helper_gvec_3_ptr *fn;
@@ -2506,37 +2505,21 @@ static DisasJumpType op_vfc(DisasContext *s, DisasOps *o)
return DISAS_NORETURN;
}
- if (cs) {
- switch (s->fields.op2) {
- case 0xe8:
- fn = se ? gen_helper_gvec_vfce64s_cc : gen_helper_gvec_vfce64_cc;
- break;
- case 0xeb:
- fn = se ? gen_helper_gvec_vfch64s_cc : gen_helper_gvec_vfch64_cc;
- break;
- case 0xea:
- fn = se ? gen_helper_gvec_vfche64s_cc : gen_helper_gvec_vfche64_cc;
- break;
- default:
- g_assert_not_reached();
- }
- } else {
- switch (s->fields.op2) {
- case 0xe8:
- fn = se ? gen_helper_gvec_vfce64s : gen_helper_gvec_vfce64;
- break;
- case 0xeb:
- fn = se ? gen_helper_gvec_vfch64s : gen_helper_gvec_vfch64;
- break;
- case 0xea:
- fn = se ? gen_helper_gvec_vfche64s : gen_helper_gvec_vfche64;
- break;
- default:
- g_assert_not_reached();
- }
+ switch (s->fields.op2) {
+ case 0xe8:
+ fn = cs ? gen_helper_gvec_vfce64_cc : gen_helper_gvec_vfce64;
+ break;
+ case 0xeb:
+ fn = cs ? gen_helper_gvec_vfch64_cc : gen_helper_gvec_vfch64;
+ break;
+ case 0xea:
+ fn = cs ? gen_helper_gvec_vfche64_cc : gen_helper_gvec_vfche64;
+ break;
+ default:
+ g_assert_not_reached();
}
- gen_gvec_3_ptr(get_field(s, v1), get_field(s, v2),
- get_field(s, v3), cpu_env, 0, fn);
+ gen_gvec_3_ptr(get_field(s, v1), get_field(s, v2), get_field(s, v3),
+ cpu_env, m5, fn);
if (cs) {
set_cc_static(s);
}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index da5862d6c6..793dc77fd1 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -241,8 +241,8 @@ static int vfc64(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
int i;
for (i = 0; i < 2; i++) {
- const float64 a = s390_vec_read_element64(v2, i);
- const float64 b = s390_vec_read_element64(v3, i);
+ const float64 a = s390_vec_read_float64(v2, i);
+ const float64 b = s390_vec_read_float64(v3, i);
/* swap the order of the parameters, so we can use existing functions */
if (fn(b, a, &env->fpu_status)) {
@@ -263,77 +263,31 @@ static int vfc64(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
return 3;
}
-void HELPER(gvec_vfce64)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- vfc64(v1, v2, v3, env, false, float64_eq_quiet, GETPC());
-}
-
-void HELPER(gvec_vfce64s)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- vfc64(v1, v2, v3, env, true, float64_eq_quiet, GETPC());
-}
-
-void HELPER(gvec_vfce64_cc)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- env->cc_op = vfc64(v1, v2, v3, env, false, float64_eq_quiet, GETPC());
-}
-
-void HELPER(gvec_vfce64s_cc)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- env->cc_op = vfc64(v1, v2, v3, env, true, float64_eq_quiet, GETPC());
-}
-
-void HELPER(gvec_vfch64)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- vfc64(v1, v2, v3, env, false, float64_lt_quiet, GETPC());
-}
-
-void HELPER(gvec_vfch64s)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- vfc64(v1, v2, v3, env, true, float64_lt_quiet, GETPC());
-}
-
-void HELPER(gvec_vfch64_cc)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- env->cc_op = vfc64(v1, v2, v3, env, false, float64_lt_quiet, GETPC());
-}
-
-void HELPER(gvec_vfch64s_cc)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- env->cc_op = vfc64(v1, v2, v3, env, true, float64_lt_quiet, GETPC());
-}
-
-void HELPER(gvec_vfche64)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- vfc64(v1, v2, v3, env, false, float64_le_quiet, GETPC());
-}
-
-void HELPER(gvec_vfche64s)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- vfc64(v1, v2, v3, env, true, float64_le_quiet, GETPC());
+#define DEF_GVEC_VFC_B(NAME, OP, BITS) \
+void HELPER(gvec_##NAME##BITS)(void *v1, const void *v2, const void *v3, \
+ CPUS390XState *env, uint32_t desc) \
+{ \
+ const bool se = extract32(simd_data(desc), 3, 1); \
+ vfc##BITS##_fn fn = float##BITS##_##OP##_quiet; \
+ \
+ vfc##BITS(v1, v2, v3, env, se, fn, GETPC()); \
+} \
+ \
+void HELPER(gvec_##NAME##BITS##_cc)(void *v1, const void *v2, const void *v3, \
+ CPUS390XState *env, uint32_t desc) \
+{ \
+ const bool se = extract32(simd_data(desc), 3, 1); \
+ vfc##BITS##_fn fn = float##BITS##_##OP##_quiet; \
+ \
+ env->cc_op = vfc##BITS(v1, v2, v3, env, se, fn, GETPC()); \
}
-void HELPER(gvec_vfche64_cc)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- env->cc_op = vfc64(v1, v2, v3, env, false, float64_le_quiet, GETPC());
-}
+#define DEF_GVEC_VFC(NAME, OP) \
+DEF_GVEC_VFC_B(NAME, OP, 64)
-void HELPER(gvec_vfche64s_cc)(void *v1, const void *v2, const void *v3,
- CPUS390XState *env, uint32_t desc)
-{
- env->cc_op = vfc64(v1, v2, v3, env, true, float64_le_quiet, GETPC());
-}
+DEF_GVEC_VFC(vfce, eq)
+DEF_GVEC_VFC(vfch, lt)
+DEF_GVEC_VFC(vfche, le)
static void vfll32(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
bool s, uintptr_t retaddr)
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 06/26] s390x/tcg: Simplify vftci64() handling
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (4 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 05/26] s390x/tcg: Simplify vfc64() handling David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-03 17:21 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 07/26] s390x/tcg: Simplify vfma64() handling David Hildenbrand
` (19 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 1 -
target/s390x/translate_vx.c.inc | 7 ++-----
target/s390x/vec_fpu_helper.c | 29 +++++++++++------------------
3 files changed, 13 insertions(+), 24 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 02a16924a7..e832680236 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -273,7 +273,6 @@ DEF_HELPER_FLAGS_6(gvec_vfms64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, en
DEF_HELPER_FLAGS_4(gvec_vfsq64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfs64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_4(gvec_vftci64, void, ptr, cptr, env, i32)
-DEF_HELPER_4(gvec_vftci64s, void, ptr, cptr, env, i32)
#ifndef CONFIG_USER_ONLY
DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 604ae11024..1404471881 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2680,17 +2680,14 @@ static DisasJumpType op_vftci(DisasContext *s, DisasOps *o)
const uint16_t i3 = get_field(s, i3);
const uint8_t fpf = get_field(s, m4);
const uint8_t m5 = get_field(s, m5);
- gen_helper_gvec_2_ptr *fn = gen_helper_gvec_vftci64;
if (fpf != FPF_LONG || extract32(m5, 0, 3)) {
gen_program_exception(s, PGM_SPECIFICATION);
return DISAS_NORETURN;
}
- if (extract32(m5, 3, 1)) {
- fn = gen_helper_gvec_vftci64s;
- }
- gen_gvec_2_ptr(get_field(s, v1), get_field(s, v2), cpu_env, i3, fn);
+ gen_gvec_2_ptr(get_field(s, v1), get_field(s, v2), cpu_env,
+ deposit32(m5, 4, 12, i3), gen_helper_gvec_vftci64);
set_cc_static(s);
return DISAS_NEXT;
}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 793dc77fd1..3267067420 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -415,13 +415,15 @@ void HELPER(gvec_vfms64s)(void *v1, const void *v2, const void *v3,
vfma64(v1, v2, v3, v4, env, true, float_muladd_negate_c, GETPC());
}
-static int vftci64(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
- bool s, uint16_t i3)
+void HELPER(gvec_vftci64)(void *v1, const void *v2, CPUS390XState *env,
+ uint32_t desc)
{
+ const uint16_t i3 = extract32(simd_data(desc), 4, 12);
+ const bool s = extract32(simd_data(desc), 3, 1);
int i, match = 0;
for (i = 0; i < 2; i++) {
- float64 a = s390_vec_read_element64(v2, i);
+ const float64 a = s390_vec_read_float64(v2, i);
if (float64_dcmask(env, a) & i3) {
match++;
@@ -434,20 +436,11 @@ static int vftci64(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
}
}
- if (match) {
- return s || match == 2 ? 0 : 1;
+ if (match == 2 || (s && match)) {
+ env->cc_op = 0;
+ } else if (match) {
+ env->cc_op = 1;
+ } else {
+ env->cc_op = 3;
}
- return 3;
-}
-
-void HELPER(gvec_vftci64)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- env->cc_op = vftci64(v1, v2, env, false, simd_data(desc));
-}
-
-void HELPER(gvec_vftci64s)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- env->cc_op = vftci64(v1, v2, env, true, simd_data(desc));
}
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 07/26] s390x/tcg: Simplify vfma64() handling
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (5 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 06/26] s390x/tcg: Simplify vftci64() handling David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-03 17:22 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 08/26] s390x/tcg: Simplify vfll32() handling David Hildenbrand
` (18 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 2 --
target/s390x/translate_vx.c.inc | 8 +++----
target/s390x/vec_fpu_helper.c | 42 +++++++++++++--------------------
3 files changed, 20 insertions(+), 32 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index e832680236..3c87593553 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -267,9 +267,7 @@ DEF_HELPER_FLAGS_4(gvec_vflr64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vflr64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfma64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
-DEF_HELPER_FLAGS_6(gvec_vfma64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfms64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
-DEF_HELPER_FLAGS_6(gvec_vfms64s, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfsq64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfs64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_4(gvec_vftci64, void, ptr, cptr, env, i32)
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 1404471881..4b5bf0a7e3 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2589,7 +2589,6 @@ static DisasJumpType op_vfma(DisasContext *s, DisasOps *o)
{
const uint8_t m5 = get_field(s, m5);
const uint8_t fpf = get_field(s, m6);
- const bool se = extract32(m5, 3, 1);
gen_helper_gvec_4_ptr *fn;
if (fpf != FPF_LONG || extract32(m5, 0, 3)) {
@@ -2598,13 +2597,12 @@ static DisasJumpType op_vfma(DisasContext *s, DisasOps *o)
}
if (s->fields.op2 == 0x8f) {
- fn = se ? gen_helper_gvec_vfma64s : gen_helper_gvec_vfma64;
+ fn = gen_helper_gvec_vfma64;
} else {
- fn = se ? gen_helper_gvec_vfms64s : gen_helper_gvec_vfms64;
+ fn = gen_helper_gvec_vfms64;
}
gen_gvec_4_ptr(get_field(s, v1), get_field(s, v2),
- get_field(s, v3), get_field(s, v4), cpu_env,
- 0, fn);
+ get_field(s, v3), get_field(s, v4), cpu_env, m5, fn);
return DISAS_NEXT;
}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 3267067420..29a6d52827 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -376,12 +376,12 @@ static void vfma64(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
int i;
for (i = 0; i < 2; i++) {
- const uint64_t a = s390_vec_read_element64(v2, i);
- const uint64_t b = s390_vec_read_element64(v3, i);
- const uint64_t c = s390_vec_read_element64(v4, i);
- uint64_t ret = float64_muladd(a, b, c, flags, &env->fpu_status);
+ const float64 a = s390_vec_read_float64(v2, i);
+ const float64 b = s390_vec_read_float64(v3, i);
+ const float64 c = s390_vec_read_float64(v4, i);
+ const float64 ret = float64_muladd(a, b, c, flags, &env->fpu_status);
- s390_vec_write_element64(&tmp, i, ret);
+ s390_vec_write_float64(&tmp, i, ret);
vxc = check_ieee_exc(env, i, false, &vec_exc);
if (s || vxc) {
break;
@@ -391,29 +391,21 @@ static void vfma64(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
*v1 = tmp;
}
-void HELPER(gvec_vfma64)(void *v1, const void *v2, const void *v3,
- const void *v4, CPUS390XState *env, uint32_t desc)
-{
- vfma64(v1, v2, v3, v4, env, false, 0, GETPC());
-}
-
-void HELPER(gvec_vfma64s)(void *v1, const void *v2, const void *v3,
- const void *v4, CPUS390XState *env, uint32_t desc)
-{
- vfma64(v1, v2, v3, v4, env, true, 0, GETPC());
+#define DEF_GVEC_VFMA_B(NAME, FLAGS, BITS) \
+void HELPER(gvec_##NAME##BITS)(void *v1, const void *v2, const void *v3, \
+ const void *v4, CPUS390XState *env, \
+ uint32_t desc) \
+{ \
+ const bool se = extract32(simd_data(desc), 3, 1); \
+ \
+ vfma##BITS(v1, v2, v3, v4, env, se, FLAGS, GETPC()); \
}
-void HELPER(gvec_vfms64)(void *v1, const void *v2, const void *v3,
- const void *v4, CPUS390XState *env, uint32_t desc)
-{
- vfma64(v1, v2, v3, v4, env, false, float_muladd_negate_c, GETPC());
-}
+#define DEF_GVEC_VFMA(NAME, FLAGS) \
+ DEF_GVEC_VFMA_B(NAME, FLAGS, 64)
-void HELPER(gvec_vfms64s)(void *v1, const void *v2, const void *v3,
- const void *v4, CPUS390XState *env, uint32_t desc)
-{
- vfma64(v1, v2, v3, v4, env, true, float_muladd_negate_c, GETPC());
-}
+DEF_GVEC_VFMA(vfma, 0)
+DEF_GVEC_VFMA(vfms, float_muladd_negate_c)
void HELPER(gvec_vftci64)(void *v1, const void *v2, CPUS390XState *env,
uint32_t desc)
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 08/26] s390x/tcg: Simplify vfll32() handling
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (6 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 07/26] s390x/tcg: Simplify vfma64() handling David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-03 17:23 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 09/26] s390x/tcg: Simplify vflr64() handling David Hildenbrand
` (17 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 1 -
target/s390x/translate_vx.c.inc | 6 +-----
target/s390x/vec_fpu_helper.c | 21 +++++----------------
3 files changed, 6 insertions(+), 22 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 3c87593553..63039c8d73 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -262,7 +262,6 @@ DEF_HELPER_FLAGS_4(gvec_vclgd64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfd64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfi64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfll32, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
-DEF_HELPER_FLAGS_4(gvec_vfll32s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vflr64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vflr64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 4b5bf0a7e3..5ff59984b5 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2570,18 +2570,14 @@ static DisasJumpType op_vfll(DisasContext *s, DisasOps *o)
{
const uint8_t fpf = get_field(s, m3);
const uint8_t m4 = get_field(s, m4);
- gen_helper_gvec_2_ptr *fn = gen_helper_gvec_vfll32;
if (fpf != FPF_SHORT || extract32(m4, 0, 3)) {
gen_program_exception(s, PGM_SPECIFICATION);
return DISAS_NORETURN;
}
- if (extract32(m4, 3, 1)) {
- fn = gen_helper_gvec_vfll32s;
- }
gen_gvec_2_ptr(get_field(s, v1), get_field(s, v2), cpu_env,
- 0, fn);
+ m4, gen_helper_gvec_vfll32);
return DISAS_NEXT;
}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 29a6d52827..5c063a681a 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -289,9 +289,10 @@ DEF_GVEC_VFC(vfce, eq)
DEF_GVEC_VFC(vfch, lt)
DEF_GVEC_VFC(vfche, le)
-static void vfll32(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
- bool s, uintptr_t retaddr)
+void HELPER(gvec_vfll32)(void *v1, const void *v2, CPUS390XState *env,
+ uint32_t desc)
{
+ const bool s = extract32(simd_data(desc), 3, 1);
uint8_t vxc, vec_exc = 0;
S390Vector tmp = {};
int i;
@@ -308,20 +309,8 @@ static void vfll32(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
break;
}
}
- handle_ieee_exc(env, vxc, vec_exc, retaddr);
- *v1 = tmp;
-}
-
-void HELPER(gvec_vfll32)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- vfll32(v1, v2, env, false, GETPC());
-}
-
-void HELPER(gvec_vfll32s)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- vfll32(v1, v2, env, true, GETPC());
+ handle_ieee_exc(env, vxc, vec_exc, GETPC());
+ *(S390Vector *)v1 = tmp;
}
static void vflr64(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 09/26] s390x/tcg: Simplify vflr64() handling
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (7 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 08/26] s390x/tcg: Simplify vfll32() handling David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-03 17:25 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 10/26] s390x/tcg: Simplify wfc64() handling David Hildenbrand
` (16 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 1 -
target/s390x/translate_vx.c.inc | 3 +--
target/s390x/vec_fpu_helper.c | 29 +++++++----------------------
3 files changed, 8 insertions(+), 25 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 63039c8d73..0cfb82ee8a 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -263,7 +263,6 @@ DEF_HELPER_FLAGS_5(gvec_vfd64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfi64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfll32, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vflr64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
-DEF_HELPER_FLAGS_4(gvec_vflr64s, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfma64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfms64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 5ff59984b5..91e2967c49 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2531,7 +2531,6 @@ static DisasJumpType op_vcdg(DisasContext *s, DisasOps *o)
const uint8_t fpf = get_field(s, m3);
const uint8_t m4 = get_field(s, m4);
const uint8_t erm = get_field(s, m5);
- const bool se = extract32(m4, 3, 1);
gen_helper_gvec_2_ptr *fn;
if (fpf != FPF_LONG || extract32(m4, 0, 2) || erm > 7 || erm == 2) {
@@ -2556,7 +2555,7 @@ static DisasJumpType op_vcdg(DisasContext *s, DisasOps *o)
fn = gen_helper_gvec_vfi64;
break;
case 0xc5:
- fn = se ? gen_helper_gvec_vflr64s : gen_helper_gvec_vflr64;
+ fn = gen_helper_gvec_vflr64;
break;
default:
g_assert_not_reached();
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 5c063a681a..d07bc7cd64 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -313,9 +313,12 @@ void HELPER(gvec_vfll32)(void *v1, const void *v2, CPUS390XState *env,
*(S390Vector *)v1 = tmp;
}
-static void vflr64(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
- bool s, bool XxC, uint8_t erm, uintptr_t retaddr)
+void HELPER(gvec_vflr64)(void *v1, const void *v2, CPUS390XState *env,
+ uint32_t desc)
{
+ const uint8_t erm = extract32(simd_data(desc), 4, 4);
+ const bool s = extract32(simd_data(desc), 3, 1);
+ const bool XxC = extract32(simd_data(desc), 2, 1);
uint8_t vxc, vec_exc = 0;
S390Vector tmp = {};
int i, old_mode;
@@ -334,26 +337,8 @@ static void vflr64(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
}
}
s390_restore_bfp_rounding_mode(env, old_mode);
- handle_ieee_exc(env, vxc, vec_exc, retaddr);
- *v1 = tmp;
-}
-
-void HELPER(gvec_vflr64)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- const uint8_t erm = extract32(simd_data(desc), 4, 4);
- const bool XxC = extract32(simd_data(desc), 2, 1);
-
- vflr64(v1, v2, env, false, XxC, erm, GETPC());
-}
-
-void HELPER(gvec_vflr64s)(void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- const uint8_t erm = extract32(simd_data(desc), 4, 4);
- const bool XxC = extract32(simd_data(desc), 2, 1);
-
- vflr64(v1, v2, env, true, XxC, erm, GETPC());
+ handle_ieee_exc(env, vxc, vec_exc, GETPC());
+ *(S390Vector *)v1 = tmp;
}
static void vfma64(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 10/26] s390x/tcg: Simplify wfc64() handling
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (8 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 09/26] s390x/tcg: Simplify vflr64() handling David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-03 17:27 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 11/26] s390x/tcg: Implement VECTOR BIT PERMUTE David Hildenbrand
` (15 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
... and prepare for 32/128 bit support.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/vec_fpu_helper.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index d07bc7cd64..219ef19d24 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -203,8 +203,8 @@ static int wfc64(const S390Vector *v1, const S390Vector *v2,
CPUS390XState *env, bool signal, uintptr_t retaddr)
{
/* only the zero-indexed elements are compared */
- const float64 a = s390_vec_read_element64(v1, 0);
- const float64 b = s390_vec_read_element64(v2, 0);
+ const float64 a = s390_vec_read_float64(v1, 0);
+ const float64 b = s390_vec_read_float64(v2, 0);
uint8_t vxc, vec_exc = 0;
int cmp;
@@ -219,17 +219,18 @@ static int wfc64(const S390Vector *v1, const S390Vector *v2,
return float_comp_to_cc(env, cmp);
}
-void HELPER(gvec_wfc64)(const void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- env->cc_op = wfc64(v1, v2, env, false, GETPC());
+#define DEF_GVEC_WFC_B(NAME, SIGNAL, BITS) \
+void HELPER(gvec_##NAME##BITS)(const void *v1, const void *v2, \
+ CPUS390XState *env, uint32_t desc) \
+{ \
+ env->cc_op = wfc##BITS(v1, v2, env, SIGNAL, GETPC()); \
}
-void HELPER(gvec_wfk64)(const void *v1, const void *v2, CPUS390XState *env,
- uint32_t desc)
-{
- env->cc_op = wfc64(v1, v2, env, true, GETPC());
-}
+#define DEF_GVEC_WFC(NAME, SIGNAL) \
+ DEF_GVEC_WFC_B(NAME, SIGNAL, 64)
+
+DEF_GVEC_WFC(wfc, false)
+DEF_GVEC_WFC(wfk, true)
typedef bool (*vfc64_fn)(float64 a, float64 b, float_status *status);
static int vfc64(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 11/26] s390x/tcg: Implement VECTOR BIT PERMUTE
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (9 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 10/26] s390x/tcg: Simplify wfc64() handling David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 12/26] s390x/tcg: Implement VECTOR MULTIPLY SUM LOGICAL David Hildenbrand
` (14 subsequent siblings)
25 siblings, 0 replies; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 1 +
target/s390x/insn-data.def | 2 ++
target/s390x/translate_vx.c.inc | 8 ++++++++
target/s390x/vec_helper.c | 22 ++++++++++++++++++++++
4 files changed, 33 insertions(+)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 0cfb82ee8a..e99c9643eb 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -126,6 +126,7 @@ DEF_HELPER_FLAGS_1(stck, TCG_CALL_NO_RWG_SE, i64, env)
DEF_HELPER_FLAGS_3(probe_write_access, TCG_CALL_NO_WG, void, env, i64, i64)
/* === Vector Support Instructions === */
+DEF_HELPER_FLAGS_4(gvec_vbperm, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
DEF_HELPER_FLAGS_4(vll, TCG_CALL_NO_WG, void, env, ptr, i64, i64)
DEF_HELPER_FLAGS_4(gvec_vpk16, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
DEF_HELPER_FLAGS_4(gvec_vpk32, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, i32)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 35a0086a85..1634a6bc5a 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -989,6 +989,8 @@
/* === Vector Support Instructions === */
+/* VECTOR BIT PERMUTE */
+ E(0xe785, VBPERM, VRR_c, VE, 0, 0, 0, 0, vbperm, 0, 0, IF_VEC)
/* VECTOR GATHER ELEMENT */
E(0xe713, VGEF, VRV, V, la2, 0, 0, 0, vge, 0, ES_32, IF_VEC)
E(0xe712, VGEG, VRV, V, la2, 0, 0, 0, vge, 0, ES_64, IF_VEC)
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 91e2967c49..96283d4ddb 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -327,6 +327,14 @@ static void gen_addi2_i64(TCGv_i64 dl, TCGv_i64 dh, TCGv_i64 al, TCGv_i64 ah,
tcg_temp_free_i64(bh);
}
+static DisasJumpType op_vbperm(DisasContext *s, DisasOps *o)
+{
+ gen_gvec_3_ool(get_field(s, v1), get_field(s, v2), get_field(s, v3), 0,
+ gen_helper_gvec_vbperm);
+
+ return DISAS_NEXT;
+}
+
static DisasJumpType op_vge(DisasContext *s, DisasOps *o)
{
const uint8_t es = s->insn->data;
diff --git a/target/s390x/vec_helper.c b/target/s390x/vec_helper.c
index 986e7cc825..599bab06bd 100644
--- a/target/s390x/vec_helper.c
+++ b/target/s390x/vec_helper.c
@@ -19,6 +19,28 @@
#include "exec/cpu_ldst.h"
#include "exec/exec-all.h"
+void HELPER(gvec_vbperm)(void *v1, const void *v2, const void *v3,
+ uint32_t desc)
+{
+ S390Vector tmp = {};
+ uint16_t result = 0;
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ const uint8_t bit_nr = s390_vec_read_element8(v3, i);
+ uint16_t bit;
+
+ if (bit_nr >= 128) {
+ continue;
+ }
+ bit = (s390_vec_read_element8(v2, bit_nr / 8)
+ >> (7 - (bit_nr % 8))) & 1;
+ result |= (bit << (15 - i));
+ }
+ s390_vec_write_element16(&tmp, 3, result);
+ *(S390Vector *)v1 = tmp;
+}
+
void HELPER(vll)(CPUS390XState *env, void *v1, uint64_t addr, uint64_t bytes)
{
if (likely(bytes >= 16)) {
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 12/26] s390x/tcg: Implement VECTOR MULTIPLY SUM LOGICAL
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (10 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 11/26] s390x/tcg: Implement VECTOR BIT PERMUTE David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 13/26] s390x/tcg: Implement 32/128 bit for VECTOR FP (ADD|DIVIDE|MULTIPLY|SUBTRACT) David Hildenbrand
` (13 subsequent siblings)
25 siblings, 0 replies; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
Fortunately, we only need the Doubleword implementation.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/insn-data.def | 2 ++
target/s390x/translate_vx.c.inc | 50 +++++++++++++++++++++++++++++++++
2 files changed, 52 insertions(+)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 1634a6bc5a..1a3ae7e7e7 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1151,6 +1151,8 @@
F(0xe7a7, VMO, VRR_c, V, 0, 0, 0, 0, vm, 0, IF_VEC)
/* VECTOR MULTIPLY LOGICAL ODD */
F(0xe7a5, VMLO, VRR_c, V, 0, 0, 0, 0, vm, 0, IF_VEC)
+/* VECTOR MULTIPLY SUM LOGICAL */
+ F(0xe7b8, VMSL, VRR_d, VE, 0, 0, 0, 0, vmsl, 0, IF_VEC)
/* VECTOR NAND */
F(0xe76e, VNN, VRR_c, VE, 0, 0, 0, 0, vnn, 0, IF_VEC)
/* VECTOR NOR */
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 96283d4ddb..6e75b40eb8 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -1779,6 +1779,56 @@ static DisasJumpType op_vm(DisasContext *s, DisasOps *o)
return DISAS_NEXT;
}
+static DisasJumpType op_vmsl(DisasContext *s, DisasOps *o)
+{
+ TCGv_i64 l1, h1, l2, h2;
+
+ if (get_field(s, m4) != ES_64) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ l1 = tcg_temp_new_i64();
+ h1 = tcg_temp_new_i64();
+ l2 = tcg_temp_new_i64();
+ h2 = tcg_temp_new_i64();
+
+ /* Multipy both even elements from v2 and v3 */
+ read_vec_element_i64(l1, get_field(s, v2), 0, ES_64);
+ read_vec_element_i64(h1, get_field(s, v3), 0, ES_64);
+ tcg_gen_mulu2_i64(l1, h1, l1, h1);
+ /* Shift result left by one (x2) if requested */
+ if (extract32(get_field(s, m6), 3, 1)) {
+ tcg_gen_add2_i64(l1, h1, l1, h1, l1, h1);
+ }
+
+ /* Multipy both odd elements from v2 and v3 */
+ read_vec_element_i64(l2, get_field(s, v2), 1, ES_64);
+ read_vec_element_i64(h2, get_field(s, v3), 1, ES_64);
+ tcg_gen_mulu2_i64(l2, h2, l2, h2);
+ /* Shift result left by one (x2) if requested */
+ if (extract32(get_field(s, m6), 2, 1)) {
+ tcg_gen_add2_i64(l2, h2, l2, h2, l2, h2);
+ }
+
+ /* Add both intermediate results */
+ tcg_gen_add2_i64(l1, h1, l1, h1, l2, h2);
+ /* Add whole v4 */
+ read_vec_element_i64(h2, get_field(s, v4), 0, ES_64);
+ read_vec_element_i64(l2, get_field(s, v4), 1, ES_64);
+ tcg_gen_add2_i64(l1, h1, l1, h1, l2, h2);
+
+ /* Store final result into v1. */
+ write_vec_element_i64(h1, get_field(s, v1), 0, ES_64);
+ write_vec_element_i64(l1, get_field(s, v1), 1, ES_64);
+
+ tcg_temp_free_i64(l1);
+ tcg_temp_free_i64(h1);
+ tcg_temp_free_i64(l2);
+ tcg_temp_free_i64(h2);
+ return DISAS_NEXT;
+}
+
static DisasJumpType op_vnn(DisasContext *s, DisasOps *o)
{
gen_gvec_fn_3(nand, ES_8, get_field(s, v1),
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 13/26] s390x/tcg: Implement 32/128 bit for VECTOR FP (ADD|DIVIDE|MULTIPLY|SUBTRACT)
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (11 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 12/26] s390x/tcg: Implement VECTOR MULTIPLY SUM LOGICAL David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-03 17:32 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 14/26] s390x/tcg: Implement 32/128 bit for VECTOR (LOAD FP INTEGER|FP SQUARE ROOT) David Hildenbrand
` (12 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
In case of 128bit, we always have a single element. Add new helpers for
reading/writing 32/128 bit floats.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 8 ++++
target/s390x/translate_vx.c.inc | 85 +++++++++++++++++++++++++++++----
target/s390x/vec_fpu_helper.c | 74 ++++++++++++++++++++++++++--
3 files changed, 153 insertions(+), 14 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index e99c9643eb..2d5e382e61 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -247,7 +247,9 @@ DEF_HELPER_6(gvec_vstrc_cc_rt16, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_6(gvec_vstrc_cc_rt32, void, ptr, cptr, cptr, cptr, env, i32)
/* === Vector Floating-Point Instructions */
+DEF_HELPER_FLAGS_5(gvec_vfa32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfa64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfa128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_4(gvec_wfc64, void, cptr, cptr, env, i32)
DEF_HELPER_4(gvec_wfk64, void, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfce64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
@@ -260,15 +262,21 @@ DEF_HELPER_FLAGS_4(gvec_vcdg64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vcdlg64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vcgd64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vclgd64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfd32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfd64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfd128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfi64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfll32, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vflr64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfm32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfm128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfma64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfms64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfsq64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfs32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfs64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfs128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_4(gvec_vftci64, void, ptr, cptr, env, i32)
#ifndef CONFIG_USER_ONLY
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 6e75b40eb8..0fbd914b40 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2501,29 +2501,94 @@ static DisasJumpType op_vfa(DisasContext *s, DisasOps *o)
{
const uint8_t fpf = get_field(s, m4);
const uint8_t m5 = get_field(s, m5);
- gen_helper_gvec_3_ptr *fn;
-
- if (fpf != FPF_LONG || extract32(m5, 0, 3)) {
- gen_program_exception(s, PGM_SPECIFICATION);
- return DISAS_NORETURN;
- }
+ gen_helper_gvec_3_ptr *fn = NULL;
switch (s->fields.op2) {
case 0xe3:
- fn = gen_helper_gvec_vfa64;
+ switch (fpf) {
+ case FPF_SHORT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vfa32;
+ }
+ break;
+ case FPF_LONG:
+ fn = gen_helper_gvec_vfa64;
+ break;
+ case FPF_EXT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vfa128;
+ }
+ break;
+ default:
+ break;
+ }
break;
case 0xe5:
- fn = gen_helper_gvec_vfd64;
+ switch (fpf) {
+ case FPF_SHORT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vfd32;
+ }
+ break;
+ case FPF_LONG:
+ fn = gen_helper_gvec_vfd64;
+ break;
+ case FPF_EXT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vfd128;
+ }
+ break;
+ default:
+ break;
+ }
break;
case 0xe7:
- fn = gen_helper_gvec_vfm64;
+ switch (fpf) {
+ case FPF_SHORT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vfm32;
+ }
+ break;
+ case FPF_LONG:
+ fn = gen_helper_gvec_vfm64;
+ break;
+ case FPF_EXT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vfm128;
+ }
+ break;
+ default:
+ break;
+ }
break;
case 0xe2:
- fn = gen_helper_gvec_vfs64;
+ switch (fpf) {
+ case FPF_SHORT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vfs32;
+ }
+ break;
+ case FPF_LONG:
+ fn = gen_helper_gvec_vfs64;
+ break;
+ case FPF_EXT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vfs128;
+ }
+ break;
+ default:
+ break;
+ }
break;
default:
g_assert_not_reached();
}
+
+ if (!fn || extract32(m5, 0, 3)) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
gen_gvec_3_ptr(get_field(s, v1), get_field(s, v2),
get_field(s, v3), cpu_env, m5, fn);
return DISAS_NEXT;
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 219ef19d24..1e90df90ec 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -78,16 +78,38 @@ static void handle_ieee_exc(CPUS390XState *env, uint8_t vxc, uint8_t vec_exc,
}
}
+static float32 s390_vec_read_float32(const S390Vector *v, uint8_t enr)
+{
+ return make_float32(s390_vec_read_element32(v, enr));
+}
+
static float64 s390_vec_read_float64(const S390Vector *v, uint8_t enr)
{
return make_float64(s390_vec_read_element64(v, enr));
}
+static float128 s390_vec_read_float128(const S390Vector *v)
+{
+ return make_float128(s390_vec_read_element64(v, 0),
+ s390_vec_read_element64(v, 1));
+}
+
+static void s390_vec_write_float32(S390Vector *v, uint8_t enr, float32 data)
+{
+ return s390_vec_write_element32(v, enr, data);
+}
+
static void s390_vec_write_float64(S390Vector *v, uint8_t enr, float64 data)
{
return s390_vec_write_element64(v, enr, data);
}
+static void s390_vec_write_float128(S390Vector *v, float128 data)
+{
+ s390_vec_write_element64(v, 0, data.high);
+ s390_vec_write_element64(v, 1, data.low);
+}
+
typedef float64 (*vop64_2_fn)(float64 a, float_status *s);
static void vop64_2(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
bool s, bool XxC, uint8_t erm, vop64_2_fn fn,
@@ -162,6 +184,29 @@ DEF_GVEC_VOP2_64(vclgd)
DEF_GVEC_VOP2(vfi, round_to_int)
DEF_GVEC_VOP2(vfsq, sqrt)
+typedef float32 (*vop32_3_fn)(float32 a, float32 b, float_status *s);
+static void vop32_3(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
+ CPUS390XState *env, bool s, vop32_3_fn fn,
+ uintptr_t retaddr)
+{
+ uint8_t vxc, vec_exc = 0;
+ S390Vector tmp = {};
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ const float32 a = s390_vec_read_float32(v2, i);
+ const float32 b = s390_vec_read_float32(v3, i);
+
+ s390_vec_write_float32(&tmp, i, fn(a, b, &env->fpu_status));
+ vxc = check_ieee_exc(env, i, false, &vec_exc);
+ if (s || vxc) {
+ break;
+ }
+ }
+ handle_ieee_exc(env, vxc, vec_exc, retaddr);
+ *v1 = tmp;
+}
+
typedef float64 (*vop64_3_fn)(float64 a, float64 b, float_status *s);
static void vop64_3(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
CPUS390XState *env, bool s, vop64_3_fn fn,
@@ -185,15 +230,36 @@ static void vop64_3(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
*v1 = tmp;
}
-#define DEF_GVEC_VOP3(NAME, OP) \
-void HELPER(gvec_##NAME##64)(void *v1, const void *v2, const void *v3, \
- CPUS390XState *env, uint32_t desc) \
+typedef float128 (*vop128_3_fn)(float128 a, float128 b, float_status *s);
+static void vop128_3(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
+ CPUS390XState *env, bool s, vop128_3_fn fn,
+ uintptr_t retaddr)
+{
+ const float128 a = s390_vec_read_float128(v2);
+ const float128 b = s390_vec_read_float128(v3);
+ uint8_t vxc, vec_exc = 0;
+ S390Vector tmp = {};
+
+ s390_vec_write_float128(&tmp, fn(a, b, &env->fpu_status));
+ vxc = check_ieee_exc(env, 0, false, &vec_exc);
+ handle_ieee_exc(env, vxc, vec_exc, retaddr);
+ *v1 = tmp;
+}
+
+#define DEF_GVEC_VOP3_B(NAME, OP, BITS) \
+void HELPER(gvec_##NAME##BITS)(void *v1, const void *v2, const void *v3, \
+ CPUS390XState *env, uint32_t desc) \
{ \
const bool se = extract32(simd_data(desc), 3, 1); \
\
- vop64_3(v1, v2, v3, env, se, float64_##OP, GETPC()); \
+ vop##BITS##_3(v1, v2, v3, env, se, float##BITS##_##OP, GETPC()); \
}
+#define DEF_GVEC_VOP3(NAME, OP) \
+DEF_GVEC_VOP3_B(NAME, OP, 32) \
+DEF_GVEC_VOP3_B(NAME, OP, 64) \
+DEF_GVEC_VOP3_B(NAME, OP, 128)
+
DEF_GVEC_VOP3(vfa, add)
DEF_GVEC_VOP3(vfs, sub)
DEF_GVEC_VOP3(vfd, div)
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 14/26] s390x/tcg: Implement 32/128 bit for VECTOR (LOAD FP INTEGER|FP SQUARE ROOT)
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (12 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 13/26] s390x/tcg: Implement 32/128 bit for VECTOR FP (ADD|DIVIDE|MULTIPLY|SUBTRACT) David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-03 17:33 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 15/26] s390x/tcg: Implement 32/128 bit for VECTOR FP COMPARE * David Hildenbrand
` (11 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 4 ++
target/s390x/translate_vx.c.inc | 74 ++++++++++++++++++++++++++-------
target/s390x/vec_fpu_helper.c | 46 +++++++++++++++++++-
3 files changed, 109 insertions(+), 15 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 2d5e382e61..28797a6ccc 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -265,7 +265,9 @@ DEF_HELPER_FLAGS_4(gvec_vclgd64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfd32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfd64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfd128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vfi32, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfi64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vfi128, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfll32, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vflr64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
@@ -273,7 +275,9 @@ DEF_HELPER_FLAGS_5(gvec_vfm64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfma64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfms64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vfsq32, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfsq64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vfsq128, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfs32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfs64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfs128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 0fbd914b40..6241279e68 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2654,35 +2654,63 @@ static DisasJumpType op_vcdg(DisasContext *s, DisasOps *o)
const uint8_t fpf = get_field(s, m3);
const uint8_t m4 = get_field(s, m4);
const uint8_t erm = get_field(s, m5);
- gen_helper_gvec_2_ptr *fn;
+ gen_helper_gvec_2_ptr *fn = NULL;
- if (fpf != FPF_LONG || extract32(m4, 0, 2) || erm > 7 || erm == 2) {
- gen_program_exception(s, PGM_SPECIFICATION);
- return DISAS_NORETURN;
- }
switch (s->fields.op2) {
case 0xc3:
- fn = gen_helper_gvec_vcdg64;
+ if (fpf == FPF_LONG) {
+ fn = gen_helper_gvec_vcdg64;
+ }
break;
case 0xc1:
- fn = gen_helper_gvec_vcdlg64;
+ if (fpf == FPF_LONG) {
+ fn = gen_helper_gvec_vcdlg64;
+ }
break;
case 0xc2:
- fn = gen_helper_gvec_vcgd64;
+ if (fpf == FPF_LONG) {
+ fn = gen_helper_gvec_vcgd64;
+ }
break;
case 0xc0:
- fn = gen_helper_gvec_vclgd64;
+ if (fpf == FPF_LONG) {
+ fn = gen_helper_gvec_vclgd64;
+ }
break;
case 0xc7:
- fn = gen_helper_gvec_vfi64;
+ switch (fpf) {
+ case FPF_SHORT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vfi32;
+ }
+ break;
+ case FPF_LONG:
+ fn = gen_helper_gvec_vfi64;
+ break;
+ case FPF_EXT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vfi128;
+ }
+ break;
+ default:
+ break;
+ }
break;
case 0xc5:
- fn = gen_helper_gvec_vflr64;
+ if (fpf == FPF_LONG) {
+ fn = gen_helper_gvec_vflr64;
+ }
break;
default:
g_assert_not_reached();
}
+
+ if (!fn || extract32(m4, 0, 2) || erm > 7 || erm == 2) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
gen_gvec_2_ptr(get_field(s, v1), get_field(s, v2), cpu_env,
deposit32(m4, 4, 4, erm), fn);
return DISAS_NEXT;
@@ -2780,14 +2808,32 @@ static DisasJumpType op_vfsq(DisasContext *s, DisasOps *o)
{
const uint8_t fpf = get_field(s, m3);
const uint8_t m4 = get_field(s, m4);
+ gen_helper_gvec_2_ptr *fn = NULL;
+
+ switch (fpf) {
+ case FPF_SHORT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vfsq32;
+ }
+ break;
+ case FPF_LONG:
+ fn = gen_helper_gvec_vfsq64;
+ break;
+ case FPF_EXT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vfsq128;
+ }
+ break;
+ default:
+ break;
+ }
- if (fpf != FPF_LONG || extract32(m4, 0, 3)) {
+ if (!fn || extract32(m4, 0, 3)) {
gen_program_exception(s, PGM_SPECIFICATION);
return DISAS_NORETURN;
}
- gen_gvec_2_ptr(get_field(s, v1), get_field(s, v2), cpu_env, m4,
- gen_helper_gvec_vfsq64);
+ gen_gvec_2_ptr(get_field(s, v1), get_field(s, v2), cpu_env, m4, fn);
return DISAS_NEXT;
}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 1e90df90ec..042e062a31 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -110,6 +110,30 @@ static void s390_vec_write_float128(S390Vector *v, float128 data)
s390_vec_write_element64(v, 1, data.low);
}
+typedef float32 (*vop32_2_fn)(float32 a, float_status *s);
+static void vop32_2(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
+ bool s, bool XxC, uint8_t erm, vop32_2_fn fn,
+ uintptr_t retaddr)
+{
+ uint8_t vxc, vec_exc = 0;
+ S390Vector tmp = {};
+ int i, old_mode;
+
+ old_mode = s390_swap_bfp_rounding_mode(env, erm);
+ for (i = 0; i < 4; i++) {
+ const float32 a = s390_vec_read_float32(v2, i);
+
+ s390_vec_write_float32(&tmp, i, fn(a, &env->fpu_status));
+ vxc = check_ieee_exc(env, i, XxC, &vec_exc);
+ if (s || vxc) {
+ break;
+ }
+ }
+ s390_restore_bfp_rounding_mode(env, old_mode);
+ handle_ieee_exc(env, vxc, vec_exc, retaddr);
+ *v1 = tmp;
+}
+
typedef float64 (*vop64_2_fn)(float64 a, float_status *s);
static void vop64_2(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
bool s, bool XxC, uint8_t erm, vop64_2_fn fn,
@@ -134,6 +158,24 @@ static void vop64_2(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
*v1 = tmp;
}
+typedef float128 (*vop128_2_fn)(float128 a, float_status *s);
+static void vop128_2(S390Vector *v1, const S390Vector *v2, CPUS390XState *env,
+ bool s, bool XxC, uint8_t erm, vop128_2_fn fn,
+ uintptr_t retaddr)
+{
+ const float128 a = s390_vec_read_float128(v2);
+ uint8_t vxc, vec_exc = 0;
+ S390Vector tmp = {};
+ int old_mode;
+
+ old_mode = s390_swap_bfp_rounding_mode(env, erm);
+ s390_vec_write_float128(&tmp, fn(a, &env->fpu_status));
+ vxc = check_ieee_exc(env, 0, XxC, &vec_exc);
+ s390_restore_bfp_rounding_mode(env, old_mode);
+ handle_ieee_exc(env, vxc, vec_exc, retaddr);
+ *v1 = tmp;
+}
+
static float64 vcdg64(float64 a, float_status *s)
{
return int64_to_float64(a, s);
@@ -175,7 +217,9 @@ void HELPER(gvec_##NAME##BITS)(void *v1, const void *v2, CPUS390XState *env, \
DEF_GVEC_VOP2_FN(NAME, NAME##64, 64)
#define DEF_GVEC_VOP2(NAME, OP) \
-DEF_GVEC_VOP2_FN(NAME, float64_##OP, 64)
+DEF_GVEC_VOP2_FN(NAME, float32_##OP, 32) \
+DEF_GVEC_VOP2_FN(NAME, float64_##OP, 64) \
+DEF_GVEC_VOP2_FN(NAME, float128_##OP, 128)
DEF_GVEC_VOP2_64(vcdg)
DEF_GVEC_VOP2_64(vcdlg)
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 15/26] s390x/tcg: Implement 32/128 bit for VECTOR FP COMPARE *
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (13 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 14/26] s390x/tcg: Implement 32/128 bit for VECTOR (LOAD FP INTEGER|FP SQUARE ROOT) David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-03 17:37 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 16/26] s390x/tcg: Implement 32/128 bit for VECTOR FP COMPARE (AND SIGNAL) SCALAR David Hildenbrand
` (10 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
In addition to 32/128bit variants, we also have to support the
"Signal-on-QNaN (SQ)" bit.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 12 +++++++
target/s390x/translate_vx.c.inc | 57 ++++++++++++++++++++++++-----
target/s390x/vec_fpu_helper.c | 64 +++++++++++++++++++++++++++++++--
3 files changed, 121 insertions(+), 12 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 28797a6ccc..146836126c 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -252,12 +252,24 @@ DEF_HELPER_FLAGS_5(gvec_vfa64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfa128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_4(gvec_wfc64, void, cptr, cptr, env, i32)
DEF_HELPER_4(gvec_wfk64, void, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfce32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vfce32_cc, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfce64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_5(gvec_vfce64_cc, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfce128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vfce128_cc, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfch32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vfch32_cc, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfch64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_5(gvec_vfch64_cc, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfch128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vfch128_cc, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfche32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vfche32_cc, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfche64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_5(gvec_vfche64_cc, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfche128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_5(gvec_vfche128_cc, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vcdg64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vcdlg64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vcgd64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 6241279e68..6f6ef6b6b8 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2621,26 +2621,65 @@ static DisasJumpType op_vfc(DisasContext *s, DisasOps *o)
const uint8_t m5 = get_field(s, m5);
const uint8_t m6 = get_field(s, m6);
const bool cs = extract32(m6, 0, 1);
- gen_helper_gvec_3_ptr *fn;
-
- if (fpf != FPF_LONG || extract32(m5, 0, 3) || extract32(m6, 1, 3)) {
- gen_program_exception(s, PGM_SPECIFICATION);
- return DISAS_NORETURN;
- }
+ const bool sq = extract32(m5, 2, 1);
+ gen_helper_gvec_3_ptr *fn = NULL;
switch (s->fields.op2) {
case 0xe8:
- fn = cs ? gen_helper_gvec_vfce64_cc : gen_helper_gvec_vfce64;
+ switch (fpf) {
+ case FPF_SHORT:
+ fn = cs ? gen_helper_gvec_vfce32_cc : gen_helper_gvec_vfce32;
+ break;
+ case FPF_LONG:
+ fn = cs ? gen_helper_gvec_vfce64_cc : gen_helper_gvec_vfce64;
+ break;
+ case FPF_EXT:
+ fn = cs ? gen_helper_gvec_vfce128_cc : gen_helper_gvec_vfce128;
+ break;
+ default:
+ break;
+ }
break;
case 0xeb:
- fn = cs ? gen_helper_gvec_vfch64_cc : gen_helper_gvec_vfch64;
+ switch (fpf) {
+ case FPF_SHORT:
+ fn = cs ? gen_helper_gvec_vfch32_cc : gen_helper_gvec_vfch32;
+ break;
+ case FPF_LONG:
+ fn = cs ? gen_helper_gvec_vfch64_cc : gen_helper_gvec_vfch64;
+ break;
+ case FPF_EXT:
+ fn = cs ? gen_helper_gvec_vfch128_cc : gen_helper_gvec_vfch128;
+ break;
+ default:
+ break;
+ }
break;
case 0xea:
- fn = cs ? gen_helper_gvec_vfche64_cc : gen_helper_gvec_vfche64;
+ switch (fpf) {
+ case FPF_SHORT:
+ fn = cs ? gen_helper_gvec_vfche32_cc : gen_helper_gvec_vfche32;
+ break;
+ case FPF_LONG:
+ fn = cs ? gen_helper_gvec_vfche64_cc : gen_helper_gvec_vfche64;
+ break;
+ case FPF_EXT:
+ fn = cs ? gen_helper_gvec_vfche128_cc : gen_helper_gvec_vfche128;
+ break;
+ default:
+ break;
+ }
break;
default:
g_assert_not_reached();
}
+
+ if (!fn || extract32(m5, 0, 2) || extract32(m6, 1, 3) ||
+ (!s390_has_feat(S390_FEAT_VECTOR_ENH) && (fpf != FPF_LONG || sq))) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
gen_gvec_3_ptr(get_field(s, v1), get_field(s, v2), get_field(s, v3),
cpu_env, m5, fn);
if (cs) {
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 042e062a31..6fff3e9f01 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -342,6 +342,38 @@ void HELPER(gvec_##NAME##BITS)(const void *v1, const void *v2, \
DEF_GVEC_WFC(wfc, false)
DEF_GVEC_WFC(wfk, true)
+typedef bool (*vfc32_fn)(float32 a, float32 b, float_status *status);
+static int vfc32(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
+ CPUS390XState *env, bool s, vfc32_fn fn, uintptr_t retaddr)
+{
+ uint8_t vxc, vec_exc = 0;
+ S390Vector tmp = {};
+ int match = 0;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ const float32 a = s390_vec_read_float32(v2, i);
+ const float32 b = s390_vec_read_float32(v3, i);
+
+ /* swap the order of the parameters, so we can use existing functions */
+ if (fn(b, a, &env->fpu_status)) {
+ match++;
+ s390_vec_write_element32(&tmp, i, -1u);
+ }
+ vxc = check_ieee_exc(env, i, false, &vec_exc);
+ if (s || vxc) {
+ break;
+ }
+ }
+
+ handle_ieee_exc(env, vxc, vec_exc, retaddr);
+ *v1 = tmp;
+ if (match) {
+ return s || match == 4 ? 0 : 1;
+ }
+ return 3;
+}
+
typedef bool (*vfc64_fn)(float64 a, float64 b, float_status *status);
static int vfc64(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
CPUS390XState *env, bool s, vfc64_fn fn, uintptr_t retaddr)
@@ -374,12 +406,35 @@ static int vfc64(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
return 3;
}
+typedef bool (*vfc128_fn)(float128 a, float128 b, float_status *status);
+static int vfc128(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
+ CPUS390XState *env, bool s, vfc128_fn fn, uintptr_t retaddr)
+{
+ const float128 a = s390_vec_read_float128(v2);
+ const float128 b = s390_vec_read_float128(v3);
+ uint8_t vxc, vec_exc = 0;
+ S390Vector tmp = {};
+ bool match = false;
+
+ /* swap the order of the parameters, so we can use existing functions */
+ if (fn(b, a, &env->fpu_status)) {
+ match = true;
+ s390_vec_write_element64(&tmp, 0, -1ull);
+ s390_vec_write_element64(&tmp, 1, -1ull);
+ }
+ vxc = check_ieee_exc(env, 0, false, &vec_exc);
+ handle_ieee_exc(env, vxc, vec_exc, retaddr);
+ *v1 = tmp;
+ return match ? 0 : 3;
+}
+
#define DEF_GVEC_VFC_B(NAME, OP, BITS) \
void HELPER(gvec_##NAME##BITS)(void *v1, const void *v2, const void *v3, \
CPUS390XState *env, uint32_t desc) \
{ \
const bool se = extract32(simd_data(desc), 3, 1); \
- vfc##BITS##_fn fn = float##BITS##_##OP##_quiet; \
+ const bool sq = extract32(simd_data(desc), 2, 1); \
+ vfc##BITS##_fn fn = sq ? float##BITS##_##OP : float##BITS##_##OP##_quiet; \
\
vfc##BITS(v1, v2, v3, env, se, fn, GETPC()); \
} \
@@ -388,13 +443,16 @@ void HELPER(gvec_##NAME##BITS##_cc)(void *v1, const void *v2, const void *v3, \
CPUS390XState *env, uint32_t desc) \
{ \
const bool se = extract32(simd_data(desc), 3, 1); \
- vfc##BITS##_fn fn = float##BITS##_##OP##_quiet; \
+ const bool sq = extract32(simd_data(desc), 2, 1); \
+ vfc##BITS##_fn fn = sq ? float##BITS##_##OP : float##BITS##_##OP##_quiet; \
\
env->cc_op = vfc##BITS(v1, v2, v3, env, se, fn, GETPC()); \
}
#define DEF_GVEC_VFC(NAME, OP) \
-DEF_GVEC_VFC_B(NAME, OP, 64)
+DEF_GVEC_VFC_B(NAME, OP, 32) \
+DEF_GVEC_VFC_B(NAME, OP, 64) \
+DEF_GVEC_VFC_B(NAME, OP, 128) \
DEF_GVEC_VFC(vfce, eq)
DEF_GVEC_VFC(vfch, lt)
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 16/26] s390x/tcg: Implement 32/128 bit for VECTOR FP COMPARE (AND SIGNAL) SCALAR
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (14 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 15/26] s390x/tcg: Implement 32/128 bit for VECTOR FP COMPARE * David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-03 17:40 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 17/26] s390x/tcg: Implement 64 bit for VECTOR FP LOAD LENGTHENED David Hildenbrand
` (9 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 4 +++
target/s390x/translate_vx.c.inc | 38 ++++++++++++++++++++++------
target/s390x/vec_fpu_helper.c | 44 ++++++++++++++++++++++++++++++++-
3 files changed, 77 insertions(+), 9 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 146836126c..dca436f710 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -250,8 +250,12 @@ DEF_HELPER_6(gvec_vstrc_cc_rt32, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfa32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfa64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfa128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_4(gvec_wfc32, void, cptr, cptr, env, i32)
+DEF_HELPER_4(gvec_wfk32, void, cptr, cptr, env, i32)
DEF_HELPER_4(gvec_wfc64, void, cptr, cptr, env, i32)
DEF_HELPER_4(gvec_wfk64, void, cptr, cptr, env, i32)
+DEF_HELPER_4(gvec_wfc128, void, cptr, cptr, env, i32)
+DEF_HELPER_4(gvec_wfk128, void, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfce32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_5(gvec_vfce32_cc, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfce64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 6f6ef6b6b8..822a9d0513 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2598,19 +2598,41 @@ static DisasJumpType op_wfc(DisasContext *s, DisasOps *o)
{
const uint8_t fpf = get_field(s, m3);
const uint8_t m4 = get_field(s, m4);
+ gen_helper_gvec_2_ptr *fn = NULL;
- if (fpf != FPF_LONG || m4) {
+ switch (fpf) {
+ case FPF_SHORT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_wfk32;
+ if (s->fields.op2 == 0xcb) {
+ fn = gen_helper_gvec_wfc32;
+ }
+ }
+ break;
+ case FPF_LONG:
+ fn = gen_helper_gvec_wfk64;
+ if (s->fields.op2 == 0xcb) {
+ fn = gen_helper_gvec_wfc64;
+ }
+ break;
+ case FPF_EXT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_wfk128;
+ if (s->fields.op2 == 0xcb) {
+ fn = gen_helper_gvec_wfc128;
+ }
+ }
+ break;
+ default:
+ break;
+ };
+
+ if (!fn || m4) {
gen_program_exception(s, PGM_SPECIFICATION);
return DISAS_NORETURN;
}
- if (s->fields.op2 == 0xcb) {
- gen_gvec_2_ptr(get_field(s, v1), get_field(s, v2),
- cpu_env, 0, gen_helper_gvec_wfc64);
- } else {
- gen_gvec_2_ptr(get_field(s, v1), get_field(s, v2),
- cpu_env, 0, gen_helper_gvec_wfk64);
- }
+ gen_gvec_2_ptr(get_field(s, v1), get_field(s, v2), cpu_env, 0, fn);
set_cc_static(s);
return DISAS_NEXT;
}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 6fff3e9f01..ab16ed4e24 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -309,6 +309,26 @@ DEF_GVEC_VOP3(vfs, sub)
DEF_GVEC_VOP3(vfd, div)
DEF_GVEC_VOP3(vfm, mul)
+static int wfc32(const S390Vector *v1, const S390Vector *v2,
+ CPUS390XState *env, bool signal, uintptr_t retaddr)
+{
+ /* only the zero-indexed elements are compared */
+ const float32 a = s390_vec_read_float32(v1, 0);
+ const float32 b = s390_vec_read_float32(v2, 0);
+ uint8_t vxc, vec_exc = 0;
+ int cmp;
+
+ if (signal) {
+ cmp = float32_compare(a, b, &env->fpu_status);
+ } else {
+ cmp = float32_compare_quiet(a, b, &env->fpu_status);
+ }
+ vxc = check_ieee_exc(env, 0, false, &vec_exc);
+ handle_ieee_exc(env, vxc, vec_exc, retaddr);
+
+ return float_comp_to_cc(env, cmp);
+}
+
static int wfc64(const S390Vector *v1, const S390Vector *v2,
CPUS390XState *env, bool signal, uintptr_t retaddr)
{
@@ -329,6 +349,26 @@ static int wfc64(const S390Vector *v1, const S390Vector *v2,
return float_comp_to_cc(env, cmp);
}
+static int wfc128(const S390Vector *v1, const S390Vector *v2,
+ CPUS390XState *env, bool signal, uintptr_t retaddr)
+{
+ /* only the zero-indexed elements are compared */
+ const float128 a = s390_vec_read_float128(v1);
+ const float128 b = s390_vec_read_float128(v2);
+ uint8_t vxc, vec_exc = 0;
+ int cmp;
+
+ if (signal) {
+ cmp = float128_compare(a, b, &env->fpu_status);
+ } else {
+ cmp = float128_compare_quiet(a, b, &env->fpu_status);
+ }
+ vxc = check_ieee_exc(env, 0, false, &vec_exc);
+ handle_ieee_exc(env, vxc, vec_exc, retaddr);
+
+ return float_comp_to_cc(env, cmp);
+}
+
#define DEF_GVEC_WFC_B(NAME, SIGNAL, BITS) \
void HELPER(gvec_##NAME##BITS)(const void *v1, const void *v2, \
CPUS390XState *env, uint32_t desc) \
@@ -337,7 +377,9 @@ void HELPER(gvec_##NAME##BITS)(const void *v1, const void *v2, \
}
#define DEF_GVEC_WFC(NAME, SIGNAL) \
- DEF_GVEC_WFC_B(NAME, SIGNAL, 64)
+ DEF_GVEC_WFC_B(NAME, SIGNAL, 32) \
+ DEF_GVEC_WFC_B(NAME, SIGNAL, 64) \
+ DEF_GVEC_WFC_B(NAME, SIGNAL, 128)
DEF_GVEC_WFC(wfc, false)
DEF_GVEC_WFC(wfk, true)
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 17/26] s390x/tcg: Implement 64 bit for VECTOR FP LOAD LENGTHENED
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (15 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 16/26] s390x/tcg: Implement 32/128 bit for VECTOR FP COMPARE (AND SIGNAL) SCALAR David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 18/26] s390x/tcg: Implement 128 bit for VECTOR FP LOAD ROUNDED David Hildenbrand
` (8 subsequent siblings)
25 siblings, 0 replies; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
64 bit -> 128 bit, there is only a single final element.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 1 +
target/s390x/translate_vx.c.inc | 19 ++++++++++++++++---
target/s390x/vec_fpu_helper.c | 13 +++++++++++++
3 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index dca436f710..b5ba159402 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -285,6 +285,7 @@ DEF_HELPER_FLAGS_4(gvec_vfi32, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfi64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfi128, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfll32, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vfll64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vflr64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 822a9d0513..472afca45e 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2781,14 +2781,27 @@ static DisasJumpType op_vfll(DisasContext *s, DisasOps *o)
{
const uint8_t fpf = get_field(s, m3);
const uint8_t m4 = get_field(s, m4);
+ gen_helper_gvec_2_ptr *fn = NULL;
- if (fpf != FPF_SHORT || extract32(m4, 0, 3)) {
+ switch (fpf) {
+ case FPF_SHORT:
+ fn = gen_helper_gvec_vfll32;
+ break;
+ case FPF_LONG:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vfll64;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!fn || extract32(m4, 0, 3)) {
gen_program_exception(s, PGM_SPECIFICATION);
return DISAS_NORETURN;
}
- gen_gvec_2_ptr(get_field(s, v1), get_field(s, v2), cpu_env,
- m4, gen_helper_gvec_vfll32);
+ gen_gvec_2_ptr(get_field(s, v1), get_field(s, v2), cpu_env, m4, fn);
return DISAS_NEXT;
}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index ab16ed4e24..8b9f64e03f 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -524,6 +524,19 @@ void HELPER(gvec_vfll32)(void *v1, const void *v2, CPUS390XState *env,
*(S390Vector *)v1 = tmp;
}
+void HELPER(gvec_vfll64)(void *v1, const void *v2, CPUS390XState *env,
+ uint32_t desc)
+{
+ /* load from even element */
+ const float128 ret = float64_to_float128(s390_vec_read_float64(v2, 0),
+ &env->fpu_status);
+ uint8_t vxc, vec_exc = 0;
+
+ vxc = check_ieee_exc(env, 0, false, &vec_exc);
+ handle_ieee_exc(env, vxc, vec_exc, GETPC());
+ s390_vec_write_float128(v1, ret);
+}
+
void HELPER(gvec_vflr64)(void *v1, const void *v2, CPUS390XState *env,
uint32_t desc)
{
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 18/26] s390x/tcg: Implement 128 bit for VECTOR FP LOAD ROUNDED
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (16 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 17/26] s390x/tcg: Implement 64 bit for VECTOR FP LOAD LENGTHENED David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 19/26] s390x/tcg: Implement 32/128 bit for VECTOR FP PERFORM SIGN OPERATION David Hildenbrand
` (7 subsequent siblings)
25 siblings, 0 replies; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
128 bit -> 64 bit, there is only a single element to process.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 1 +
target/s390x/translate_vx.c.inc | 11 ++++++++++-
target/s390x/vec_fpu_helper.c | 19 +++++++++++++++++++
3 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index b5ba159402..02e6967ae6 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -287,6 +287,7 @@ DEF_HELPER_FLAGS_4(gvec_vfi128, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfll32, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfll64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vflr64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
+DEF_HELPER_FLAGS_4(gvec_vflr128, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 472afca45e..e94c9f9d86 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2759,8 +2759,17 @@ static DisasJumpType op_vcdg(DisasContext *s, DisasOps *o)
}
break;
case 0xc5:
- if (fpf == FPF_LONG) {
+ switch (fpf) {
+ case FPF_LONG:
fn = gen_helper_gvec_vflr64;
+ break;
+ case FPF_EXT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vflr128;
+ }
+ break;
+ default:
+ break;
}
break;
default:
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 8b9f64e03f..65170ed307 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -565,6 +565,25 @@ void HELPER(gvec_vflr64)(void *v1, const void *v2, CPUS390XState *env,
*(S390Vector *)v1 = tmp;
}
+void HELPER(gvec_vflr128)(void *v1, const void *v2, CPUS390XState *env,
+ uint32_t desc)
+{
+ const uint8_t erm = extract32(simd_data(desc), 4, 4);
+ const bool XxC = extract32(simd_data(desc), 2, 1);
+ uint8_t vxc, vec_exc = 0;
+ int old_mode;
+ float64 ret;
+
+ old_mode = s390_swap_bfp_rounding_mode(env, erm);
+ ret = float128_to_float64(s390_vec_read_float128(v2), &env->fpu_status);
+ vxc = check_ieee_exc(env, 0, XxC, &vec_exc);
+ s390_restore_bfp_rounding_mode(env, old_mode);
+ handle_ieee_exc(env, vxc, vec_exc, GETPC());
+
+ /* place at even element, odd element is unpredictable */
+ s390_vec_write_float64(v1, 0, ret);
+}
+
static void vfma64(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
const S390Vector *v4, CPUS390XState *env, bool s, int flags,
uintptr_t retaddr)
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 19/26] s390x/tcg: Implement 32/128 bit for VECTOR FP PERFORM SIGN OPERATION
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (17 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 18/26] s390x/tcg: Implement 128 bit for VECTOR FP LOAD ROUNDED David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 20/26] s390x/tcg: Implement 32/128 bit for VECTOR FP TEST DATA CLASS IMMEDIATE David Hildenbrand
` (6 subsequent siblings)
25 siblings, 0 replies; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/translate_vx.c.inc | 106 ++++++++++++++++++++++----------
1 file changed, 73 insertions(+), 33 deletions(-)
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index e94c9f9d86..4d1ccb4159 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2842,48 +2842,88 @@ static DisasJumpType op_vfpso(DisasContext *s, DisasOps *o)
const uint8_t fpf = get_field(s, m3);
const uint8_t m4 = get_field(s, m4);
const uint8_t m5 = get_field(s, m5);
+ const bool se = extract32(m4, 3, 1);
TCGv_i64 tmp;
- if (fpf != FPF_LONG || extract32(m4, 0, 3) || m5 > 2) {
+ if ((fpf != FPF_LONG && !s390_has_feat(S390_FEAT_VECTOR_ENH)) ||
+ extract32(m4, 0, 3) || m5 > 2) {
gen_program_exception(s, PGM_SPECIFICATION);
return DISAS_NORETURN;
}
- if (extract32(m4, 3, 1)) {
- tmp = tcg_temp_new_i64();
- read_vec_element_i64(tmp, v2, 0, ES_64);
- switch (m5) {
- case 0:
- /* sign bit is inverted (complement) */
- tcg_gen_xori_i64(tmp, tmp, 1ull << 63);
- break;
- case 1:
- /* sign bit is set to one (negative) */
- tcg_gen_ori_i64(tmp, tmp, 1ull << 63);
- break;
- case 2:
- /* sign bit is set to zero (positive) */
- tcg_gen_andi_i64(tmp, tmp, (1ull << 63) - 1);
- break;
+ switch (fpf) {
+ case FPF_SHORT:
+ if (!se) {
+ switch (m5) {
+ case 0:
+ /* sign bit is inverted (complement) */
+ gen_gvec_fn_2i(xori, ES_32, v1, v2, 1ull << 31);
+ break;
+ case 1:
+ /* sign bit is set to one (negative) */
+ gen_gvec_fn_2i(ori, ES_32, v1, v2, 1ull << 31);
+ break;
+ case 2:
+ /* sign bit is set to zero (positive) */
+ gen_gvec_fn_2i(andi, ES_32, v1, v2, (1ull << 31) - 1);
+ break;
+ }
+ return DISAS_NEXT;
}
- write_vec_element_i64(tmp, v1, 0, ES_64);
- tcg_temp_free_i64(tmp);
- } else {
- switch (m5) {
- case 0:
- /* sign bit is inverted (complement) */
- gen_gvec_fn_2i(xori, ES_64, v1, v2, 1ull << 63);
- break;
- case 1:
- /* sign bit is set to one (negative) */
- gen_gvec_fn_2i(ori, ES_64, v1, v2, 1ull << 63);
- break;
- case 2:
- /* sign bit is set to zero (positive) */
- gen_gvec_fn_2i(andi, ES_64, v1, v2, (1ull << 63) - 1);
- break;
+ break;
+ case FPF_LONG:
+ if (!se) {
+ switch (m5) {
+ case 0:
+ /* sign bit is inverted (complement) */
+ gen_gvec_fn_2i(xori, ES_64, v1, v2, 1ull << 63);
+ break;
+ case 1:
+ /* sign bit is set to one (negative) */
+ gen_gvec_fn_2i(ori, ES_64, v1, v2, 1ull << 63);
+ break;
+ case 2:
+ /* sign bit is set to zero (positive) */
+ gen_gvec_fn_2i(andi, ES_64, v1, v2, (1ull << 63) - 1);
+ break;
+ }
+ return DISAS_NEXT;
}
+ break;
+ case FPF_EXT:
+ /* Only a single element. */
+ break;
+ default:
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
}
+
+ /* With a single element, we are only interested in bit 0. */
+ tmp = tcg_temp_new_i64();
+ read_vec_element_i64(tmp, v2, 0, ES_64);
+ switch (m5) {
+ case 0:
+ /* sign bit is inverted (complement) */
+ tcg_gen_xori_i64(tmp, tmp, 1ull << 63);
+ break;
+ case 1:
+ /* sign bit is set to one (negative) */
+ tcg_gen_ori_i64(tmp, tmp, 1ull << 63);
+ break;
+ case 2:
+ /* sign bit is set to zero (positive) */
+ tcg_gen_andi_i64(tmp, tmp, (1ull << 63) - 1);
+ break;
+ }
+ write_vec_element_i64(tmp, v1, 0, ES_64);
+
+ if (fpf == FPF_EXT) {
+ read_vec_element_i64(tmp, v2, 1, ES_64);
+ write_vec_element_i64(tmp, v1, 1, ES_64);
+ }
+
+ tcg_temp_free_i64(tmp);
+
return DISAS_NEXT;
}
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 20/26] s390x/tcg: Implement 32/128 bit for VECTOR FP TEST DATA CLASS IMMEDIATE
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (18 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 19/26] s390x/tcg: Implement 32/128 bit for VECTOR FP PERFORM SIGN OPERATION David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-03 17:43 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 21/26] s390x/tcg: Implement 32/128 bit for VECTOR FP MULTIPLY AND (ADD|SUBTRACT) David Hildenbrand
` (5 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 2 ++
target/s390x/translate_vx.c.inc | 23 ++++++++++++++--
target/s390x/vec_fpu_helper.c | 47 +++++++++++++++++++++++++++++++++
3 files changed, 70 insertions(+), 2 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 02e6967ae6..bae73b9a56 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -299,7 +299,9 @@ DEF_HELPER_FLAGS_4(gvec_vfsq128, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfs32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfs64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfs128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_4(gvec_vftci32, void, ptr, cptr, env, i32)
DEF_HELPER_4(gvec_vftci64, void, ptr, cptr, env, i32)
+DEF_HELPER_4(gvec_vftci128, void, ptr, cptr, env, i32)
#ifndef CONFIG_USER_ONLY
DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 4d1ccb4159..765f75df9c 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2965,14 +2965,33 @@ static DisasJumpType op_vftci(DisasContext *s, DisasOps *o)
const uint16_t i3 = get_field(s, i3);
const uint8_t fpf = get_field(s, m4);
const uint8_t m5 = get_field(s, m5);
+ gen_helper_gvec_2_ptr *fn = NULL;
- if (fpf != FPF_LONG || extract32(m5, 0, 3)) {
+ switch (fpf) {
+ case FPF_SHORT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vftci32;
+ }
+ break;
+ case FPF_LONG:
+ fn = gen_helper_gvec_vftci64;
+ break;
+ case FPF_EXT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vftci128;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!fn || extract32(m5, 0, 3)) {
gen_program_exception(s, PGM_SPECIFICATION);
return DISAS_NORETURN;
}
gen_gvec_2_ptr(get_field(s, v1), get_field(s, v2), cpu_env,
- deposit32(m5, 4, 12, i3), gen_helper_gvec_vftci64);
+ deposit32(m5, 4, 12, i3), fn);
set_cc_static(s);
return DISAS_NEXT;
}
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 65170ed307..4c10734c4e 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -624,6 +624,36 @@ void HELPER(gvec_##NAME##BITS)(void *v1, const void *v2, const void *v3, \
DEF_GVEC_VFMA(vfma, 0)
DEF_GVEC_VFMA(vfms, float_muladd_negate_c)
+void HELPER(gvec_vftci32)(void *v1, const void *v2, CPUS390XState *env,
+ uint32_t desc)
+{
+ uint16_t i3 = extract32(simd_data(desc), 4, 12);
+ bool s = extract32(simd_data(desc), 3, 1);
+ int i, match = 0;
+
+ for (i = 0; i < 4; i++) {
+ float32 a = s390_vec_read_float32(v2, i);
+
+ if (float32_dcmask(env, a) & i3) {
+ match++;
+ s390_vec_write_element32(v1, i, -1u);
+ } else {
+ s390_vec_write_element32(v1, i, 0);
+ }
+ if (s) {
+ break;
+ }
+ }
+
+ if (match == 4 || (s && match)) {
+ env->cc_op = 0;
+ } else if (match) {
+ env->cc_op = 1;
+ } else {
+ env->cc_op = 3;
+ }
+}
+
void HELPER(gvec_vftci64)(void *v1, const void *v2, CPUS390XState *env,
uint32_t desc)
{
@@ -653,3 +683,20 @@ void HELPER(gvec_vftci64)(void *v1, const void *v2, CPUS390XState *env,
env->cc_op = 3;
}
}
+
+void HELPER(gvec_vftci128)(void *v1, const void *v2, CPUS390XState *env,
+ uint32_t desc)
+{
+ const float128 a = s390_vec_read_float128(v2);
+ uint16_t i3 = extract32(simd_data(desc), 4, 12);
+
+ if (float128_dcmask(env, a) & i3) {
+ env->cc_op = 0;
+ s390_vec_write_element64(v1, 0, -1ull);
+ s390_vec_write_element64(v1, 1, -1ull);
+ } else {
+ env->cc_op = 3;
+ s390_vec_write_element64(v1, 0, 0);
+ s390_vec_write_element64(v1, 1, 0);
+ }
+}
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 21/26] s390x/tcg: Implement 32/128 bit for VECTOR FP MULTIPLY AND (ADD|SUBTRACT)
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (19 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 20/26] s390x/tcg: Implement 32/128 bit for VECTOR FP TEST DATA CLASS IMMEDIATE David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-03 17:44 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 22/26] s390x/tcg: Implement VECTOR FP NEGATIVE " David Hildenbrand
` (4 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 4 +++
target/s390x/translate_vx.c.inc | 47 ++++++++++++++++++++++++++++-----
target/s390x/vec_fpu_helper.c | 44 +++++++++++++++++++++++++++++-
3 files changed, 87 insertions(+), 8 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index bae73b9a56..2366756063 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -291,8 +291,12 @@ DEF_HELPER_FLAGS_4(gvec_vflr128, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_6(gvec_vfma32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfma64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_6(gvec_vfma128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_6(gvec_vfms32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfms64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_6(gvec_vfms128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfsq32, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfsq64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfsq128, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 765f75df9c..17d41b178f 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2818,18 +2818,51 @@ static DisasJumpType op_vfma(DisasContext *s, DisasOps *o)
{
const uint8_t m5 = get_field(s, m5);
const uint8_t fpf = get_field(s, m6);
- gen_helper_gvec_4_ptr *fn;
+ gen_helper_gvec_4_ptr *fn = NULL;
- if (fpf != FPF_LONG || extract32(m5, 0, 3)) {
+ if (s->fields.op2 == 0x8f) {
+ switch (fpf) {
+ case FPF_SHORT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vfma32;
+ }
+ break;
+ case FPF_LONG:
+ fn = gen_helper_gvec_vfma64;
+ break;
+ case FPF_EXT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vfma128;
+ }
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (fpf) {
+ case FPF_SHORT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vfms32;
+ }
+ break;
+ case FPF_LONG:
+ fn = gen_helper_gvec_vfms64;
+ break;
+ case FPF_EXT:
+ if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
+ fn = gen_helper_gvec_vfms128;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!fn || extract32(m5, 0, 3)) {
gen_program_exception(s, PGM_SPECIFICATION);
return DISAS_NORETURN;
}
- if (s->fields.op2 == 0x8f) {
- fn = gen_helper_gvec_vfma64;
- } else {
- fn = gen_helper_gvec_vfms64;
- }
gen_gvec_4_ptr(get_field(s, v1), get_field(s, v2),
get_field(s, v3), get_field(s, v4), cpu_env, m5, fn);
return DISAS_NEXT;
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 4c10734c4e..966b1dbf50 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -584,6 +584,30 @@ void HELPER(gvec_vflr128)(void *v1, const void *v2, CPUS390XState *env,
s390_vec_write_float64(v1, 0, ret);
}
+static void vfma32(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
+ const S390Vector *v4, CPUS390XState *env, bool s, int flags,
+ uintptr_t retaddr)
+{
+ uint8_t vxc, vec_exc = 0;
+ S390Vector tmp = {};
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ const float32 a = s390_vec_read_float32(v2, i);
+ const float32 b = s390_vec_read_float32(v3, i);
+ const float32 c = s390_vec_read_float32(v4, i);
+ float32 ret = float32_muladd(a, b, c, flags, &env->fpu_status);
+
+ s390_vec_write_float32(&tmp, i, ret);
+ vxc = check_ieee_exc(env, i, false, &vec_exc);
+ if (s || vxc) {
+ break;
+ }
+ }
+ handle_ieee_exc(env, vxc, vec_exc, retaddr);
+ *v1 = tmp;
+}
+
static void vfma64(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
const S390Vector *v4, CPUS390XState *env, bool s, int flags,
uintptr_t retaddr)
@@ -608,6 +632,22 @@ static void vfma64(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
*v1 = tmp;
}
+static void vfma128(S390Vector *v1, const S390Vector *v2, const S390Vector *v3,
+ const S390Vector *v4, CPUS390XState *env, bool s, int flags,
+ uintptr_t retaddr)
+{
+ const float128 a = s390_vec_read_float128(v2);
+ const float128 b = s390_vec_read_float128(v3);
+ const float128 c = s390_vec_read_float128(v4);
+ uint8_t vxc, vec_exc = 0;
+ float128 ret;
+
+ ret = float128_muladd(a, b, c, flags, &env->fpu_status);
+ vxc = check_ieee_exc(env, 0, false, &vec_exc);
+ handle_ieee_exc(env, vxc, vec_exc, retaddr);
+ s390_vec_write_float128(v1, ret);
+}
+
#define DEF_GVEC_VFMA_B(NAME, FLAGS, BITS) \
void HELPER(gvec_##NAME##BITS)(void *v1, const void *v2, const void *v3, \
const void *v4, CPUS390XState *env, \
@@ -619,7 +659,9 @@ void HELPER(gvec_##NAME##BITS)(void *v1, const void *v2, const void *v3, \
}
#define DEF_GVEC_VFMA(NAME, FLAGS) \
- DEF_GVEC_VFMA_B(NAME, FLAGS, 64)
+ DEF_GVEC_VFMA_B(NAME, FLAGS, 32) \
+ DEF_GVEC_VFMA_B(NAME, FLAGS, 64) \
+ DEF_GVEC_VFMA_B(NAME, FLAGS, 128)
DEF_GVEC_VFMA(vfma, 0)
DEF_GVEC_VFMA(vfms, float_muladd_negate_c)
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 22/26] s390x/tcg: Implement VECTOR FP NEGATIVE MULTIPLY AND (ADD|SUBTRACT)
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (20 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 21/26] s390x/tcg: Implement 32/128 bit for VECTOR FP MULTIPLY AND (ADD|SUBTRACT) David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-03 17:45 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 23/26] softfloat: Implement float128_(min|minnum|minnummag|max|maxnum|maxnummag) David Hildenbrand
` (3 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 6 +++++
target/s390x/insn-data.def | 4 ++++
target/s390x/translate_vx.c.inc | 39 +++++++++++++++++++++++++++++++--
target/s390x/vec_fpu_helper.c | 2 ++
4 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 2366756063..913967ce4e 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -297,6 +297,12 @@ DEF_HELPER_FLAGS_6(gvec_vfma128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, en
DEF_HELPER_FLAGS_6(gvec_vfms32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfms64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfms128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_6(gvec_vfnma32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_6(gvec_vfnma64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_6(gvec_vfnma128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_6(gvec_vfnms32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_6(gvec_vfnms64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_6(gvec_vfnms128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfsq32, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfsq64, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_4(gvec_vfsq128, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 1a3ae7e7e7..19b02dffca 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1259,6 +1259,10 @@
F(0xe78f, VFMA, VRR_e, V, 0, 0, 0, 0, vfma, 0, IF_VEC)
/* VECTOR FP MULTIPLY AND SUBTRACT */
F(0xe78e, VFMS, VRR_e, V, 0, 0, 0, 0, vfma, 0, IF_VEC)
+/* VECTOR FP NEGATIVE MULTIPLY AND ADD */
+ F(0xe79f, VFNMA, VRR_e, VE, 0, 0, 0, 0, vfma, 0, IF_VEC)
+/* VECTOR FP NEGATIVE MULTIPLY AND SUBTRACT */
+ F(0xe79e, VFNMS, VRR_e, VE, 0, 0, 0, 0, vfma, 0, IF_VEC)
/* VECTOR FP PERFORM SIGN OPERATION */
F(0xe7cc, VFPSO, VRR_a, V, 0, 0, 0, 0, vfpso, 0, IF_VEC)
/* VECTOR FP SQUARE ROOT */
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 17d41b178f..200d83e783 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2820,7 +2820,8 @@ static DisasJumpType op_vfma(DisasContext *s, DisasOps *o)
const uint8_t fpf = get_field(s, m6);
gen_helper_gvec_4_ptr *fn = NULL;
- if (s->fields.op2 == 0x8f) {
+ switch (s->fields.op2) {
+ case 0x8f:
switch (fpf) {
case FPF_SHORT:
if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
@@ -2838,7 +2839,8 @@ static DisasJumpType op_vfma(DisasContext *s, DisasOps *o)
default:
break;
}
- } else {
+ break;
+ case 0x8e:
switch (fpf) {
case FPF_SHORT:
if (s390_has_feat(S390_FEAT_VECTOR_ENH)) {
@@ -2856,6 +2858,39 @@ static DisasJumpType op_vfma(DisasContext *s, DisasOps *o)
default:
break;
}
+ break;
+ case 0x9f:
+ switch (fpf) {
+ case FPF_SHORT:
+ fn = gen_helper_gvec_vfnma32;
+ break;
+ case FPF_LONG:
+ fn = gen_helper_gvec_vfnma64;
+ break;
+ case FPF_EXT:
+ fn = gen_helper_gvec_vfnma128;
+ break;
+ default:
+ break;
+ }
+ break;
+ case 0x9e:
+ switch (fpf) {
+ case FPF_SHORT:
+ fn = gen_helper_gvec_vfnms32;
+ break;
+ case FPF_LONG:
+ fn = gen_helper_gvec_vfnms64;
+ break;
+ case FPF_EXT:
+ fn = gen_helper_gvec_vfnms128;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ g_assert_not_reached();
}
if (!fn || extract32(m5, 0, 3)) {
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index 966b1dbf50..f6090f7d61 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -665,6 +665,8 @@ void HELPER(gvec_##NAME##BITS)(void *v1, const void *v2, const void *v3, \
DEF_GVEC_VFMA(vfma, 0)
DEF_GVEC_VFMA(vfms, float_muladd_negate_c)
+DEF_GVEC_VFMA(vfnma, float_muladd_negate_result)
+DEF_GVEC_VFMA(vfnms, float_muladd_negate_c | float_muladd_negate_result)
void HELPER(gvec_vftci32)(void *v1, const void *v2, CPUS390XState *env,
uint32_t desc)
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 23/26] softfloat: Implement float128_(min|minnum|minnummag|max|maxnum|maxnummag)
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (21 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 22/26] s390x/tcg: Implement VECTOR FP NEGATIVE " David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-03 17:01 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 24/26] s390x/tcg: Implement VECTOR FP (MAXIMUM|MINIMUM) David Hildenbrand
` (2 subsequent siblings)
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
With Richard's softfloat rework, the float128 implementation is
straight-forward. Unfortuantely, we don't have any tests we can simply
adjust/unlock.
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: "Alex Bennée" <alex.bennee@linaro.org>
Cc: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
fpu/softfloat.c | 17 +++++++++++++++++
include/fpu/softfloat.h | 6 ++++++
2 files changed, 23 insertions(+)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 7376b3470c..bfe5a6b975 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -3893,6 +3893,22 @@ static float64 float64_minmax(float64 a, float64 b, float_status *s, int flags)
return which ? b : a;
}
+static float128 float128_minmax(float128 a, float128 b, float_status *s,
+ int flags)
+{
+ FloatParts128 pa, pb;
+ int which;
+
+ float128_unpack_canonical(&pa, a, s);
+ float128_unpack_canonical(&pb, b, s);
+ which = parts_minmax(&pa, &pb, s, flags, &float64_params);
+ if (unlikely(which < 0)) {
+ /* Some sort of nan, need to repack default and silenced nans. */
+ return float128_round_pack_canonical(&pa, s);
+ }
+ return which ? b : a;
+}
+
#define MINMAX_1(type, name, flags) \
type type##_##name(type a, type b, float_status *s) \
{ return type##_minmax(a, b, s, flags); }
@@ -3909,6 +3925,7 @@ MINMAX_2(float16)
MINMAX_2(bfloat16)
MINMAX_2(float32)
MINMAX_2(float64)
+MINMAX_2(float128)
#undef MINMAX_1
#undef MINMAX_2
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 94f7841b9f..ec7dca0960 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -1204,6 +1204,12 @@ float128 float128_rem(float128, float128, float_status *status);
float128 float128_sqrt(float128, float_status *status);
FloatRelation float128_compare(float128, float128, float_status *status);
FloatRelation float128_compare_quiet(float128, float128, float_status *status);
+float128 float128_min(float128, float128, float_status *status);
+float128 float128_max(float128, float128, float_status *status);
+float128 float128_minnum(float128, float128, float_status *status);
+float128 float128_maxnum(float128, float128, float_status *status);
+float128 float128_minnummag(float128, float128, float_status *status);
+float128 float128_maxnummag(float128, float128, float_status *status);
bool float128_is_quiet_nan(float128, float_status *status);
bool float128_is_signaling_nan(float128, float_status *status);
float128 float128_silence_nan(float128, float_status *status);
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 24/26] s390x/tcg: Implement VECTOR FP (MAXIMUM|MINIMUM)
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (22 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 23/26] softfloat: Implement float128_(min|minnum|minnummag|max|maxnum|maxnummag) David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-03 18:13 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 25/26] s390x/tcg: We support Vector enhancements facility David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 26/26] s390x/cpumodel: Bump up QEMU model to a stripped-down IBM z14 GA2 David Hildenbrand
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
For IEEE functions, we can reuse the softfloat implementations. For the
other functions, implement it generically for 32bit/64bit/128bit -
carefully taking care of all weird special cases according to the tables
defined in the PoP.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/helper.h | 6 +
target/s390x/insn-data.def | 4 +
target/s390x/internal.h | 9 +
target/s390x/translate_vx.c.inc | 44 ++++
target/s390x/vec_fpu_helper.c | 361 ++++++++++++++++++++++++++++++++
5 files changed, 424 insertions(+)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 913967ce4e..ba045f559d 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -291,6 +291,12 @@ DEF_HELPER_FLAGS_4(gvec_vflr128, TCG_CALL_NO_WG, void, ptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vfm128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfmax32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfmax64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfmax128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfmin32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfmin64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
+DEF_HELPER_FLAGS_5(gvec_vfmin128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfma32, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfma64, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_6(gvec_vfma128, TCG_CALL_NO_WG, void, ptr, cptr, cptr, cptr, env, i32)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 19b02dffca..3e5594210c 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -1253,6 +1253,10 @@
F(0xe7c4, VFLL, VRR_a, V, 0, 0, 0, 0, vfll, 0, IF_VEC)
/* VECTOR FP LOAD ROUNDED */
F(0xe7c5, VFLR, VRR_a, V, 0, 0, 0, 0, vcdg, 0, IF_VEC)
+/* VECTOR FP MAXIMUM */
+ F(0xe7ef, VFMAX, VRR_c, VE, 0, 0, 0, 0, vfmax, 0, IF_VEC)
+/* VECTOR FP MINIMUM */
+ F(0xe7ee, VFMIN, VRR_c, VE, 0, 0, 0, 0, vfmax, 0, IF_VEC)
/* VECTOR FP MULTIPLY */
F(0xe7e7, VFM, VRR_c, V, 0, 0, 0, 0, vfa, 0, IF_VEC)
/* VECTOR FP MULTIPLY AND ADD */
diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index 11515bb617..d62dfc4dc6 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -288,6 +288,15 @@ uint8_t s390_softfloat_exc_to_ieee(unsigned int exc);
int s390_swap_bfp_rounding_mode(CPUS390XState *env, int m3);
void s390_restore_bfp_rounding_mode(CPUS390XState *env, int old_mode);
int float_comp_to_cc(CPUS390XState *env, int float_compare);
+
+#define DCMASK_ZERO 0x0c00
+#define DCMASK_NORMAL 0x0300
+#define DCMASK_SUBNORMAL 0x00c0
+#define DCMASK_INFINITY 0x0030
+#define DCMASK_QUIET_NAN 0x000c
+#define DCMASK_SIGNALING_NAN 0x0003
+#define DCMASK_NAN 0x000f
+#define DCMASK_NEGATIVE 0x0555
uint16_t float32_dcmask(CPUS390XState *env, float32 f1);
uint16_t float64_dcmask(CPUS390XState *env, float64 f1);
uint16_t float128_dcmask(CPUS390XState *env, float128 f1);
diff --git a/target/s390x/translate_vx.c.inc b/target/s390x/translate_vx.c.inc
index 200d83e783..a9d51b1f4c 100644
--- a/target/s390x/translate_vx.c.inc
+++ b/target/s390x/translate_vx.c.inc
@@ -2814,6 +2814,50 @@ static DisasJumpType op_vfll(DisasContext *s, DisasOps *o)
return DISAS_NEXT;
}
+static DisasJumpType op_vfmax(DisasContext *s, DisasOps *o)
+{
+ const uint8_t fpf = get_field(s, m4);
+ const uint8_t m6 = get_field(s, m6);
+ const uint8_t m5 = get_field(s, m5);
+ gen_helper_gvec_3_ptr *fn;
+
+ if (m6 == 5 || m6 == 6 || m6 == 7 || m6 > 13) {
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ switch (fpf) {
+ case FPF_SHORT:
+ if (s->fields.op2 == 0xef) {
+ fn = gen_helper_gvec_vfmax32;
+ } else {
+ fn = gen_helper_gvec_vfmin32;
+ }
+ break;
+ case FPF_LONG:
+ if (s->fields.op2 == 0xef) {
+ fn = gen_helper_gvec_vfmax64;
+ } else {
+ fn = gen_helper_gvec_vfmin64;
+ }
+ break;
+ case FPF_EXT:
+ if (s->fields.op2 == 0xef) {
+ fn = gen_helper_gvec_vfmax128;
+ } else {
+ fn = gen_helper_gvec_vfmin128;
+ }
+ break;
+ default:
+ gen_program_exception(s, PGM_SPECIFICATION);
+ return DISAS_NORETURN;
+ }
+
+ gen_gvec_3_ptr(get_field(s, v1), get_field(s, v2), get_field(s, v3),
+ cpu_env, deposit32(m5, 4, 4, m6), fn);
+ return DISAS_NEXT;
+}
+
static DisasJumpType op_vfma(DisasContext *s, DisasOps *o)
{
const uint8_t m5 = get_field(s, m5);
diff --git a/target/s390x/vec_fpu_helper.c b/target/s390x/vec_fpu_helper.c
index f6090f7d61..aab20739e0 100644
--- a/target/s390x/vec_fpu_helper.c
+++ b/target/s390x/vec_fpu_helper.c
@@ -744,3 +744,364 @@ void HELPER(gvec_vftci128)(void *v1, const void *v2, CPUS390XState *env,
s390_vec_write_element64(v1, 1, 0);
}
}
+
+typedef enum S390MinMaxType {
+ S390_MINMAX_TYPE_IEEE = 0,
+ S390_MINMAX_TYPE_JAVA,
+ S390_MINMAX_TYPE_C_MACRO,
+ S390_MINMAX_TYPE_CPP,
+ S390_MINMAX_TYPE_F,
+} S390MinMaxType;
+
+typedef enum S390MinMaxRes {
+ S390_MINMAX_RES_MINMAX = 0,
+ S390_MINMAX_RES_A,
+ S390_MINMAX_RES_B,
+ S390_MINMAX_RES_SILENCE_A,
+ S390_MINMAX_RES_SILENCE_B,
+} S390MinMaxRes;
+
+static S390MinMaxRes vfmin_res(uint16_t dcmask_a, uint16_t dcmask_b,
+ S390MinMaxType type, float_status *s)
+{
+ const bool neg_a = dcmask_a & DCMASK_NEGATIVE;
+ const bool neg_b = dcmask_b & DCMASK_NEGATIVE;
+ const bool inf_a = dcmask_a & DCMASK_INFINITY;
+ const bool inf_b = dcmask_b & DCMASK_INFINITY;
+ const bool zero_a = dcmask_a & DCMASK_ZERO;
+ const bool zero_b = dcmask_b & DCMASK_ZERO;
+ const bool nan_a = dcmask_a & DCMASK_NAN;
+ const bool nan_b = dcmask_b & DCMASK_NAN;
+
+ g_assert(type > S390_MINMAX_TYPE_IEEE && type <= S390_MINMAX_TYPE_F);
+
+ if (unlikely(nan_a || nan_b)) {
+ const bool sig_a = dcmask_a & DCMASK_SIGNALING_NAN;
+ const bool sig_b = dcmask_b & DCMASK_SIGNALING_NAN;
+
+ if (sig_a || sig_b) {
+ s->float_exception_flags |= float_flag_invalid;
+ }
+ switch (type) {
+ case S390_MINMAX_TYPE_JAVA:
+ if (sig_a) {
+ return S390_MINMAX_RES_SILENCE_A;
+ } else if (sig_b) {
+ return S390_MINMAX_RES_SILENCE_B;
+ }
+ return nan_a ? S390_MINMAX_RES_A : S390_MINMAX_RES_B;
+ case S390_MINMAX_TYPE_F:
+ return nan_b ? S390_MINMAX_RES_A : S390_MINMAX_RES_B;
+ case S390_MINMAX_TYPE_C_MACRO:
+ s->float_exception_flags |= float_flag_invalid;
+ return S390_MINMAX_RES_B;
+ case S390_MINMAX_TYPE_CPP:
+ s->float_exception_flags |= float_flag_invalid;
+ return S390_MINMAX_RES_A;
+ default:
+ g_assert_not_reached();
+ }
+ } else if (unlikely(inf_a && inf_b)) {
+ switch (type) {
+ case S390_MINMAX_TYPE_JAVA:
+ return neg_a && !neg_b ? S390_MINMAX_RES_A : S390_MINMAX_RES_B;
+ case S390_MINMAX_TYPE_C_MACRO:
+ case S390_MINMAX_TYPE_CPP:
+ return neg_b ? S390_MINMAX_RES_B : S390_MINMAX_RES_A;
+ case S390_MINMAX_TYPE_F:
+ return !neg_a && neg_b ? S390_MINMAX_RES_B : S390_MINMAX_RES_A;
+ default:
+ g_assert_not_reached();
+ }
+ } else if (unlikely(zero_a && zero_b)) {
+ switch (type) {
+ case S390_MINMAX_TYPE_JAVA:
+ return neg_a && !neg_b ? S390_MINMAX_RES_A : S390_MINMAX_RES_B;
+ case S390_MINMAX_TYPE_C_MACRO:
+ return S390_MINMAX_RES_B;
+ case S390_MINMAX_TYPE_F:
+ return !neg_a && neg_b ? S390_MINMAX_RES_B : S390_MINMAX_RES_A;
+ case S390_MINMAX_TYPE_CPP:
+ return S390_MINMAX_RES_A;
+ default:
+ g_assert_not_reached();
+ }
+ }
+ return S390_MINMAX_RES_MINMAX;
+}
+
+static S390MinMaxRes vfmax_res(uint16_t dcmask_a, uint16_t dcmask_b,
+ S390MinMaxType type, float_status *s)
+{
+ const bool neg_a = dcmask_a & DCMASK_NEGATIVE;
+ const bool neg_b = dcmask_b & DCMASK_NEGATIVE;
+ const bool inf_a = dcmask_a & DCMASK_INFINITY;
+ const bool inf_b = dcmask_b & DCMASK_INFINITY;
+ const bool zero_a = dcmask_a & DCMASK_ZERO;
+ const bool zero_b = dcmask_b & DCMASK_ZERO;
+ const bool nan_a = dcmask_a & DCMASK_NAN;
+ const bool nan_b = dcmask_b & DCMASK_NAN;
+
+ g_assert(type > S390_MINMAX_TYPE_IEEE && type <= S390_MINMAX_TYPE_F);
+
+ if (unlikely(nan_a || nan_b)) {
+ const bool sig_a = dcmask_a & DCMASK_SIGNALING_NAN;
+ const bool sig_b = dcmask_b & DCMASK_SIGNALING_NAN;
+
+ if (sig_a || sig_b) {
+ s->float_exception_flags |= float_flag_invalid;
+ }
+ switch (type) {
+ case S390_MINMAX_TYPE_JAVA:
+ if (sig_a) {
+ return S390_MINMAX_RES_SILENCE_A;
+ } else if (sig_b) {
+ return S390_MINMAX_RES_SILENCE_B;
+ }
+ return nan_a ? S390_MINMAX_RES_A : S390_MINMAX_RES_B;
+ case S390_MINMAX_TYPE_F:
+ return nan_b ? S390_MINMAX_RES_A : S390_MINMAX_RES_B;
+ case S390_MINMAX_TYPE_C_MACRO:
+ s->float_exception_flags |= float_flag_invalid;
+ return S390_MINMAX_RES_B;
+ case S390_MINMAX_TYPE_CPP:
+ s->float_exception_flags |= float_flag_invalid;
+ return S390_MINMAX_RES_A;
+ default:
+ g_assert_not_reached();
+ }
+ } else if (unlikely(inf_a && inf_b)) {
+ switch (type) {
+ case S390_MINMAX_TYPE_JAVA:
+ case S390_MINMAX_TYPE_F:
+ case S390_MINMAX_TYPE_CPP:
+ return neg_a && !neg_b ? S390_MINMAX_RES_B : S390_MINMAX_RES_A;
+ case S390_MINMAX_TYPE_C_MACRO:
+ return !neg_a && neg_b ? S390_MINMAX_RES_A : S390_MINMAX_RES_B;
+ default:
+ g_assert_not_reached();
+ }
+ } else if (unlikely(zero_a && zero_b)) {
+ switch (type) {
+ case S390_MINMAX_TYPE_JAVA:
+ case S390_MINMAX_TYPE_F:
+ return neg_a && !neg_b ? S390_MINMAX_RES_B : S390_MINMAX_RES_A;
+ case S390_MINMAX_TYPE_C_MACRO:
+ return S390_MINMAX_RES_B;
+ case S390_MINMAX_TYPE_CPP:
+ return S390_MINMAX_RES_A;
+ default:
+ g_assert_not_reached();
+ }
+ }
+ return S390_MINMAX_RES_MINMAX;
+}
+
+static S390MinMaxRes vfminmax_res(uint16_t dcmask_a, uint16_t dcmask_b,
+ S390MinMaxType type, bool is_min,
+ float_status *s)
+{
+ return is_min ? vfmin_res(dcmask_a, dcmask_b, type, s) :
+ vfmax_res(dcmask_a, dcmask_b, type, s);
+}
+
+static void vfminmax32(S390Vector *v1, const S390Vector *v2,
+ const S390Vector *v3, CPUS390XState *env,
+ S390MinMaxType type, bool is_min, bool is_abs, bool se,
+ uintptr_t retaddr)
+{
+ float_status *s = &env->fpu_status;
+ uint8_t vxc, vec_exc = 0;
+ S390Vector tmp = {};
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ float32 a = s390_vec_read_float32(v2, i);
+ float32 b = s390_vec_read_float32(v3, i);
+ float32 result;
+
+ if (type != S390_MINMAX_TYPE_IEEE) {
+ S390MinMaxRes res;
+
+ if (is_abs) {
+ a = float32_abs(a);
+ b = float32_abs(b);
+ }
+
+ res = vfminmax_res(float32_dcmask(env, a), float32_dcmask(env, b),
+ type, is_min, s);
+ switch (res) {
+ case S390_MINMAX_RES_MINMAX:
+ result = is_min ? float32_min(a, b, s) : float32_max(a, b, s);
+ break;
+ case S390_MINMAX_RES_A:
+ result = a;
+ break;
+ case S390_MINMAX_RES_B:
+ result = b;
+ break;
+ case S390_MINMAX_RES_SILENCE_A:
+ result = float32_silence_nan(a, s);
+ break;
+ case S390_MINMAX_RES_SILENCE_B:
+ result = float32_silence_nan(b, s);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ } else if (!is_abs) {
+ result = is_min ? float32_minnum(a, b, &env->fpu_status) :
+ float32_maxnum(a, b, &env->fpu_status);
+ } else {
+ result = is_min ? float32_minnummag(a, b, &env->fpu_status) :
+ float32_maxnummag(a, b, &env->fpu_status);
+ }
+
+ s390_vec_write_float32(&tmp, i, result);
+ vxc = check_ieee_exc(env, i, false, &vec_exc);
+ if (se || vxc) {
+ break;
+ }
+ }
+ handle_ieee_exc(env, vxc, vec_exc, retaddr);
+ *v1 = tmp;
+}
+
+static void vfminmax64(S390Vector *v1, const S390Vector *v2,
+ const S390Vector *v3, CPUS390XState *env,
+ S390MinMaxType type, bool is_min, bool is_abs, bool se,
+ uintptr_t retaddr)
+{
+ float_status *s = &env->fpu_status;
+ uint8_t vxc, vec_exc = 0;
+ S390Vector tmp = {};
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ float64 a = s390_vec_read_float64(v2, i);
+ float64 b = s390_vec_read_float64(v3, i);
+ float64 result;
+
+ if (type != S390_MINMAX_TYPE_IEEE) {
+ S390MinMaxRes res;
+
+ if (is_abs) {
+ a = float64_abs(a);
+ b = float64_abs(b);
+ }
+
+ res = vfminmax_res(float64_dcmask(env, a), float64_dcmask(env, b),
+ type, is_min, s);
+ switch (res) {
+ case S390_MINMAX_RES_MINMAX:
+ result = is_min ? float64_min(a, b, s) : float64_max(a, b, s);
+ break;
+ case S390_MINMAX_RES_A:
+ result = a;
+ break;
+ case S390_MINMAX_RES_B:
+ result = b;
+ break;
+ case S390_MINMAX_RES_SILENCE_A:
+ result = float64_silence_nan(a, s);
+ break;
+ case S390_MINMAX_RES_SILENCE_B:
+ result = float64_silence_nan(b, s);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ } else if (!is_abs) {
+ result = is_min ? float64_minnum(a, b, &env->fpu_status) :
+ float64_maxnum(a, b, &env->fpu_status);
+ } else {
+ result = is_min ? float64_minnummag(a, b, &env->fpu_status) :
+ float64_maxnummag(a, b, &env->fpu_status);
+ }
+
+ s390_vec_write_float64(&tmp, i, result);
+ vxc = check_ieee_exc(env, i, false, &vec_exc);
+ if (se || vxc) {
+ break;
+ }
+ }
+ handle_ieee_exc(env, vxc, vec_exc, retaddr);
+ *v1 = tmp;
+}
+
+static void vfminmax128(S390Vector *v1, const S390Vector *v2,
+ const S390Vector *v3, CPUS390XState *env,
+ S390MinMaxType type, bool is_min, bool is_abs, bool se,
+ uintptr_t retaddr)
+{
+ float128 a = s390_vec_read_float128(v2);
+ float128 b = s390_vec_read_float128(v3);
+ float_status *s = &env->fpu_status;
+ uint8_t vxc, vec_exc = 0;
+ float128 result;
+
+ if (type != S390_MINMAX_TYPE_IEEE) {
+ S390MinMaxRes res;
+
+ if (is_abs) {
+ a = float128_abs(a);
+ b = float128_abs(b);
+ }
+
+ res = vfminmax_res(float128_dcmask(env, a), float128_dcmask(env, b),
+ type, is_min, s);
+ switch (res) {
+ case S390_MINMAX_RES_MINMAX:
+ result = is_min ? float128_min(a, b, s) : float128_max(a, b, s);
+ break;
+ case S390_MINMAX_RES_A:
+ result = a;
+ break;
+ case S390_MINMAX_RES_B:
+ result = b;
+ break;
+ case S390_MINMAX_RES_SILENCE_A:
+ result = float128_silence_nan(a, s);
+ break;
+ case S390_MINMAX_RES_SILENCE_B:
+ result = float128_silence_nan(b, s);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ } else if (!is_abs) {
+ result = is_min ? float128_minnum(a, b, &env->fpu_status) :
+ float128_maxnum(a, b, &env->fpu_status);
+ } else {
+ result = is_min ? float128_minnummag(a, b, &env->fpu_status) :
+ float128_maxnummag(a, b, &env->fpu_status);
+ }
+
+ vxc = check_ieee_exc(env, 0, false, &vec_exc);
+ handle_ieee_exc(env, vxc, vec_exc, retaddr);
+ s390_vec_write_float128(v1, result);
+}
+
+#define DEF_GVEC_VFMINMAX_B(NAME, IS_MIN, BITS) \
+void HELPER(gvec_##NAME##BITS)(void *v1, const void *v2, const void *v3, \
+ CPUS390XState *env, uint32_t desc) \
+{ \
+ const uint8_t se = extract32(simd_data(desc), 3, 1); \
+ uint8_t type = extract32(simd_data(desc), 4, 4); \
+ bool is_abs = false; \
+ \
+ if (type >= 8) { \
+ is_abs = true; \
+ type -= 8; \
+ } \
+ \
+ vfminmax##BITS(v1, v2, v3, env, type, IS_MIN, is_abs, se, GETPC()); \
+}
+
+#define DEF_GVEC_VFMINMAX(NAME, IS_MIN) \
+ DEF_GVEC_VFMINMAX_B(NAME, IS_MIN, 32) \
+ DEF_GVEC_VFMINMAX_B(NAME, IS_MIN, 64) \
+ DEF_GVEC_VFMINMAX_B(NAME, IS_MIN, 128)
+
+DEF_GVEC_VFMINMAX(vfmax, false)
+DEF_GVEC_VFMINMAX(vfmin, true)
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 25/26] s390x/tcg: We support Vector enhancements facility
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (23 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 24/26] s390x/tcg: Implement VECTOR FP (MAXIMUM|MINIMUM) David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
2021-06-07 7:47 ` David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 26/26] s390x/cpumodel: Bump up QEMU model to a stripped-down IBM z14 GA2 David Hildenbrand
25 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/gen-features.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
index a6ec918e90..219b1f9420 100644
--- a/target/s390x/gen-features.c
+++ b/target/s390x/gen-features.c
@@ -720,6 +720,7 @@ static uint16_t qemu_MAX[] = {
S390_FEAT_INSTRUCTION_EXEC_PROT,
S390_FEAT_MISC_INSTRUCTION_EXT2,
S390_FEAT_MSA_EXT_8,
+ S390_FEAT_VECTOR_ENH,
};
/****** END FEATURE DEFS ******/
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* [PATCH v2 26/26] s390x/cpumodel: Bump up QEMU model to a stripped-down IBM z14 GA2
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
` (24 preceding siblings ...)
2021-05-17 14:27 ` [PATCH v2 25/26] s390x/tcg: We support Vector enhancements facility David Hildenbrand
@ 2021-05-17 14:27 ` David Hildenbrand
25 siblings, 0 replies; 50+ messages in thread
From: David Hildenbrand @ 2021-05-17 14:27 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, David Hildenbrand, Cornelia Huck,
Richard Henderson, Halil Pasic, Christian Borntraeger,
qemu-s390x, Alex Bennée, Aurelien Jarno
TCG implements everything we need to run basic z14 OS+software.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
hw/s390x/s390-virtio-ccw.c | 3 +++
target/s390x/cpu_models.c | 4 ++--
target/s390x/gen-features.c | 15 +++++++++------
3 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 7af27ca305..e4b18aef49 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -802,7 +802,10 @@ DEFINE_CCW_MACHINE(6_1, "6.1", true);
static void ccw_machine_6_0_instance_options(MachineState *machine)
{
+ static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V6_0 };
+
ccw_machine_6_1_instance_options(machine);
+ s390_set_qemu_cpu_model(0x2964, 13, 2, qemu_cpu_feat);
}
static void ccw_machine_6_0_class_options(MachineClass *mc)
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 050dcf2d42..94090a6e22 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -90,8 +90,8 @@ static S390CPUDef s390_cpu_defs[] = {
CPUDEF_INIT(0x8562, 15, 1, 47, 0x08000000U, "gen15b", "IBM z15 T02 GA1"),
};
-#define QEMU_MAX_CPU_TYPE 0x2964
-#define QEMU_MAX_CPU_GEN 13
+#define QEMU_MAX_CPU_TYPE 0x3906
+#define QEMU_MAX_CPU_GEN 14
#define QEMU_MAX_CPU_EC_GA 2
static const S390FeatInit qemu_max_cpu_feat_init = { S390_FEAT_LIST_QEMU_MAX };
static S390FeatBitmap qemu_max_cpu_feat;
diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
index 219b1f9420..242c95ede4 100644
--- a/target/s390x/gen-features.c
+++ b/target/s390x/gen-features.c
@@ -706,23 +706,25 @@ static uint16_t qemu_V4_1[] = {
S390_FEAT_VECTOR,
};
-static uint16_t qemu_LATEST[] = {
+static uint16_t qemu_V6_0[] = {
S390_FEAT_ACCESS_EXCEPTION_FS_INDICATION,
S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2,
S390_FEAT_ESOP,
};
-/* add all new definitions before this point */
-static uint16_t qemu_MAX[] = {
- /* generates a dependency warning, leave it out for now */
- S390_FEAT_MSA_EXT_5,
- /* features introduced after the z13 */
+static uint16_t qemu_LATEST[] = {
S390_FEAT_INSTRUCTION_EXEC_PROT,
S390_FEAT_MISC_INSTRUCTION_EXT2,
S390_FEAT_MSA_EXT_8,
S390_FEAT_VECTOR_ENH,
};
+/* add all new definitions before this point */
+static uint16_t qemu_MAX[] = {
+ /* generates a dependency warning, leave it out for now */
+ S390_FEAT_MSA_EXT_5,
+};
+
/****** END FEATURE DEFS ******/
#define _YEARS "2016"
@@ -839,6 +841,7 @@ static FeatGroupDefSpec QemuFeatDef[] = {
QEMU_FEAT_INITIALIZER(V3_1),
QEMU_FEAT_INITIALIZER(V4_0),
QEMU_FEAT_INITIALIZER(V4_1),
+ QEMU_FEAT_INITIALIZER(V6_0),
QEMU_FEAT_INITIALIZER(LATEST),
QEMU_FEAT_INITIALIZER(MAX),
};
--
2.31.1
^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PATCH v2 01/26] s390x/tcg: Fix FP CONVERT TO (LOGICAL) FIXED NaN handling
2021-05-17 14:27 ` [PATCH v2 01/26] s390x/tcg: Fix FP CONVERT TO (LOGICAL) FIXED NaN handling David Hildenbrand
@ 2021-06-01 21:27 ` Richard Henderson
2021-06-02 9:50 ` David Hildenbrand
0 siblings, 1 reply; 50+ messages in thread
From: Richard Henderson @ 2021-06-01 21:27 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> @@ -634,6 +664,9 @@ uint64_t HELPER(clfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
>
> s390_restore_bfp_rounding_mode(env, old_mode);
> handle_exceptions(env, xxc_from_m34(m34), GETPC());
> + if (float128_is_any_nan(make_float128(h, l))) {
> + return 0;
> + }
I wonder if handle_exceptions should return s390_exc.
Then you can test
exc = handle_exceptions(...);
if (unlikely(exc & S390_IEEE_MASK_INVALID)) {
ret = 0;
}
return ret;
> +++ b/target/s390x/vec_fpu_helper.c
> @@ -326,6 +326,9 @@ void HELPER(gvec_vcdlg64s)(void *v1, const void *v2, CPUS390XState *env,
>
> static uint64_t vcgd64(uint64_t a, float_status *s)
> {
> + if (float64_is_any_nan(a)) {
> + return INT64_MIN;
> + }
> return float64_to_int64(a, s);
> }
>
> @@ -349,6 +352,9 @@ void HELPER(gvec_vcgd64s)(void *v1, const void *v2, CPUS390XState *env,
>
> static uint64_t vclgd64(uint64_t a, float_status *s)
> {
> + if (float64_is_any_nan(a)) {
> + return 0;
> + }
> return float64_to_uint64(a, s);
> }
You do still need to raise invalid, as far as I can see.
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 02/26] s390x/tcg: Fix instruction name for VECTOR FP LOAD (LENGTHENED|ROUNDED)
2021-05-17 14:27 ` [PATCH v2 02/26] s390x/tcg: Fix instruction name for VECTOR FP LOAD (LENGTHENED|ROUNDED) David Hildenbrand
@ 2021-06-01 21:27 ` Richard Henderson
0 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2021-06-01 21:27 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> Let's use the correct name.
>
> Signed-off-by: David Hildenbrand<david@redhat.com>
> ---
> target/s390x/insn-data.def | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 01/26] s390x/tcg: Fix FP CONVERT TO (LOGICAL) FIXED NaN handling
2021-06-01 21:27 ` Richard Henderson
@ 2021-06-02 9:50 ` David Hildenbrand
2021-06-07 8:04 ` David Hildenbrand
0 siblings, 1 reply; 50+ messages in thread
From: David Hildenbrand @ 2021-06-02 9:50 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 01.06.21 23:27, Richard Henderson wrote:
> On 5/17/21 7:27 AM, David Hildenbrand wrote:
>> @@ -634,6 +664,9 @@ uint64_t HELPER(clfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
>>
>> s390_restore_bfp_rounding_mode(env, old_mode);
>> handle_exceptions(env, xxc_from_m34(m34), GETPC());
>> + if (float128_is_any_nan(make_float128(h, l))) {
>> + return 0;
>> + }
>
> I wonder if handle_exceptions should return s390_exc.
> Then you can test
>
> exc = handle_exceptions(...);
> if (unlikely(exc & S390_IEEE_MASK_INVALID)) {
> ret = 0;
> }
> return ret;
>
I'll give it a thought if that makes things easier.
>
>
>> +++ b/target/s390x/vec_fpu_helper.c
>> @@ -326,6 +326,9 @@ void HELPER(gvec_vcdlg64s)(void *v1, const void *v2, CPUS390XState *env,
>>
>> static uint64_t vcgd64(uint64_t a, float_status *s)
>> {
>> + if (float64_is_any_nan(a)) {
>> + return INT64_MIN;
>> + }
>> return float64_to_int64(a, s);
>> }
>>
>> @@ -349,6 +352,9 @@ void HELPER(gvec_vcgd64s)(void *v1, const void *v2, CPUS390XState *env,
>>
>> static uint64_t vclgd64(uint64_t a, float_status *s)
>> {
>> + if (float64_is_any_nan(a)) {
>> + return 0;
>> + }
>> return float64_to_uint64(a, s);
>> }
>
> You do still need to raise invalid, as far as I can see.
Good point, so maybe
uint64_t ret = float64_to_uint64(a, s);
/* Note: check after converting to properly raise exceptions. */
if (float64_is_any_nan(a)) {
ret = 0;
}
return ret;
to minimize manual handling?
--
Thanks,
David / dhildenb
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 23/26] softfloat: Implement float128_(min|minnum|minnummag|max|maxnum|maxnummag)
2021-05-17 14:27 ` [PATCH v2 23/26] softfloat: Implement float128_(min|minnum|minnummag|max|maxnum|maxnummag) David Hildenbrand
@ 2021-06-03 17:01 ` Richard Henderson
0 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2021-06-03 17:01 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> With Richard's softfloat rework, the float128 implementation is
> straight-forward. Unfortuantely, we don't have any tests we can simply
> adjust/unlock.
>
> Cc: Aurelien Jarno <aurelien@aurel32.net>
> Cc: Peter Maydell <peter.maydell@linaro.org>
> Cc: "Alex Bennée" <alex.bennee@linaro.org>
> Cc: Richard Henderson <richard.henderson@linaro.org>
> Signed-off-by: David Hildenbrand <david@redhat.com>
Queueing this into my softfloat rework. Thanks,
r~
> ---
> fpu/softfloat.c | 17 +++++++++++++++++
> include/fpu/softfloat.h | 6 ++++++
> 2 files changed, 23 insertions(+)
>
> diff --git a/fpu/softfloat.c b/fpu/softfloat.c
> index 7376b3470c..bfe5a6b975 100644
> --- a/fpu/softfloat.c
> +++ b/fpu/softfloat.c
> @@ -3893,6 +3893,22 @@ static float64 float64_minmax(float64 a, float64 b, float_status *s, int flags)
> return which ? b : a;
> }
>
> +static float128 float128_minmax(float128 a, float128 b, float_status *s,
> + int flags)
> +{
> + FloatParts128 pa, pb;
> + int which;
> +
> + float128_unpack_canonical(&pa, a, s);
> + float128_unpack_canonical(&pb, b, s);
> + which = parts_minmax(&pa, &pb, s, flags, &float64_params);
> + if (unlikely(which < 0)) {
> + /* Some sort of nan, need to repack default and silenced nans. */
> + return float128_round_pack_canonical(&pa, s);
> + }
> + return which ? b : a;
> +}
> +
> #define MINMAX_1(type, name, flags) \
> type type##_##name(type a, type b, float_status *s) \
> { return type##_minmax(a, b, s, flags); }
> @@ -3909,6 +3925,7 @@ MINMAX_2(float16)
> MINMAX_2(bfloat16)
> MINMAX_2(float32)
> MINMAX_2(float64)
> +MINMAX_2(float128)
>
> #undef MINMAX_1
> #undef MINMAX_2
> diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
> index 94f7841b9f..ec7dca0960 100644
> --- a/include/fpu/softfloat.h
> +++ b/include/fpu/softfloat.h
> @@ -1204,6 +1204,12 @@ float128 float128_rem(float128, float128, float_status *status);
> float128 float128_sqrt(float128, float_status *status);
> FloatRelation float128_compare(float128, float128, float_status *status);
> FloatRelation float128_compare_quiet(float128, float128, float_status *status);
> +float128 float128_min(float128, float128, float_status *status);
> +float128 float128_max(float128, float128, float_status *status);
> +float128 float128_minnum(float128, float128, float_status *status);
> +float128 float128_maxnum(float128, float128, float_status *status);
> +float128 float128_minnummag(float128, float128, float_status *status);
> +float128 float128_maxnummag(float128, float128, float_status *status);
> bool float128_is_quiet_nan(float128, float_status *status);
> bool float128_is_signaling_nan(float128, float_status *status);
> float128 float128_silence_nan(float128, float_status *status);
>
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 03/26] s390x/tcg: Simplify vop64_3() handling
2021-05-17 14:27 ` [PATCH v2 03/26] s390x/tcg: Simplify vop64_3() handling David Hildenbrand
@ 2021-06-03 17:10 ` Richard Henderson
0 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2021-06-03 17:10 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> Let's simplify, reworking our handler generation, passing the whole "m5"
> register content and not providing specialized handlers for "se", and
> reading/writing proper float64 values using new helpers.
>
> Suggested-by: Richard Henderson<richard.henderson@linaro.org>
> Signed-off-by: David Hildenbrand<david@redhat.com>
> ---
> target/s390x/helper.h | 4 --
> target/s390x/translate_vx.c.inc | 11 ++--
> target/s390x/vec_fpu_helper.c | 94 +++++++++------------------------
> 3 files changed, 30 insertions(+), 79 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 04/26] s390x/tcg: Simplify vop64_2() handling
2021-05-17 14:27 ` [PATCH v2 04/26] s390x/tcg: Simplify vop64_2() handling David Hildenbrand
@ 2021-06-03 17:16 ` Richard Henderson
0 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2021-06-03 17:16 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> +#define DEF_GVEC_VOP2_FN(NAME, FN, BITS) \
> +void HELPER(gvec_##NAME##BITS)(void *v1, const void *v2, CPUS390XState *env, \
> + uint32_t desc) \
> +{ \
> + const uint8_t erm = extract32(simd_data(desc), 4, 4); \
> + const uint8_t se = extract32(simd_data(desc), 3, 1); \
bool for se? The argumemt to vopN_2 is bool...
Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 05/26] s390x/tcg: Simplify vfc64() handling
2021-05-17 14:27 ` [PATCH v2 05/26] s390x/tcg: Simplify vfc64() handling David Hildenbrand
@ 2021-06-03 17:18 ` Richard Henderson
0 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2021-06-03 17:18 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> Pass the m5 field via simd_data() and don't provide specialized handlers
> for single-element variants.
>
> Signed-off-by: David Hildenbrand<david@redhat.com>
> ---
> target/s390x/helper.h | 6 ---
> target/s390x/translate_vx.c.inc | 45 +++++-----------
> target/s390x/vec_fpu_helper.c | 94 +++++++++------------------------
> 3 files changed, 38 insertions(+), 107 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 06/26] s390x/tcg: Simplify vftci64() handling
2021-05-17 14:27 ` [PATCH v2 06/26] s390x/tcg: Simplify vftci64() handling David Hildenbrand
@ 2021-06-03 17:21 ` Richard Henderson
0 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2021-06-03 17:21 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> Signed-off-by: David Hildenbrand<david@redhat.com>
> ---
> target/s390x/helper.h | 1 -
> target/s390x/translate_vx.c.inc | 7 ++-----
> target/s390x/vec_fpu_helper.c | 29 +++++++++++------------------
> 3 files changed, 13 insertions(+), 24 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 07/26] s390x/tcg: Simplify vfma64() handling
2021-05-17 14:27 ` [PATCH v2 07/26] s390x/tcg: Simplify vfma64() handling David Hildenbrand
@ 2021-06-03 17:22 ` Richard Henderson
0 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2021-06-03 17:22 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> Signed-off-by: David Hildenbrand<david@redhat.com>
> ---
> target/s390x/helper.h | 2 --
> target/s390x/translate_vx.c.inc | 8 +++----
> target/s390x/vec_fpu_helper.c | 42 +++++++++++++--------------------
> 3 files changed, 20 insertions(+), 32 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 08/26] s390x/tcg: Simplify vfll32() handling
2021-05-17 14:27 ` [PATCH v2 08/26] s390x/tcg: Simplify vfll32() handling David Hildenbrand
@ 2021-06-03 17:23 ` Richard Henderson
0 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2021-06-03 17:23 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> Signed-off-by: David Hildenbrand<david@redhat.com>
> ---
> target/s390x/helper.h | 1 -
> target/s390x/translate_vx.c.inc | 6 +-----
> target/s390x/vec_fpu_helper.c | 21 +++++----------------
> 3 files changed, 6 insertions(+), 22 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 09/26] s390x/tcg: Simplify vflr64() handling
2021-05-17 14:27 ` [PATCH v2 09/26] s390x/tcg: Simplify vflr64() handling David Hildenbrand
@ 2021-06-03 17:25 ` Richard Henderson
0 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2021-06-03 17:25 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> Signed-off-by: David Hildenbrand<david@redhat.com>
> ---
> target/s390x/helper.h | 1 -
> target/s390x/translate_vx.c.inc | 3 +--
> target/s390x/vec_fpu_helper.c | 29 +++++++----------------------
> 3 files changed, 8 insertions(+), 25 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 10/26] s390x/tcg: Simplify wfc64() handling
2021-05-17 14:27 ` [PATCH v2 10/26] s390x/tcg: Simplify wfc64() handling David Hildenbrand
@ 2021-06-03 17:27 ` Richard Henderson
0 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2021-06-03 17:27 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> ... and prepare for 32/128 bit support.
>
> Signed-off-by: David Hildenbrand<david@redhat.com>
> ---
> target/s390x/vec_fpu_helper.c | 23 ++++++++++++-----------
> 1 file changed, 12 insertions(+), 11 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 13/26] s390x/tcg: Implement 32/128 bit for VECTOR FP (ADD|DIVIDE|MULTIPLY|SUBTRACT)
2021-05-17 14:27 ` [PATCH v2 13/26] s390x/tcg: Implement 32/128 bit for VECTOR FP (ADD|DIVIDE|MULTIPLY|SUBTRACT) David Hildenbrand
@ 2021-06-03 17:32 ` Richard Henderson
0 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2021-06-03 17:32 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> In case of 128bit, we always have a single element. Add new helpers for
> reading/writing 32/128 bit floats.
>
> Signed-off-by: David Hildenbrand<david@redhat.com>
> ---
> target/s390x/helper.h | 8 ++++
> target/s390x/translate_vx.c.inc | 85 +++++++++++++++++++++++++++++----
> target/s390x/vec_fpu_helper.c | 74 ++++++++++++++++++++++++++--
> 3 files changed, 153 insertions(+), 14 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 14/26] s390x/tcg: Implement 32/128 bit for VECTOR (LOAD FP INTEGER|FP SQUARE ROOT)
2021-05-17 14:27 ` [PATCH v2 14/26] s390x/tcg: Implement 32/128 bit for VECTOR (LOAD FP INTEGER|FP SQUARE ROOT) David Hildenbrand
@ 2021-06-03 17:33 ` Richard Henderson
0 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2021-06-03 17:33 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> Signed-off-by: David Hildenbrand<david@redhat.com>
> ---
> target/s390x/helper.h | 4 ++
> target/s390x/translate_vx.c.inc | 74 ++++++++++++++++++++++++++-------
> target/s390x/vec_fpu_helper.c | 46 +++++++++++++++++++-
> 3 files changed, 109 insertions(+), 15 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 15/26] s390x/tcg: Implement 32/128 bit for VECTOR FP COMPARE *
2021-05-17 14:27 ` [PATCH v2 15/26] s390x/tcg: Implement 32/128 bit for VECTOR FP COMPARE * David Hildenbrand
@ 2021-06-03 17:37 ` Richard Henderson
0 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2021-06-03 17:37 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> In addition to 32/128bit variants, we also have to support the
> "Signal-on-QNaN (SQ)" bit.
>
> Signed-off-by: David Hildenbrand<david@redhat.com>
> ---
> target/s390x/helper.h | 12 +++++++
> target/s390x/translate_vx.c.inc | 57 ++++++++++++++++++++++++-----
> target/s390x/vec_fpu_helper.c | 64 +++++++++++++++++++++++++++++++--
> 3 files changed, 121 insertions(+), 12 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 16/26] s390x/tcg: Implement 32/128 bit for VECTOR FP COMPARE (AND SIGNAL) SCALAR
2021-05-17 14:27 ` [PATCH v2 16/26] s390x/tcg: Implement 32/128 bit for VECTOR FP COMPARE (AND SIGNAL) SCALAR David Hildenbrand
@ 2021-06-03 17:40 ` Richard Henderson
0 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2021-06-03 17:40 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> Signed-off-by: David Hildenbrand<david@redhat.com>
> ---
> target/s390x/helper.h | 4 +++
> target/s390x/translate_vx.c.inc | 38 ++++++++++++++++++++++------
> target/s390x/vec_fpu_helper.c | 44 ++++++++++++++++++++++++++++++++-
> 3 files changed, 77 insertions(+), 9 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 20/26] s390x/tcg: Implement 32/128 bit for VECTOR FP TEST DATA CLASS IMMEDIATE
2021-05-17 14:27 ` [PATCH v2 20/26] s390x/tcg: Implement 32/128 bit for VECTOR FP TEST DATA CLASS IMMEDIATE David Hildenbrand
@ 2021-06-03 17:43 ` Richard Henderson
0 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2021-06-03 17:43 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> Signed-off-by: David Hildenbrand<david@redhat.com>
> ---
> target/s390x/helper.h | 2 ++
> target/s390x/translate_vx.c.inc | 23 ++++++++++++++--
> target/s390x/vec_fpu_helper.c | 47 +++++++++++++++++++++++++++++++++
> 3 files changed, 70 insertions(+), 2 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 21/26] s390x/tcg: Implement 32/128 bit for VECTOR FP MULTIPLY AND (ADD|SUBTRACT)
2021-05-17 14:27 ` [PATCH v2 21/26] s390x/tcg: Implement 32/128 bit for VECTOR FP MULTIPLY AND (ADD|SUBTRACT) David Hildenbrand
@ 2021-06-03 17:44 ` Richard Henderson
0 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2021-06-03 17:44 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> Signed-off-by: David Hildenbrand<david@redhat.com>
> ---
> target/s390x/helper.h | 4 +++
> target/s390x/translate_vx.c.inc | 47 ++++++++++++++++++++++++++++-----
> target/s390x/vec_fpu_helper.c | 44 +++++++++++++++++++++++++++++-
> 3 files changed, 87 insertions(+), 8 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 22/26] s390x/tcg: Implement VECTOR FP NEGATIVE MULTIPLY AND (ADD|SUBTRACT)
2021-05-17 14:27 ` [PATCH v2 22/26] s390x/tcg: Implement VECTOR FP NEGATIVE " David Hildenbrand
@ 2021-06-03 17:45 ` Richard Henderson
0 siblings, 0 replies; 50+ messages in thread
From: Richard Henderson @ 2021-06-03 17:45 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> Signed-off-by: David Hildenbrand<david@redhat.com>
> ---
> target/s390x/helper.h | 6 +++++
> target/s390x/insn-data.def | 4 ++++
> target/s390x/translate_vx.c.inc | 39 +++++++++++++++++++++++++++++++--
> target/s390x/vec_fpu_helper.c | 2 ++
> 4 files changed, 49 insertions(+), 2 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 24/26] s390x/tcg: Implement VECTOR FP (MAXIMUM|MINIMUM)
2021-05-17 14:27 ` [PATCH v2 24/26] s390x/tcg: Implement VECTOR FP (MAXIMUM|MINIMUM) David Hildenbrand
@ 2021-06-03 18:13 ` Richard Henderson
2021-06-07 9:06 ` David Hildenbrand
0 siblings, 1 reply; 50+ messages in thread
From: Richard Henderson @ 2021-06-03 18:13 UTC (permalink / raw)
To: David Hildenbrand, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 5/17/21 7:27 AM, David Hildenbrand wrote:
> + if (unlikely(nan_a || nan_b)) {
Perhaps better as (dcmask_a | dcmask_b) & DCMASK_NAN ?
> + if (sig_a || sig_b) {
Similarly.
> + } else if (unlikely(inf_a && inf_b)) {
> + switch (type) {
> + case S390_MINMAX_TYPE_JAVA:
> + return neg_a && !neg_b ? S390_MINMAX_RES_A : S390_MINMAX_RES_B;
> + case S390_MINMAX_TYPE_C_MACRO:
> + case S390_MINMAX_TYPE_CPP:
> + return neg_b ? S390_MINMAX_RES_B : S390_MINMAX_RES_A;
> + case S390_MINMAX_TYPE_F:
> + return !neg_a && neg_b ? S390_MINMAX_RES_B : S390_MINMAX_RES_A;
> + default:
> + g_assert_not_reached();
> + }
I don't understand why inf_a && inf_b gets a special case. Inf is
well-ordered. If the arguments are equal you can't tell the difference between
them, so it doesn't matter whether A or B is returned.
I would pass this case along to S390_MINMAX_RES_MINMAX.
> + } else if (unlikely(zero_a && zero_b)) {
> + switch (type) {
> + case S390_MINMAX_TYPE_JAVA:
> + return neg_a && !neg_b ? S390_MINMAX_RES_A : S390_MINMAX_RES_B;
If neg_a && neg_b, both A and B are -0, and you can't distinguish them. So
this would seem to simplify to
neg_a ? S390_MINMAX_RES_A : S390_MINMAX_RES_B
> + case S390_MINMAX_TYPE_C_MACRO:
> + return S390_MINMAX_RES_B;
> + case S390_MINMAX_TYPE_F:
> + return !neg_a && neg_b ? S390_MINMAX_RES_B : S390_MINMAX_RES_A;
Similarly if !neg_a && !neg_b, both A and B are +0.
Otherwise this looks good.
r~
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 25/26] s390x/tcg: We support Vector enhancements facility
2021-05-17 14:27 ` [PATCH v2 25/26] s390x/tcg: We support Vector enhancements facility David Hildenbrand
@ 2021-06-07 7:47 ` David Hildenbrand
0 siblings, 0 replies; 50+ messages in thread
From: David Hildenbrand @ 2021-06-07 7:47 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Richard Henderson,
Halil Pasic, Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 17.05.21 16:27, David Hildenbrand wrote:
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
> target/s390x/gen-features.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
> index a6ec918e90..219b1f9420 100644
> --- a/target/s390x/gen-features.c
> +++ b/target/s390x/gen-features.c
> @@ -720,6 +720,7 @@ static uint16_t qemu_MAX[] = {
> S390_FEAT_INSTRUCTION_EXEC_PROT,
> S390_FEAT_MISC_INSTRUCTION_EXT2,
> S390_FEAT_MSA_EXT_8,
> + S390_FEAT_VECTOR_ENH,
> };
>
> /****** END FEATURE DEFS ******/
>
I'll squash the following changes:
diff --git a/include/elf.h b/include/elf.h
index 033bcc9576..0049d5a318 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -605,6 +605,7 @@ typedef struct {
#define HWCAP_S390_HIGH_GPRS 512
#define HWCAP_S390_TE 1024
#define HWCAP_S390_VXRS 2048
+#define HWCAP_S390_VXRS_EXT 8192
/* M68K specific definitions. */
/* We use the top 24 bits to encode information about the
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 1ab97e38e0..23ccaf6df2 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1374,6 +1374,7 @@ static uint32_t get_elf_hwcap(void)
hwcap |= HWCAP_S390_ETF3EH;
}
GET_FEATURE(S390_FEAT_VECTOR, HWCAP_S390_VXRS);
+ GET_FEATURE(S390_FEAT_VECTOR_ENH, HWCAP_S390_VXRS_EXT);
return hwcap;
}
--
Thanks,
David / dhildenb
^ permalink raw reply related [flat|nested] 50+ messages in thread
* Re: [PATCH v2 01/26] s390x/tcg: Fix FP CONVERT TO (LOGICAL) FIXED NaN handling
2021-06-02 9:50 ` David Hildenbrand
@ 2021-06-07 8:04 ` David Hildenbrand
0 siblings, 0 replies; 50+ messages in thread
From: David Hildenbrand @ 2021-06-07 8:04 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 02.06.21 11:50, David Hildenbrand wrote:
> On 01.06.21 23:27, Richard Henderson wrote:
>> On 5/17/21 7:27 AM, David Hildenbrand wrote:
>>> @@ -634,6 +664,9 @@ uint64_t HELPER(clfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
>>>
>>> s390_restore_bfp_rounding_mode(env, old_mode);
>>> handle_exceptions(env, xxc_from_m34(m34), GETPC());
>>> + if (float128_is_any_nan(make_float128(h, l))) {
>>> + return 0;
>>> + }
>>
>> I wonder if handle_exceptions should return s390_exc.
>> Then you can test
>>
>> exc = handle_exceptions(...);
>> if (unlikely(exc & S390_IEEE_MASK_INVALID)) {
>> ret = 0;
>> }
>> return ret;
>>
>
> I'll give it a thought if that makes things easier.
Looking at partsN(float_to_uint), we also raise float_flag_invalid in
other cases, for example with float_class_inf. So IIUC, your proposal
would also set "ret = 0" in case our input is +inf, which would be wrong.
--
Thanks,
David / dhildenb
^ permalink raw reply [flat|nested] 50+ messages in thread
* Re: [PATCH v2 24/26] s390x/tcg: Implement VECTOR FP (MAXIMUM|MINIMUM)
2021-06-03 18:13 ` Richard Henderson
@ 2021-06-07 9:06 ` David Hildenbrand
0 siblings, 0 replies; 50+ messages in thread
From: David Hildenbrand @ 2021-06-07 9:06 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
Cc: Peter Maydell, Thomas Huth, Cornelia Huck, Halil Pasic,
Christian Borntraeger, qemu-s390x, Alex Bennée,
Aurelien Jarno
On 03.06.21 20:13, Richard Henderson wrote:
> On 5/17/21 7:27 AM, David Hildenbrand wrote:
>> + if (unlikely(nan_a || nan_b)) {
>
> Perhaps better as (dcmask_a | dcmask_b) & DCMASK_NAN ?
>
>> + if (sig_a || sig_b) {
>
> Similarly.
>
Will do, thanks.
>> + } else if (unlikely(inf_a && inf_b)) {
>> + switch (type) {
>> + case S390_MINMAX_TYPE_JAVA:
>> + return neg_a && !neg_b ? S390_MINMAX_RES_A : S390_MINMAX_RES_B;
>> + case S390_MINMAX_TYPE_C_MACRO:
>> + case S390_MINMAX_TYPE_CPP:
>> + return neg_b ? S390_MINMAX_RES_B : S390_MINMAX_RES_A;
>> + case S390_MINMAX_TYPE_F:
>> + return !neg_a && neg_b ? S390_MINMAX_RES_B : S390_MINMAX_RES_A;
>> + default:
>> + g_assert_not_reached();
>> + }
>
> I don't understand why inf_a && inf_b gets a special case. Inf is
> well-ordered. If the arguments are equal you can't tell the difference between
> them, so it doesn't matter whether A or B is returned.
>
> I would pass this case along to S390_MINMAX_RES_MINMAX.
Thinking about it, that makes sense. I have no clue why the PoP has
these special cases expressed in the tables, at least it managed to
confuse me.
>
>> + } else if (unlikely(zero_a && zero_b)) {
>> + switch (type) {
>> + case S390_MINMAX_TYPE_JAVA:
>> + return neg_a && !neg_b ? S390_MINMAX_RES_A : S390_MINMAX_RES_B;
>
> If neg_a && neg_b, both A and B are -0, and you can't distinguish them. So
> this would seem to simplify to
Another case of "let's make the tables inconsistent to confuse David".
>
> neg_a ? S390_MINMAX_RES_A : S390_MINMAX_RES_B
>
>> + case S390_MINMAX_TYPE_C_MACRO:
>> + return S390_MINMAX_RES_B;
>> + case S390_MINMAX_TYPE_F:
>> + return !neg_a && neg_b ? S390_MINMAX_RES_B : S390_MINMAX_RES_A;
>
> Similarly if !neg_a && !neg_b, both A and B are +0.
>
> Otherwise this looks good.
Agreed, thanks!
--
Thanks,
David / dhildenb
^ permalink raw reply [flat|nested] 50+ messages in thread
end of thread, other threads:[~2021-06-07 9:07 UTC | newest]
Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-17 14:27 [PATCH v2 00/26] s390x/tcg: Implement Vector enhancements facility and switch to z14 David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 01/26] s390x/tcg: Fix FP CONVERT TO (LOGICAL) FIXED NaN handling David Hildenbrand
2021-06-01 21:27 ` Richard Henderson
2021-06-02 9:50 ` David Hildenbrand
2021-06-07 8:04 ` David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 02/26] s390x/tcg: Fix instruction name for VECTOR FP LOAD (LENGTHENED|ROUNDED) David Hildenbrand
2021-06-01 21:27 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 03/26] s390x/tcg: Simplify vop64_3() handling David Hildenbrand
2021-06-03 17:10 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 04/26] s390x/tcg: Simplify vop64_2() handling David Hildenbrand
2021-06-03 17:16 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 05/26] s390x/tcg: Simplify vfc64() handling David Hildenbrand
2021-06-03 17:18 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 06/26] s390x/tcg: Simplify vftci64() handling David Hildenbrand
2021-06-03 17:21 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 07/26] s390x/tcg: Simplify vfma64() handling David Hildenbrand
2021-06-03 17:22 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 08/26] s390x/tcg: Simplify vfll32() handling David Hildenbrand
2021-06-03 17:23 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 09/26] s390x/tcg: Simplify vflr64() handling David Hildenbrand
2021-06-03 17:25 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 10/26] s390x/tcg: Simplify wfc64() handling David Hildenbrand
2021-06-03 17:27 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 11/26] s390x/tcg: Implement VECTOR BIT PERMUTE David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 12/26] s390x/tcg: Implement VECTOR MULTIPLY SUM LOGICAL David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 13/26] s390x/tcg: Implement 32/128 bit for VECTOR FP (ADD|DIVIDE|MULTIPLY|SUBTRACT) David Hildenbrand
2021-06-03 17:32 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 14/26] s390x/tcg: Implement 32/128 bit for VECTOR (LOAD FP INTEGER|FP SQUARE ROOT) David Hildenbrand
2021-06-03 17:33 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 15/26] s390x/tcg: Implement 32/128 bit for VECTOR FP COMPARE * David Hildenbrand
2021-06-03 17:37 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 16/26] s390x/tcg: Implement 32/128 bit for VECTOR FP COMPARE (AND SIGNAL) SCALAR David Hildenbrand
2021-06-03 17:40 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 17/26] s390x/tcg: Implement 64 bit for VECTOR FP LOAD LENGTHENED David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 18/26] s390x/tcg: Implement 128 bit for VECTOR FP LOAD ROUNDED David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 19/26] s390x/tcg: Implement 32/128 bit for VECTOR FP PERFORM SIGN OPERATION David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 20/26] s390x/tcg: Implement 32/128 bit for VECTOR FP TEST DATA CLASS IMMEDIATE David Hildenbrand
2021-06-03 17:43 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 21/26] s390x/tcg: Implement 32/128 bit for VECTOR FP MULTIPLY AND (ADD|SUBTRACT) David Hildenbrand
2021-06-03 17:44 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 22/26] s390x/tcg: Implement VECTOR FP NEGATIVE " David Hildenbrand
2021-06-03 17:45 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 23/26] softfloat: Implement float128_(min|minnum|minnummag|max|maxnum|maxnummag) David Hildenbrand
2021-06-03 17:01 ` Richard Henderson
2021-05-17 14:27 ` [PATCH v2 24/26] s390x/tcg: Implement VECTOR FP (MAXIMUM|MINIMUM) David Hildenbrand
2021-06-03 18:13 ` Richard Henderson
2021-06-07 9:06 ` David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 25/26] s390x/tcg: We support Vector enhancements facility David Hildenbrand
2021-06-07 7:47 ` David Hildenbrand
2021-05-17 14:27 ` [PATCH v2 26/26] s390x/cpumodel: Bump up QEMU model to a stripped-down IBM z14 GA2 David Hildenbrand
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).